From 2c969d33f45724cd87b5728807517e506c8c5f0f Mon Sep 17 00:00:00 2001 From: root Date: Sat, 1 Jan 2000 00:02:28 +0000 Subject: [PATCH 001/332] rest of the outputs --- tall-cylinder.config | 48 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tall-cylinder.config b/tall-cylinder.config index 8de6e6ec..5022a84b 100644 --- a/tall-cylinder.config +++ b/tall-cylinder.config @@ -15,3 +15,51 @@ matrix16 1,5 R 208,0 1,6 L 224,0 1,7 R 240,0 +2,0 L 256,0 +2,1 R 272,0 +2,2 L 288,0 +2,3 R 304,0 +2,4 L 320,0 +2,5 R 336,0 +2,6 L 352,0 +2,7 R 368,0 +3,0 L 384,0 +3,1 R 400,0 +3,2 L 416,0 +3,3 R 432,0 +3,4 L 448,0 +3,5 R 464,0 +3,6 L 480,0 +3,7 R 496,0 +4,0 L 0,32 +4,1 R 16,32 +4,2 L 32,32 +4,3 R 48,32 +4,4 L 64,32 +4,5 R 80,32 +4,6 L 96,32 +4,7 R 112,32 +5,0 L 128,32 +5,1 R 144,32 +5,2 L 160,32 +5,3 R 176,32 +5,4 L 192,32 +5,5 R 208,32 +5,6 L 224,32 +5,7 R 240,32 +6,0 L 256,32 +6,1 R 272,32 +6,2 L 288,32 +6,3 R 304,32 +6,4 L 320,32 +6,5 R 336,32 +6,6 L 352,32 +6,7 R 368,32 +7,0 L 384,32 +7,1 R 400,32 +7,2 L 416,32 +7,3 R 432,32 +7,4 L 448,32 +7,5 R 464,32 +7,6 L 480,32 +7,7 R 496,32 From 8d25c7522960e7fd4f2a95ceab4ae40bb1dc9c17 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Mon, 29 Jul 2013 20:16:42 -0400 Subject: [PATCH 002/332] Split everything into separate libraries for the PRU and ledscape; add initial response for PRU startup --- Makefile | 12 ++- ledscape.c | 168 +++++++++++++++++++++++++++++++++++++ ledscape.h | 90 ++++++++++++++++++++ pru.c | 132 +++++++++++++++++++++++++++++ pru.h | 57 +++++++++++++ rgb-test.c | 50 +++++++++++ ws281x.c | 239 ----------------------------------------------------- ws281x.p | 6 +- 8 files changed, 507 insertions(+), 247 deletions(-) create mode 100644 ledscape.c create mode 100644 ledscape.h create mode 100644 pru.c create mode 100644 pru.h create mode 100644 rgb-test.c delete mode 100644 ws281x.c diff --git a/Makefile b/Makefile index 40ca2f9d..0f451eb8 100755 --- a/Makefile +++ b/Makefile @@ -19,21 +19,19 @@ LDFLAGS += \ -lpthread \ PASM := ../../utils/pasm_2 -OBJDIR=obj -TARGET=$(BINDIR)/ws281x +OBJDIR := obj +TARGET := $(BINDIR)/ws281x _DEPS = DEPS = $(patsubst %,$(INCDIR_APP_LOADER)/%,$(_DEPS)) -_OBJ = ws281x.o -OBJ = $(patsubst %,$(OBJDIR)/%,$(_OBJ)) +OBJS = ledscape.o pru.o rgb-test.o -$(OBJDIR)/%.o: %.c $(DEPS) - @mkdir -p obj +%.o: %.c $(DEPS) $(CROSS_COMPILE)gcc $(CFLAGS) -c -o $@ $< all: $(TARGET) ws281x.bin -$(TARGET): $(OBJ) +$(TARGET): $(OBJS) $(CROSS_COMPILE)gcc $(CFLAGS) -o $@ $^ $(LDFLAGS) ws281x.bin: ws281x.p ws281x.hp diff --git a/ledscape.c b/ledscape.c new file mode 100644 index 00000000..f8c610e4 --- /dev/null +++ b/ledscape.c @@ -0,0 +1,168 @@ +/** \file + * Userspace interface to the WS281x LED strip driver. + * + * \todo Package this into a library, possible a Python module. + */ +#include +#include +#include +#include +#include +#include +#include +#include "ledscape.h" +#include "pru.h" + + +/** Command structure shared with the PRU. + * + * This is mapped into the PRU data RAM and points to the + * frame buffer in the shared DDR segment. + * + * Changing this requires changes in ws281x.p + */ +typedef struct +{ + // in the DDR shared with the PRU + uintptr_t pixels_dma; + + // Length in pixels of the longest LED strip. + unsigned num_pixels; + + // write 1 to start, 0xFF to abort. will be cleared when started + volatile unsigned command; + + // will have a non-zero response written when done + volatile unsigned response; +} __attribute__((__packed__)) ws281x_command_t; + + +struct ledscape +{ + ws281x_command_t * ws281x; + pru_t * pru; + unsigned num_pixels; + size_t frame_size; + ledscape_frame_t * frames[2]; +}; + + +/** Retrieve one of the two frame buffers. */ +ledscape_frame_t * +ledscape_frame( + ledscape_t * const leds, + unsigned int frame +) +{ + if (frame >= 2) + return NULL; + + return (ledscape_frame_t*)((uint8_t*) leds->pru->ddr + leds->frame_size); +} + + +/** Initiate the transfer of a frame to the LED strips */ +void +ledscape_draw( + ledscape_t * const leds, + unsigned int frame +) +{ + leds->ws281x->pixels_dma = leds->pru->ddr_addr + leds->frame_size; + + // Wait for any current command to have been acknowledged + while (leds->ws281x->command) + ; + + // Send the start command + leds->ws281x->command = 1; +} + + +/** Wait for the current frame to finish transfering to the strips. + * \returns a token indicating the response code. + */ +uint32_t +ledscape_wait( + ledscape_t * const leds +) +{ + while (1) + { + uint32_t response = leds->ws281x->response; + if (!response) + continue; + leds->ws281x->response = 0; + return response; + } +} + + +ledscape_t * +ledscape_init( + unsigned num_pixels +) +{ + pru_t * const pru = pru_init(0); + const size_t frame_size = num_pixels * LEDSCAPE_NUM_STRIPS * 4; + + if (2 *frame_size > pru->ddr_size) + die("Pixel data needs at least 2 * %zu, only %zu in DDR\n", + frame_size, + pru->ddr_size + ); + + ledscape_t * const leds = calloc(1, sizeof(*leds)); + + *leds = (ledscape_t) { + .pru = pru, + .num_pixels = num_pixels, + .frame_size = frame_size, + .ws281x = pru->data_ram, + }; + + *(leds->ws281x) = (ws281x_command_t) { + .pixels_dma = 0, // will be set in draw routine + .command = 0, + .response = 0, + .num_pixels = leds->num_pixels, + }; + + // Initiate the PRU program + pru_exec(pru, "./ws281x.bin"); + + // Watch for a done response that indicates a proper startup + // \todo timeout if it fails + while (!leds->ws281x->response) + ; + + return leds; +} + + +void +ledscape_close( + ledscape_t * const leds +) +{ + // Signal a halt command + leds->ws281x->command = 0xFF; + pru_close(leds->pru); +} + + +void +ledscape_set_color( + ledscape_frame_t * const frame, + uint8_t strip, + uint8_t pixel, + uint8_t r, + uint8_t g, + uint8_t b +) +{ + ledscape_pixel_t * const p = &frame[pixel].strip[strip]; + p->r = r; + p->g = g; + p->b = b; +} diff --git a/ledscape.h b/ledscape.h new file mode 100644 index 00000000..475420dc --- /dev/null +++ b/ledscape.h @@ -0,0 +1,90 @@ +/** \file + * LEDscape for the BeagleBone Black. + * + * Drives up to 32 ws281x LED strips using the PRU to have no CPU overhead. + * Allows easy double buffering of frames. + */ + +#ifndef _ledscape_h_ +#define _ledscape_h_ + +#include + +/** The number of strips supported. + * + * Changing this also requires changes in ws281x.p to stride the + * correct number of bytes per row.. + */ +#define LEDSCAPE_NUM_STRIPS 32 + + +/** LEDscape pixel format is BRGA. + * + * data is laid out with BRGA format, since that is how it will + * be translated during the clock out from the PRU. + */ +typedef struct { + uint8_t b; + uint8_t r; + uint8_t g; + uint8_t a; +} __attribute__((__packed__)) ledscape_pixel_t; + + +/** LEDscape frame buffer is "strip-major". + * + * All 32 strips worth of data for each pixel are stored adjacent. + * This makes it easier to clock out while reading from the DDR + * in a burst mode. + */ +typedef struct { + ledscape_pixel_t strip[LEDSCAPE_NUM_STRIPS]; +} __attribute__((__packed__)) ledscape_frame_t; + + +typedef struct ledscape ledscape_t; + + +extern ledscape_t * +ledscape_init( + unsigned num_pixels +); + + +extern ledscape_frame_t * +ledscape_frame( + ledscape_t * const leds, + unsigned frame +); + + +extern void +ledscape_draw( + ledscape_t * const leds, + unsigned frame +); + + +extern void +ledscape_set_color( + ledscape_frame_t * const frame, + uint8_t strip, + uint8_t pixel, + uint8_t r, + uint8_t g, + uint8_t b +); + + +extern uint32_t +ledscape_wait( + ledscape_t * const leds +); + + +extern void +ledscape_close( + ledscape_t * const leds +); + +#endif diff --git a/pru.c b/pru.c new file mode 100644 index 00000000..229aab96 --- /dev/null +++ b/pru.c @@ -0,0 +1,132 @@ +/** \file + * Userspace interface to the BeagleBone PRU. + * + * Wraps the prussdrv library in a sane interface. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pru.h" + + +static unsigned int +proc_read( + const char * const fname +) +{ + FILE * const f = fopen(fname, "r"); + if (!f) + die("%s: Unable to open: %s", fname, strerror(errno)); + unsigned int x; + fscanf(f, "%x", &x); + fclose(f); + return x; +} + + +pru_t * +pru_init( + const unsigned short pru_num +) +{ + prussdrv_init(); + + int ret = prussdrv_open(PRU_EVTOUT_0); + if (ret) + die("prussdrv_open open failed\n"); + + tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA; + prussdrv_pruintc_init(&pruss_intc_initdata); + + void * pru_data_mem; + prussdrv_map_prumem( + pru_num == 0 ? PRUSS0_PRU0_DATARAM :PRUSS0_PRU1_DATARAM, + &pru_data_mem; + ); + + const int mem_fd = open("/dev/mem", O_RDWR); + if (mem_fd < 0) + die("Failed to open /dev/mem: %s\n", strerror(errno)); + + const uintptr_t ddr_addr = proc_read("/sys/class/uio/uio0/maps/map1/addr"); + const uintptr_t ddr_size = proc_read("/sys/class/uio/uio0/maps/map1/size"); + + const uintptr_t ddr_start = 0x10000000; + const uintptr_t ddr_offset = ddr_addr - ddr_start; + const size_t ddr_filelen = ddr_size + ddr_start; + + /* map the memory */ + uint8_t * const ddr_mem = mmap( + 0, + ddr_filelen, + PROT_WRITE | PROT_READ, + MAP_SHARED, + mem_fd, + ddr_offset + ); + if (ddr_mem == MAP_FAILED) + die("Failed to mmap offset %"PRIxPTR" @ %zu bytes: %s\n", + ddr_offset, + ddr_filelen, + strerror(errno) + ); + + close(mem_fd); + + pru_t * const pru = calloc(1, sizeof(*pru)); + if (!pru) + die("calloc failed", strerror(errno)); + + *pru = (pru_t) { + .pru_num = pru_num, + .data_ram = pru_data_mem, + .data_ram_size = 8192, // how to determine? + .dma_addr = ddr_addr, + .dma = (void*)(ddr_mem + ddr_start), + .dma_size = ddr_size, + }; + + printf("%s: PRU %d: data %p @ %zu bytes, DMA %p / %"PRIxPTR" @ %zu bytes\n", + __func__, + pru_num, + pru->data_ram, + pru->data_ram_size, + pru->dma, + pru->dma_addr, + pru->dma_size + ); + + return pru; +} + + +void +pru_exec( + pru_t * const pru, + const char * const program +) +{ + if (!prussdrv_exec_program(pru->pru_num, program)) + die("%s failed", program); +} + + +void +pru_close( + pru_t * const pru +) +{ + // \todo unmap memory + prussdrv_pru_wait_event(PRU_EVTOUT_0); + prussdrv_pru_clear_event(PRU0_ARM_INTERRUPT); + prussdrv_pru_disable(pru->pru_num); + prussdrv_exit(); +} diff --git a/pru.h b/pru.h new file mode 100644 index 00000000..b5f9a610 --- /dev/null +++ b/pru.h @@ -0,0 +1,57 @@ +/** \file + * Simplified interface to the ARM PRU. + * + */ +#ifndef _pru_h_ +#define _pru_h_ + +#include +#include + + +/** Mapping of the PRU memory spaces. + * + * The PRU has a small, fast local data RAM that is mapped into ARM memory, + * as well as slower access to the DDR RAM of the ARM. + */ +typedef struct +{ + unsigned pru_num; + + void * data_ram; // PRU data ram in ARM space + size_t data_ram_size; // size in bytes of the PRU's data RAM + + void * ddr; // PRU DMA address (in ARM space) + uintptr_t ddr_addr; // PRU DMA address (in PRU space) + size_t ddr_size; // Size in bytes of the shared space +} pru_t; + +extern pru_t * +pru_init( + const unsigned short pru_num +); + + +extern void +pru_exec( + pru_t * const pru, + const char * const program +); + + +extern void +pru_close( + pru_t * const pru +); + + +#define die(fmt, ...) \ + do { \ + fprintf(stderr, "%s:%d: " fmt, \ + __func__, __LINE__, ## __VA_ARGS__); \ + exit(EXIT_FAILURE); \ + } while (0) + + + +#endif diff --git a/rgb-test.c b/rgb-test.c new file mode 100644 index 00000000..32ab94e0 --- /dev/null +++ b/rgb-test.c @@ -0,0 +1,50 @@ +/** \file + * Test the ledscape library by pulsing RGB on the first three LEDS. + */ +#include +#include +#include +#include +#include +#include +#include +#include "ledscape.h" + + +int main (void) +{ + const int num_pixels = 256; + ledscape_t * const leds = ledscape_init(num_pixels); + + unsigned i = 0; + while (1) + { + // Alternate frame buffers on each draw command + const unsigned frame_num = i++ % 2; + ledscape_frame_t * const frame + = ledscape_frame(leds, frame_num); + + uint8_t val = i >> 1; + fill_color(frame, num_pixels, val, 0, val); + + for (int strip = 0 ; strip < 32 ; strip++) + { + //uint8_t r = ((strip >> 2) & 0x3) * 64; + //uint8_t g = ((strip >> 0) & 0x3) * 64; + //uint8_t b = ((strip >> 4) & 0x3) * 64; + ledscale_set_color(frame, strip, 0, val, 0, 0); + ledscale_set_color(frame, strip, 1, 0, val + 80, 0); + ledscale_set_color(frame, strip, 2, 0, 0, val + 160); + } + + // wait for the previous frame to finish; + const uint32_t response = ledscape_wait(leds); + printf("starting %d previous %"PRIx32"\n", i, response); + + ledscape_draw(leds, frame_num); + } + + ledscape_close(leds); + + return EXIT_SUCCESS; +} diff --git a/ws281x.c b/ws281x.c deleted file mode 100644 index 36e598ea..00000000 --- a/ws281x.c +++ /dev/null @@ -1,239 +0,0 @@ -/** \file - * Userspace interface to the WS281x LED strip driver. - * - * \todo Package this into a library, possible a Python module. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PRU_NUM (0) - -#define die(fmt, ...) \ - do { \ - fprintf(stderr, fmt, ## __VA_ARGS__); \ - exit(EXIT_FAILURE); \ - } while (0) - -/** Command structure shared with the PRU. - * - * This is mapped into the PRU data RAM and points to the - * frame buffer in the shared DDR segment. - */ -typedef struct -{ - // in the DDR shared with the PRU - uintptr_t pixels_dma; - - // Length in pixels of the longest LED strip. - unsigned size; - - // write 1 to start, 0xFF to abort. will be cleared when started - volatile unsigned command; - - // will have a non-zero response written when done - volatile unsigned response; -} __attribute__((__packed__)) ws281x_command_t; - -// data is laid out with BRGA format, since that is how it will -// be translated during the clock out from the PRU. -typedef struct { - uint8_t b; - uint8_t r; - uint8_t g; - uint8_t a; -} __attribute__((__packed__)) pixel_t; - -// All 32 strips worth of data for each pixel are stored adjacent -// This makes it easier to clock out while reading from the DDR -// in a burst mode.. -typedef struct { - pixel_t strip[32]; -} __attribute__((__packed__)) pixel_slice_t; - -// mapped to the L3 shared with the PRU -static pixel_slice_t * pixels; - -static unsigned int -proc_read( - const char * const fname -) -{ - FILE * const f = fopen(fname, "r"); - if (!f) - die("%s: Unable to open: %s", fname, strerror(errno)); - unsigned int x; - fscanf(f, "%x", &x); - fclose(f); - return x; -} - - -static ws281x_command_t * -ws281_init( - const unsigned short pruNum, - const unsigned num_pixels -) -{ - void * pruDataMem; - prussdrv_map_prumem( - pruNum == 0 ? PRUSS0_PRU0_DATARAM :PRUSS0_PRU1_DATARAM, - &pruDataMem - ); - - const int mem_fd = open("/dev/mem", O_RDWR); - if (mem_fd < 0) - die("Failed to open /dev/mem: %s\n", strerror(errno)); - - const uintptr_t ddr_addr = proc_read("/sys/class/uio/uio0/maps/map1/addr"); - const uintptr_t ddr_size = proc_read("/sys/class/uio/uio0/maps/map1/size"); - - const uintptr_t ddr_start = 0x10000000; - const uintptr_t ddr_offset = ddr_addr - ddr_start; - const size_t ddr_filelen = ddr_size + ddr_start; - - /* map the memory */ - uint8_t * const ddr_mem = mmap( - 0, - ddr_filelen, - PROT_WRITE | PROT_READ, - MAP_SHARED, - mem_fd, - ddr_offset - ); - if (ddr_mem == MAP_FAILED) - die("Failed to mmap offset %"PRIxPTR" @ %zu bytes: %s\n", - ddr_offset, - ddr_filelen, - strerror(errno) - ); - - ws281x_command_t * const cmd = (void*) pruDataMem; - cmd->pixels_dma = ddr_addr; - cmd->size = num_pixels; - cmd->command = 0; - cmd->response = 0; - - const size_t pixel_size = num_pixels * 32 * 4; - - if (pixel_size > ddr_size) - die("Pixel data needs at least %zu, only %zu in DDR\n", - pixel_size, - ddr_size - ); - -#if 0 - prussdrv_map_l3mem (&l3mem); - pixels = l3mem; -#else - pixels = (void*)(ddr_mem + ddr_start); -#endif - - // Store values into source - printf("data ram %p l3 ram %p: setting %zu bytes\n", - cmd, - pixels, - pixel_size - ); - - - return cmd; -} - - -static void -set_color( - uint8_t strip, - uint8_t pixel, - uint8_t r, - uint8_t g, - uint8_t b -) -{ - pixel_t * const p = &pixels[pixel].strip[strip]; - p->r = r; - p->g = g; - p->b = b; -} - - -static void -fill_color( - int num_pixels, - uint8_t r, - uint8_t g, - uint8_t b -) -{ - size_t i; - for(i=0 ; i < num_pixels ; i++) - { - int strip; - for(strip=0 ; strip < 32; strip++) - { - set_color(strip, i, r, g, b); - } - } -} - - -int main (void) -{ - prussdrv_init(); - - int ret = prussdrv_open(PRU_EVTOUT_0); - if (ret) - die("prussdrv_open open failed\n"); - - tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA; - prussdrv_pruintc_init(&pruss_intc_initdata); - - const int num_pixels = 256; - ws281x_command_t * cmd = ws281_init(PRU_NUM, num_pixels); - - prussdrv_exec_program (PRU_NUM, "./ws281x.bin"); - - unsigned i = 0; - while (1) - { - printf(" starting %d!\n", ++i); - uint8_t val = i >> 1; - fill_color(num_pixels, val, 0, val); - for (int strip = 0 ; strip < 32 ; strip++) - { - //uint8_t r = ((strip >> 2) & 0x3) * 64; - //uint8_t g = ((strip >> 0) & 0x3) * 64; - //uint8_t b = ((strip >> 4) & 0x3) * 64; - set_color(strip, 0, val, 0, 0); - set_color(strip, 1, 0, val + 80, 0); - set_color(strip, 2, 0, 0, val + 160); - } - - cmd->response = 0; - cmd->command = 1; - while (!cmd->response) - ; - const uint32_t * next = (uint32_t*)(cmd + 1); - printf("done! %08x %08x", cmd->response, *next); - //if (cmd->response > 0x2900) break; - } - - // Signal a halt command - cmd->command = 0xFF; - - prussdrv_pru_wait_event(PRU_EVTOUT_0); - prussdrv_pru_clear_event(PRU0_ARM_INTERRUPT); - prussdrv_pru_disable(PRU_NUM); - prussdrv_exit(); - - return EXIT_SUCCESS; -} - diff --git a/ws281x.p b/ws281x.p index aa139052..90672edb 100644 --- a/ws281x.p +++ b/ws281x.p @@ -221,6 +221,10 @@ START: MOV r1, CTPPR_1 ST32 r0, r1 + // Write a 0x1 into the response field so that they know we have started + MOV r2, #0x1 + SBCO r2, CONST_PRUDRAM, 12, 4 + // Wait for the start condition from the main program to indicate // that we have a rendered frame ready to clock out. This also // handles the exit case if an invalid value is written to the start @@ -398,7 +402,7 @@ WORD_LOOP: // long it took to write out. MOV r8, 0x22000 // control register LBBO r2, r8, 0xC, 4 - SBCO r2, CONST_PRUDRAM, 12, 8 + SBCO r2, CONST_PRUDRAM, 12, 4 // Go back to waiting for the next frame buffer QBA _LOOP From e130d28553c8e00d5c8a6b6e4adafd21967a754d Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Mon, 29 Jul 2013 20:22:55 -0400 Subject: [PATCH 003/332] Rework for new API --- README.md | 85 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 3424077f..06017217 100644 --- a/README.md +++ b/README.md @@ -42,62 +42,75 @@ on the length of th elongest strip. API === -There is a command structure shared in PRU DRAM that holds a pointer -to the current frame buffer, the length in pixels, a command byte and -a response byte. + defines the API. The sample rgb-test program pulses +the first three LEDs in red, green and blue. The key components are: - typedef struct - { - // in the DDR shared with the PRU - const uintptr_t pixels_dma; + ledscape_t * ledscape_init(unsigned num_pixels) + ledscape_frame_t * ledscape_frame(ledscape_t*, unsigned frame_num); + ledscape_draw(ledscape_t*, unsigned frame_num); + unsigned ledscape_wait(ledscape_t*) - // Length in pixels of the longest LED strip. - unsigned size; +You can double buffer like this: - // write 1 to start, 0xFF to abort. will be cleared when started - volatile unsigned command; - - // will have a non-zero response written when done - volatile unsigned response; - } __attribute__((__packed__)) ws281x_command_t; - -Once the PRU has cleared the command byte you are free to re-write the -dma address or number of pixels. You can double buffer like this: - - unsigned frame_id = 0; - pixel_slice_t * frames[2]; - uintptr_t frames_dma[2]; + const int num_pixels = 256; + ledscape_t * const leds = ledscape_init(num_pixels); + unsigned i = 0; while (1) { - render(frames[frame_id]); - cmd->pixels_dma = frames_dma[frame_id]; - - // wait for the previous frame to finish display - while(!cmd->reponse) - ; + // Alternate frame buffers on each draw command + const unsigned frame_num = i++ % 2; + ledscape_frame_t * const frame + = ledscape_frame(leds, frame_num); - // Send the start command and wait for the ack - cmd->command = 1; - while(cmd->command) - ; + render(frame); - frame_id = (frame_id+1) % 2; + // wait for the previous frame to finish; + ledscape_wait(leds); + ledscape_draw(leds, frame_num); } + ledscape_close(leds); + The 24-bit RGB data to be displayed is laid out with BRGA format, since that is how it will be translated during the clock out from the PRU. +The frame buffer is stored as a "strip-major" array of pixels. typedef struct { uint8_t b; uint8_t r; uint8_t g; uint8_t a; - } __attribute__((__packed__)) pixel_t; + } __attribute__((__packed__)) ledscape_pixel_t; typedef struct { - pixel_t strip[32]; - } __attribute__((__packed__)) pixel_slice_t; + ledscape_pixel_t strip[32]; + } __attribute__((__packed__)) ledscape_frame_t; + + +Low level API +============= + +If you want to poke at the PRU directly, there is a command structure +shared in PRU DRAM that holds a pointer to the current frame buffer, +the length in pixels, a command byte and a response byte. +Once the PRU has cleared the command byte you are free to re-write the +dma address or number of pixels. + + typedef struct + { + // in the DDR shared with the PRU + const uintptr_t pixels_dma; + + // Length in pixels of the longest LED strip. + unsigned num_pixels; + + // write 1 to start, 0xFF to abort. will be cleared when started + volatile unsigned command; + + // will have a non-zero response written when done + volatile unsigned response; + } __attribute__((__packed__)) ws281x_command_t; LED Strips ========== From 0c3b41f19f77728151f39eee630bbe99a8008a9d Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Tue, 30 Jul 2013 19:14:21 -0400 Subject: [PATCH 004/332] Fix clean to remove all .o --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 0f451eb8..e7126318 100755 --- a/Makefile +++ b/Makefile @@ -19,7 +19,6 @@ LDFLAGS += \ -lpthread \ PASM := ../../utils/pasm_2 -OBJDIR := obj TARGET := $(BINDIR)/ws281x _DEPS = @@ -42,7 +41,7 @@ ws281x.bin: ws281x.p ws281x.hp .PHONY: clean clean: - rm -rf $(OBJDIR)/ *~ $(INCDIR_APP_LOADER)/*~ $(TARGET) ../bin/ws281x.bin ws281x.bin + rm -rf *.o *.i *~ $(INCDIR_APP_LOADER)/*~ $(TARGET) ../bin/ws281x.bin ws281x.bin SLOT_FILE=/sys/devices/bone_capemgr.8/slots dts: LEDscape.dts From 749d3ed045d9258c599627538f3ae566a0ab312f Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Tue, 30 Jul 2013 19:14:37 -0400 Subject: [PATCH 005/332] fix typos and missing functions (still not tested) --- pru.c | 16 ++++++++-------- rgb-test.c | 25 ++++++++++++++++++------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/pru.c b/pru.c index 229aab96..5d8f623b 100644 --- a/pru.c +++ b/pru.c @@ -49,7 +49,7 @@ pru_init( void * pru_data_mem; prussdrv_map_prumem( pru_num == 0 ? PRUSS0_PRU0_DATARAM :PRUSS0_PRU1_DATARAM, - &pru_data_mem; + &pru_data_mem ); const int mem_fd = open("/dev/mem", O_RDWR); @@ -83,15 +83,15 @@ pru_init( pru_t * const pru = calloc(1, sizeof(*pru)); if (!pru) - die("calloc failed", strerror(errno)); + die("calloc failed: %s", strerror(errno)); *pru = (pru_t) { .pru_num = pru_num, .data_ram = pru_data_mem, .data_ram_size = 8192, // how to determine? - .dma_addr = ddr_addr, - .dma = (void*)(ddr_mem + ddr_start), - .dma_size = ddr_size, + .ddr_addr = ddr_addr, + .ddr = (void*)(ddr_mem + ddr_start), + .ddr_size = ddr_size, }; printf("%s: PRU %d: data %p @ %zu bytes, DMA %p / %"PRIxPTR" @ %zu bytes\n", @@ -99,9 +99,9 @@ pru_init( pru_num, pru->data_ram, pru->data_ram_size, - pru->dma, - pru->dma_addr, - pru->dma_size + pru->ddr, + pru->ddr_addr, + pru->ddr_size ); return pru; diff --git a/rgb-test.c b/rgb-test.c index 32ab94e0..2ec2c9f4 100644 --- a/rgb-test.c +++ b/rgb-test.c @@ -10,6 +10,20 @@ #include #include "ledscape.h" +static void +ledscape_fill_color( + ledscape_frame_t * const frame, + const unsigned num_pixels, + const uint8_t r, + const uint8_t g, + const uint8_t b +) +{ + for (unsigned i = 0 ; i < num_pixels ; i++) + for (unsigned strip = 0 ; strip < LEDSCAPE_NUM_STRIPS ; strip++) + ledscape_set_color(frame, strip, i, r, g, b); +} + int main (void) { @@ -25,16 +39,13 @@ int main (void) = ledscape_frame(leds, frame_num); uint8_t val = i >> 1; - fill_color(frame, num_pixels, val, 0, val); + ledscape_fill_color(frame, num_pixels, val, 0, val); for (int strip = 0 ; strip < 32 ; strip++) { - //uint8_t r = ((strip >> 2) & 0x3) * 64; - //uint8_t g = ((strip >> 0) & 0x3) * 64; - //uint8_t b = ((strip >> 4) & 0x3) * 64; - ledscale_set_color(frame, strip, 0, val, 0, 0); - ledscale_set_color(frame, strip, 1, 0, val + 80, 0); - ledscale_set_color(frame, strip, 2, 0, 0, val + 160); + ledscape_set_color(frame, strip, 0, val, 0, 0); + ledscape_set_color(frame, strip, 1, 0, val + 80, 0); + ledscape_set_color(frame, strip, 2, 0, 0, val + 160); } // wait for the previous frame to finish; From 54dd1688adf4ef2ce28e995409e63d04ce83795c Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Tue, 30 Jul 2013 19:34:51 -0400 Subject: [PATCH 006/332] Moved GPIO setup functions into pru.[ch], no longer need pin-setup tool --- ledscape.c | 41 ++++++++++++++++++++++++++++++++++++++- pin-setup | 30 ----------------------------- pru.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ pru.h | 16 ++++++++++++++++ 4 files changed, 112 insertions(+), 31 deletions(-) delete mode 100755 pin-setup diff --git a/ledscape.c b/ledscape.c index f8c610e4..21e8161f 100644 --- a/ledscape.c +++ b/ledscape.c @@ -1,7 +1,6 @@ /** \file * Userspace interface to the WS281x LED strip driver. * - * \todo Package this into a library, possible a Python module. */ #include #include @@ -14,6 +13,36 @@ #include "pru.h" +/** GPIO pins used by the LEDscape. + * + * The device tree should handle this configuration for us, but it + * seems horribly broken and won't configure these pins as outputs. + * So instead we have to repeat them here as well. + * + * If these are changed, be sure to check the mappings in + * ws281x.p! + * + * \todo: Find a way to unify this with the defines in the .p file + */ +static const uint8_t gpios0[] = { + 2, 3, 4, 5, 7, 12, 13, 14, 15, 20, 22, 23, 26, 27, 30, 31, +}; + +static const uint8_t gpios1[] = { + 12, 13, 14, 15, 16, 17, 18, 19, 28, 29, +}; + +static const uint8_t gpios2[] = { + 1, 2, 3, 4, 5, +}; + +static const uint8_t gpios3[] = { + 16, 19, +}; + +#define ARRAY_COUNT(a) ((sizeof(a) / sizeof(*a))) + + /** Command structure shared with the PRU. * * This is mapped into the PRU data RAM and points to the @@ -128,6 +157,16 @@ ledscape_init( .num_pixels = leds->num_pixels, }; + // Configure all of our output pins. + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios0) ; i++) + pru_gpio(0, gpios0[i], 1, 0); + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios1) ; i++) + pru_gpio(1, gpios1[i], 1, 0); + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios2) ; i++) + pru_gpio(2, gpios2[i], 1, 0); + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios3) ; i++) + pru_gpio(3, gpios3[i], 1, 0); + // Initiate the PRU program pru_exec(pru, "./ws281x.bin"); diff --git a/pin-setup b/pin-setup deleted file mode 100755 index 1af7c900..00000000 --- a/pin-setup +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -# WTF device tree? So much work, and you still don't set the pin -# direction? - -gpio_output() { - gpio=$1 - n=$2 - pin=`expr 32 \* $gpio + $n` - echo "Exporting GPIO$gpio.$n: pin $pin" - echo $pin > /sys/class/gpio/unexport - echo $pin > /sys/class/gpio/export - echo 0 > /sys/class/gpio/gpio$pin/value - echo out > /sys/class/gpio/gpio$pin/direction -} - -for pin in 2 3 4 5 7 12 13 14 15 20 22 23 26 27 30 31; do - gpio_output 0 $pin -done - -for pin in 12 13 14 15 16 17 18 19 28 29; do - gpio_output 1 $pin -done - -for pin in 1 2 3 4 5; do - gpio_output 2 $pin -done - -for pin in 16 19; do - gpio_output 3 $pin -done diff --git a/pru.c b/pru.c index 5d8f623b..b18034d1 100644 --- a/pru.c +++ b/pru.c @@ -130,3 +130,59 @@ pru_close( prussdrv_pru_disable(pru->pru_num); prussdrv_exit(); } + + +int +pru_gpio( + const unsigned gpio, + const unsigned pin, + const unsigned direction, + const unsigned initial_value +) +{ + const unsigned pin_num = gpio * 32 + pin; + const char * export_name = "/sys/class/gpio/export"; + FILE * const export = fopen(export_name, "w"); + if (!export) + die("%s: Unable to open? %s\n", + export_name, + strerror(errno) + ); + + fprintf(export, "%d\n", pin_num); + fclose(export); + + char value_name[64]; + snprintf(value_name, sizeof(value_name), + "/sys/class/gpio%u/value", + pin_num + ); + + FILE * const value = fopen(value_name, "w"); + if (!value) + die("%s: Unable to open? %s\n", + value_name, + strerror(errno) + ); + + fprintf(value, "%d\n", initial_value); + fclose(value); + + char dir_name[64]; + snprintf(dir_name, sizeof(dir_name), + "/sys/class/gpio%u/direction", + pin_num + ); + + FILE * const dir = fopen(dir_name, "w"); + if (!dir) + die("%s: Unable to open? %s\n", + dir_name, + strerror(errno) + ); + + fprintf(dir, "%s\n", direction ? "out" : "in"); + fclose(dir); + + return 0; +} diff --git a/pru.h b/pru.h index b5f9a610..ff851d94 100644 --- a/pru.h +++ b/pru.h @@ -53,5 +53,21 @@ pru_close( } while (0) +/** Configure a GPIO pin. + * + * Since the device tree won't do it for us, we need to do it via + * /sys/class/gpio to set the direction and initial value for + * all of the pins that we use. + * + * Direction 0 == in, 1 == out. + */ +extern int +pru_gpio( + unsigned gpio, + unsigned pin, + unsigned direction, + const unsigned initial_value +); + #endif From 623f3fa300d6695e1dfce0d211b7dcd61bd42487 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Tue, 30 Jul 2013 19:38:20 -0400 Subject: [PATCH 007/332] ignore generated files --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..d87e1e4e --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.*.swp +.*.swo +*.i +*.o +*.a +*.bin From 54d69cb9088a3e82ffe191af3877ad2557b60258 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 1 Jan 2000 00:10:17 +0000 Subject: [PATCH 008/332] fix targets --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e7126318..223cdf3b 100755 --- a/Makefile +++ b/Makefile @@ -2,7 +2,6 @@ LIBDIR_APP_LOADER?=../../app_loader/lib INCDIR_APP_LOADER?=../../app_loader/include -BINDIR?=. CFLAGS += \ -std=c99 \ @@ -19,7 +18,7 @@ LDFLAGS += \ -lpthread \ PASM := ../../utils/pasm_2 -TARGET := $(BINDIR)/ws281x +TARGET := rgb-test _DEPS = DEPS = $(patsubst %,$(INCDIR_APP_LOADER)/%,$(_DEPS)) From 17797b730fcfc78fe227eaeafbd307f971e860c3 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 1 Jan 2000 00:10:32 +0000 Subject: [PATCH 009/332] Fix sense of pru exec and path to gpio lines --- pru.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pru.c b/pru.c index b18034d1..7b2f81ad 100644 --- a/pru.c +++ b/pru.c @@ -114,7 +114,8 @@ pru_exec( const char * const program ) { - if (!prussdrv_exec_program(pru->pru_num, program)) + char * program_unconst = (char*)(uintptr_t) program; + if (prussdrv_exec_program(pru->pru_num, program_unconst) < 0) die("%s failed", program); } @@ -154,7 +155,7 @@ pru_gpio( char value_name[64]; snprintf(value_name, sizeof(value_name), - "/sys/class/gpio%u/value", + "/sys/class/gpio/gpio%u/value", pin_num ); @@ -170,7 +171,7 @@ pru_gpio( char dir_name[64]; snprintf(dir_name, sizeof(dir_name), - "/sys/class/gpio%u/direction", + "/sys/class/gpio/gpio%u/direction", pin_num ); From 17024a9a093cbbe84329a919fa375ff9ab7f9400 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 1 Jan 2000 00:11:55 +0000 Subject: [PATCH 010/332] Fix frame offset computation for double buffering --- ledscape.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ledscape.c b/ledscape.c index 21e8161f..e57cb396 100644 --- a/ledscape.c +++ b/ledscape.c @@ -72,7 +72,6 @@ struct ledscape pru_t * pru; unsigned num_pixels; size_t frame_size; - ledscape_frame_t * frames[2]; }; @@ -86,7 +85,7 @@ ledscape_frame( if (frame >= 2) return NULL; - return (ledscape_frame_t*)((uint8_t*) leds->pru->ddr + leds->frame_size); + return (ledscape_frame_t*)((uint8_t*) leds->pru->ddr + leds->frame_size * frame); } @@ -97,7 +96,7 @@ ledscape_draw( unsigned int frame ) { - leds->ws281x->pixels_dma = leds->pru->ddr_addr + leds->frame_size; + leds->ws281x->pixels_dma = leds->pru->ddr_addr + leds->frame_size * frame; // Wait for any current command to have been acknowledged while (leds->ws281x->command) From 19ebc8ea1709400134cc7779c4a241ad6017884a Mon Sep 17 00:00:00 2001 From: root Date: Sat, 1 Jan 2000 00:31:18 +0000 Subject: [PATCH 011/332] Track fps. Currently 73 --- rgb-test.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/rgb-test.c b/rgb-test.c index 2ec2c9f4..79219a80 100644 --- a/rgb-test.c +++ b/rgb-test.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,8 @@ int main (void) { const int num_pixels = 256; ledscape_t * const leds = ledscape_init(num_pixels); + time_t last_time = time(NULL); + unsigned last_i = 0; unsigned i = 0; while (1) @@ -39,7 +42,7 @@ int main (void) = ledscape_frame(leds, frame_num); uint8_t val = i >> 1; - ledscape_fill_color(frame, num_pixels, val, 0, val); + //ledscape_fill_color(frame, num_pixels, val, 0, val); for (int strip = 0 ; strip < 32 ; strip++) { @@ -50,7 +53,14 @@ int main (void) // wait for the previous frame to finish; const uint32_t response = ledscape_wait(leds); - printf("starting %d previous %"PRIx32"\n", i, response); + time_t now = time(NULL); + if (now != last_time) + { + printf("%d fps. starting %d previous %"PRIx32"\n", + i - last_i, i, response); + last_i = i; + last_time = now; + } ledscape_draw(leds, frame_num); } From 439f323055af9613788af876c90c842a765783ee Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 28 Jul 2013 10:45:26 -0400 Subject: [PATCH 012/332] Cortex-A8 not OMAP --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5a8ab1cc..3424077f 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,9 @@ DANGER! This code works with the PRU units on the Beagle Bone and can easily cause *hard crashes*. It is still being debugged and developed. +Be careful hot-plugging things into the headers -- it is possible to +damage the pin drivers and cause problems in the ARM, especially if +there are +5V signals involved. Overview @@ -17,8 +20,8 @@ between bits. Since this doesn't map to normal SPI hardware and requires an 800 KHz bit clock, it is typically handled with a dedicated microcontroller or DMA hardware on something like the Teensy 3. -However, the TI OMAP in the BeagleBone Black has two programmable -"microcontrollers" built into the CPU that can handle real time +However, the TI AM335x ARM Cortex-A8 in the BeagleBone Black has two +programmable "microcontrollers" built into the CPU that can handle realtime tasks and also access the ARM's memory. This allows things that might have been delegated to external devices to be handled without any additional hardware, and without the overhead of clocking data out @@ -32,7 +35,8 @@ like this in RAM: This way length of the strip can be variable, although the memory used will depend on the length of the longest strip. 4 * 32 * longest strip -bytes are required per frame buffer. +bytes are required per frame buffer. The maximum frame rate also depends +on the length of th elongest strip. API From 996673fc23d7083c031dd92da1166f16702e6345 Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Wed, 31 Jul 2013 23:11:48 +0800 Subject: [PATCH 013/332] Update board to use 2x8 RJ45 connector --- pcb/LEDscape.brd | 1062 +++++++------ pcb/LEDscape.sch | 3702 ++++++++++++++++++++++++---------------------- 2 files changed, 2566 insertions(+), 2198 deletions(-) diff --git a/pcb/LEDscape.brd b/pcb/LEDscape.brd index da1f6c99..3e65f333 100644 --- a/pcb/LEDscape.brd +++ b/pcb/LEDscape.brd @@ -1,21 +1,35 @@ - + - + + + + + + + + + + + + + + + - + @@ -38,10 +52,10 @@ - + - + @@ -118,16 +132,143 @@ + + + + + + + + + + + + + + + + + + + + - + +<b>Maxim Components</b><p> + +<author>Created by librarian@cadsoft.de</author> - - - - - - + +<b>Thin Shrink Small Outline Plastic 16</b><p> +http://www.maxim-ic.com .. MAX3223-MAX3243.pdf + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -452,16 +593,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -656,82 +797,6 @@ - - - - - - - - - - - - - - ->Name ->Value -+ -- - - - - -<b>Maxim Components</b><p> - -<author>Created by librarian@cadsoft.de</author> - - -<b>Small Outline Package</b> .150 SIOC<p> -Source: http://www.maxim-ic.com/package_drawings/21-0041B.pdf - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->VALUE ->NAME - - - - - - - - - - - - - - - - - @@ -920,105 +985,70 @@ design rules under a new name. - - - - - - + + + + + + - - - - - - - - - + + + + + - - - - - - - - - + + + + + - - - - - - - - - + + + + + - - - - - - - - - + + + + + - - - - - - - - - + + + + + - - - - - - - - - + + + + + - - - - - - - - - + + + + + - - - - + + + + + + + + + - - - - - - - - - - - - @@ -1033,31 +1063,88 @@ design rules under a new name. - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + @@ -1089,515 +1176,612 @@ design rules under a new name. - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + + + + + - + + + + + + + + - + + + + + - + + + + + + - + + + + - + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - + + - - + + - - - - - - - - - - - - + + - - + + - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - + + + + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - + + - - + + - - - - - - - - - - - - + + - - + + - - - - - - - - - - - - + + - + + + - + + + + - + - + - + - + + - + - + + + + + + + - + + + + + + + - + + + + + + + + + + + + + - + + + + + + + - + + + - + + + + + + + - + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcb/LEDscape.sch b/pcb/LEDscape.sch index 52ea8bd7..25f09869 100644 --- a/pcb/LEDscape.sch +++ b/pcb/LEDscape.sch @@ -1,6 +1,6 @@ - + @@ -9,6 +9,20 @@ + + + + + + + + + + + + + + @@ -118,1381 +132,1365 @@ - + +<b>Maxim Components</b><p> + +<author>Created by librarian@cadsoft.de</author> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE ->NAME ->VALUE -P8 -P9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -2-Pin JST PH Series Right-Angle Connector (+/- for batteries) - - - - - - - - - - - - - - - - - - - - - ->Name ->Value -+ -- - - -4UCon #01528 -http://www.4uconnector.com/online/object/4udrawing/01528.pdf - - - - - - - - - - ->NAME -+ -- - - -<b>S2B-PH-K-S</b> -<p> -JST PH 2-pin thru-home side entry - - - - - - - - - - - - - - ->NAME -+ -- + +<b>Thin Shrink Small Outline Plastic 16</b><p> +http://www.maxim-ic.com .. MAX3223-MAX3243.pdf + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - ->Name ->Value -+ -- + +<b>Small Outline Package</b> .150 SIOC<p> +Source: http://www.maxim-ic.com/package_drawings/21-0041B.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + + + + + + + + + + + - - - - - - - - - - - ->NAME ->VALUE -P8 -P9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - + +<b>Small Outline Package</b> .300 SIOC<p> +Source: http://www.maxim-ic.com/cgi-bin/packages?pkg=16%2FSOIC%2E300&Type=Max + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +Z +Y +Z +Y +Z +Y +Z +Y + + + + + + + + + + + + + + + + - -Should match A3 pinout - but not completely tested - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>JST 2-Pin Connectors of various flavors</b> - -<ul> -<li>SMT-RA (S2B-PH-SM4) 4UConnector #17311</li> -<li>SMT (B2B-PH-SM4)</li> -<li>THM-RA (S2B-PH)</li> -<li>THM (B2B-PH)</li> -</ul> + +<b>±10kV ESD-Protected, Quad 5V RS-485/RS-422 Transmitters</b><p> +Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - + - - - - - - - - - - + - - + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - -<b>Maxim Components</b><p> - -<author>Created by librarian@cadsoft.de</author> + +<b>Supply Symbols</b><p> + GND, VCC, 0V, +5V, -5V, etc.<p> + Please keep in mind, that these devices are necessary for the + automatic wiring of the supply signals.<p> + The pin name defined in the symbol is identical to the net which is to be wired automatically.<p> + In this library the device names are the same as the pin names of the symbols, therefore the correct signal names appear next to the supply symbols in the schematic.<p> + <author>Created by librarian@cadsoft.de</author> - -<b>Thin Shrink Small Outline Plastic 16</b><p> -http://www.maxim-ic.com .. MAX3223-MAX3243.pdf - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - -<b>Small Outline Package</b> .150 SIOC<p> -Source: http://www.maxim-ic.com/package_drawings/21-0041B.pdf - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->VALUE ->NAME - - - - - - - - - - - - - - - - + + + + + +>VALUE + + + + +>VALUE + + + + + +<b>SUPPLY SYMBOL</b> + + + + + + + + + + + + +<b>SUPPLY SYMBOL</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - -<b>Small Outline Package</b> .300 SIOC<p> -Source: http://www.maxim-ic.com/cgi-bin/packages?pkg=16%2FSOIC%2E300&Type=Max - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->VALUE ->NAME - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +>NAME +>VALUE +P8 +P9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -Z -Y -Z -Y -Z -Y -Z -Y - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +P8 +P9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - -<b>±10kV ESD-Protected, Quad 5V RS-485/RS-422 Transmitters</b><p> -Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - -<b>Supply Symbols</b><p> - GND, VCC, 0V, +5V, -5V, etc.<p> - Please keep in mind, that these devices are necessary for the - automatic wiring of the supply signals.<p> - The pin name defined in the symbol is identical to the net which is to be wired automatically.<p> - In this library the device names are the same as the pin names of the symbols, therefore the correct signal names appear next to the supply symbols in the schematic.<p> - <author>Created by librarian@cadsoft.de</author> - - - - - - ->VALUE - - - - ->VALUE - - - - - -<b>SUPPLY SYMBOL</b> + - + - + + + + + + + + + + + + + + + + + + + - -<b>SUPPLY SYMBOL</b> + +Should match A3 pinout - but not completely tested - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1511,75 +1509,60 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - + + - - - - - + - - - - - + - - - - - + - - - - - + - - - - - + - - - - - + - - - - - + - - - - + + + + + + + + + + + + + + + + + @@ -1590,71 +1573,56 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1690,50 +1658,50 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - + + + @@ -1754,50 +1722,50 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - - + + + @@ -1819,17 +1787,17 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - + - + - + @@ -1839,78 +1807,231 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + - - + + + + - - - + + + + - - + + + + - - - + + + + - - + + + + - - - + + + + @@ -1964,8 +2085,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -1976,8 +2097,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -1988,428 +2109,329 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - + + - - - + + + - - + + + + - - - + + + + - - + + + + - - - + + + + - - + + + + - - - + + + + - - + + - - - + + + - - - - - - - - - - + + + + - - + + + + - - - - - - - - - - - - - - - - - - + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - + + + + - - + + - - + + - - + + + + - - - + + + + - - + + + + - - - + + + + - - + + + + - - - + + + + - - + + - - - + + + - - - - - - - - - - + + + + - - + + + + - - - + + + + - - + + + + - - - + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - + + + + - - + + - - - - - - - - - - - - - - - - - - + + + - - + + + + - - - - - - - - - - - - - - - - - - + + + + - - @@ -2420,8 +2442,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2432,8 +2454,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2444,8 +2466,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2456,8 +2478,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2468,8 +2490,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2480,8 +2502,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2492,8 +2514,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2504,8 +2526,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2516,8 +2538,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2576,8 +2598,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2588,8 +2610,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2600,8 +2622,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2612,8 +2634,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2624,8 +2646,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2636,8 +2658,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2648,8 +2670,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2660,8 +2682,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2672,8 +2694,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2684,8 +2706,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2696,8 +2718,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2708,8 +2730,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - @@ -2724,6 +2746,168 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 16c106ecf0f9d43b6e068ad8973a61eb03ae388d Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Wed, 31 Jul 2013 23:12:50 +0800 Subject: [PATCH 014/332] Add datasheets for the RS485 transcever, RJ45 jack --- pcb/datasheets/10118074.pdf | Bin 0 -> 196965 bytes pcb/datasheets/MAX3040_.pdf | Bin 0 -> 251328 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 pcb/datasheets/10118074.pdf create mode 100644 pcb/datasheets/MAX3040_.pdf diff --git a/pcb/datasheets/10118074.pdf b/pcb/datasheets/10118074.pdf new file mode 100644 index 0000000000000000000000000000000000000000..933ff2a490748c46659dfd5117f032df414a1044 GIT binary patch literal 196965 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%0A?CQW5i8R+3l8QW;Mon+77z;pM^HRj< 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%0DEM_``_T_!;_T@- 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

kL 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�(W1TIraS9nzNJ^%AUNy|X%4 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 zℑ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 Ds7MyH literal 0 HcmV?d00001 From 31afb764bb98948740290df5947be98cd82d7321 Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Wed, 31 Jul 2013 23:13:21 +0800 Subject: [PATCH 015/332] Add library for the board, RJ45 jack --- pcb/LEDscape.lbr | 1020 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1020 insertions(+) create mode 100644 pcb/LEDscape.lbr diff --git a/pcb/LEDscape.lbr b/pcb/LEDscape.lbr new file mode 100644 index 00000000..189946c9 --- /dev/null +++ b/pcb/LEDscape.lbr @@ -0,0 +1,1020 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +>NAME +>VALUE +P8 +P9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +P8 +P9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Should match A3 pinout - but not completely tested + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 8a411d1fdd803688ed3efd88dabe3ebe71a5f5b3 Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Thu, 1 Aug 2013 04:18:37 +0800 Subject: [PATCH 016/332] Flip board over (put everything on the front, not the back), add caps, work on routing. --- pcb/LEDscape.brd | 1499 ++++++++++++++------ pcb/LEDscape.lbr | 6 +- pcb/LEDscape.sch | 3381 ++++++++++++++++++++++++++++++++++++++++++++++ pcb/TODO | 11 + 4 files changed, 4458 insertions(+), 439 deletions(-) create mode 100644 pcb/TODO diff --git a/pcb/LEDscape.brd b/pcb/LEDscape.brd index 3e65f333..494e12c0 100644 --- a/pcb/LEDscape.brd +++ b/pcb/LEDscape.brd @@ -9,27 +9,27 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + - + @@ -46,20 +46,20 @@ - - - - - + + + + + - + - + - - + + @@ -72,50 +72,50 @@ - - + + - - - - + + + + - - - - - + + + + + - - - - + + + + - - - - - + + + + + - - - - - - + + + + + + - - - - - - + + + + + + @@ -124,34 +124,40 @@ - - + + - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + ++ +- +- +- +- +- @@ -242,6 +248,10 @@ http://www.maxim-ic.com .. MAX3223-MAX3243.pdf + + + + @@ -799,6 +809,265 @@ http://www.maxim-ic.com .. MAX3223-MAX3243.pdf + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + + + +<b>Molex Connectors</b><p> +<author>Created by librarian@cadsoft.de</author> + + +<b>STACKED MODULAR JACK CATEGORY 5</b><p> +Source: http://www.molex.com/pdm_docs/sd/445200006_sd.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + @@ -808,7 +1077,7 @@ http://www.maxim-ic.com .. MAX3223-MAX3243.pdf - + <b>EAGLE Design Rules</b> <p> Die Standard-Design-Rules sind so gewählt, dass sie für @@ -816,33 +1085,29 @@ die meisten Anwendungen passen. Sollte ihre Platine besondere Anforderungen haben, treffen Sie die erforderlichen Einstellungen hier und speichern die Design Rules unter einem neuen Namen ab. -<b>EAGLE Design Rules</b> +<b>Laen's PCB Order Design Rules</b> <p> -The default Design Rules have been set to cover -a wide range of applications. Your particular design -may have different requirements, so please make the -necessary adjustments and save your customized -design rules under a new name. - - - - - - - - - - - - +Please make sure your boards conform to these design rules. + + + + + + + + + + + + - - + + - - - + + + @@ -851,15 +1116,15 @@ design rules under a new name. - + - + - + - + - + @@ -985,64 +1250,81 @@ design rules under a new name. - - - - - - + + + + + + + + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + @@ -1071,25 +1353,22 @@ design rules under a new name. - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -1097,14 +1376,6 @@ design rules under a new name. - - - - - - - - @@ -1129,554 +1400,793 @@ design rules under a new name. - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - + - - - - - + + + + + - - - - - - - - + + + + + + + + - - - - - + + + + + + + - - - - - - + + + + + + + + + + + + + - - - - + + + + - - - - - + + + + + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + - + + + + + + + + - + + + + + + + + + + + - + + + + + + + - + + + + + + + - + - + - - - - - - - + + + + + - + + + + + + + + + + + - + + + + + + + + + + + + - + + + + + + + - + + + + - + + + + + - + + + + + - + + + + - + + + + + + + + - + + + + + + + - + + + + + + - + + + + + + + + + + + - + + + + + - + + + + + - + + + + - + + + + + + + + - + - + - + + + + + - + - + - + - + - - - + + + - - - - + + + + - + + + + + + + + + + + + - + + + + + + + + + + + + - + + + + + + + + - - + + + + + + + + - + + + + + + + + + + + - - - - - - - + + + + + + + + + + + - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - + + + + + + + + - - - + + + + + + + + - - - - - - - + + + + - - - - - - - - - - + + + + + + - + + + + + + + + - + + + + + - + + + + - + + + + + + + + - + + + + + + + + + + - + + - + + + + + + + + + + + + + - + + + + + + + + + + + - + - + - + - + @@ -1684,103 +2194,216 @@ design rules under a new name. - + + + + + + + - + + + + + + + - + + + + + + + - + + + + + + + - + - + - + + + + + - + + + + - + + + + + + + + - + - + - - - - - - - + + + + + + + + - - + + + + - - - - - + + + + + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcb/LEDscape.lbr b/pcb/LEDscape.lbr index 189946c9..5164c18e 100644 --- a/pcb/LEDscape.lbr +++ b/pcb/LEDscape.lbr @@ -6,7 +6,7 @@ - + @@ -164,6 +164,10 @@ + + + + diff --git a/pcb/LEDscape.sch b/pcb/LEDscape.sch index 25f09869..d8b25ec2 100644 --- a/pcb/LEDscape.sch +++ b/pcb/LEDscape.sch @@ -647,6 +647,10 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf + + + + @@ -1499,6 +1503,3256 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 2.4 x 4.4 mm + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 2.5 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 3 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 4 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 5 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 6 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm + 5 mm, outline 2.4 x 7 mm + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 + 5 mm, outline 2.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 + 5 mm, outline 3.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 + 5 mm, outline 4.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 + 5 mm, outline 5.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 2.4 x 4.4 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 2.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 4.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 3 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 5.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 7.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +Horizontal, grid 5 mm, outline 7.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>CAPACITOR</b><p> +grid 7.5 mm, outline 3.2 x 10.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 7.5 mm, outline 4.2 x 10.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 7.5 mm, outline 5.2 x 10.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 10.2 mm, outline 4.3 x 13.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 10.2 mm, outline 5.4 x 13.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 10.2 mm, outline 6.4 x 13.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 10.2 mm + 15.2 mm, outline 6.2 x 18.4 mm + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 5.4 x 18.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 6.4 x 18.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 7.2 x 18.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 8.4 x 18.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 9.1 x 18.2 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 6.2 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 7.4 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 8.7 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 10.8 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 11.3 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 9.3 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 11.3 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 13.4 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 20.5 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 32.5 mm, outline 13.7 x 37.4 mm + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 32.5 mm, outline 16.2 x 37.4 mm + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 32.5 mm, outline 18.2 x 37.4 mm + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 37.5 mm, outline 19.2 x 41.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 37.5 mm, outline 20.3 x 41.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 3.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 37.5 mm, outline 15.5 x 41.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 7.5 mm, outline 6.3 x 10.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 15.4 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 17.3 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>Ceramic Chip Capacitor KEMET 0204 Reflow solder</b><p> +Metric Code Size 1005 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 0603 Reflow solder</b><p> +Metric Code Size 1608 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 0805 Reflow solder</b><p> +Metric Code Size 2012 + + + + + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 1206 Reflow solder</b><p> +Metric Code Size 3216 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 1210 Reflow solder</b><p> +Metric Code Size 3225 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 1812 Reflow solder</b><p> +Metric Code Size 4532 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 1825 Reflow solder</b><p> +Metric Code Size 4564 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 2220 Reflow solder</b><p> +Metric Code Size 5650 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 2225 Reflow solder</b><p> +Metric Code Size 5664 + + + + +>NAME +>VALUE + + + + + + + + + + +>NAME +>VALUE + + + + + + +<B>CAPACITOR</B>, American symbol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Molex Connectors</b><p> +<author>Created by librarian@cadsoft.de</author> + + +<b>STACKED MODULAR JACK CATEGORY 5</b><p> +Source: http://www.molex.com/pdm_docs/sd/445200006_sd.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + +<b>STACKED MODULAR JACK CATEGORY 5</b><p> +Source: http://www.molex.com/pdm_docs/sd/445200006_sd.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +2mm SMD side-entry connector. tDocu layer indicates the actual physical plastic housing. +/- indicate SparkFun standard batteries and wiring. + + + + + + + + + + + + + +>Name +>Value ++ +- + + + + + + + + + + + + + + + + + + + + + + + + + +>Name +>Value + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + +This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place. +You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line). +This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace" +to hold the component in place. 0.005 has proven to be the perfect amount of "off-center" position when using our standard breakaway headers. +Although looks a little odd when you look at the bare footprint, once you have a header in there, the alteration is very hard to notice. Also, +if you push a header all the way into place, it is covered up entirely on the bottom side. This idea of altering the position of holes to aid alignment +will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins. + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + +>Name +>Value ++ +- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + +>Name +>Value ++ +- + + +<H3>JST-2-PTH-KIT</h3> +2-Pin JST, through-hole connector<br> +<br> +<b>Warning:</b> This is the KIT version of this package. This package has a smaller diameter top stop mask, which doesn't cover the diameter of the pad. This means only the bottom side of the pads' copper will be exposed. You'll only be able to solder to the bottom side. + + + + + + + + + +>Name +>Value ++ +- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + +<b>Header 2</b> +Standard 2-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08233 with associated crimp pins and housings. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1563,6 +4817,23 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf + + + + + + + + + + + + + + + + + @@ -1623,6 +4894,38 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1768,6 +5071,38 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1964,6 +5299,52 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcb/TODO b/pcb/TODO new file mode 100644 index 00000000..31557f46 --- /dev/null +++ b/pcb/TODO @@ -0,0 +1,11 @@ +x-Add bypass caps for MAX3041 chips +x-Add shield holes to back of 8x2 RJ45 header +x-Flip board so the BBB is upside down (rather than the rest of the board) +x-Verify RJ45 pinout +x-Add ground connections +-Fix case positions on RJ45 shield +-Finish routing RJ45 section +-Finish routing digital section +-Add HRC logo +-gpio on p8 pin 42(?) +-Add extra pads for GPIO like the HDMI on p9 From df1e43f577fa2b0829a3bfdfb40a89bced14cdbf Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 31 Jul 2013 20:40:16 -0400 Subject: [PATCH 017/332] ignore temporary eagle files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index d87e1e4e..e31c2a9e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ *.o *.a *.bin +pcb/*.b[^r][^d] +pcb/*.p[^c][^b] From 87dac655ef66f281ef24f8d93caf016f3c59135e Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 31 Jul 2013 20:40:55 -0400 Subject: [PATCH 018/332] Import of am335x tree from git://github.com/beagleboard/am335x_pru_package.git --- .../app_loader/include/pruss_intc_mapping.h | 104 + am335x/app_loader/include/prussdrv.h | 160 ++ am335x/app_loader/interface/Makefile | 66 + am335x/app_loader/interface/__prussdrv.h | 275 +++ am335x/app_loader/interface/prussdrv.c | 660 +++++ am335x/pasm/LICENCE.txt | 39 + am335x/pasm/dosbuild.bat | 3 + am335x/pasm/linuxbuild | 4 + am335x/pasm/macbuild | 4 + am335x/pasm/pasm.c | 1358 +++++++++++ am335x/pasm/pasm.h | 645 +++++ am335x/pasm/pasmdbg.h | 97 + am335x/pasm/pasmdot.c | 446 ++++ am335x/pasm/pasmexp.c | 585 +++++ am335x/pasm/pasmmacro.c | 560 +++++ am335x/pasm/pasmop.c | 2132 +++++++++++++++++ am335x/pasm/pasmpp.c | 1165 +++++++++ am335x/pasm/pasmstruct.c | 1251 ++++++++++ am335x/pasm/pru_ins.h | 176 ++ 19 files changed, 9730 insertions(+) create mode 100644 am335x/app_loader/include/pruss_intc_mapping.h create mode 100644 am335x/app_loader/include/prussdrv.h create mode 100644 am335x/app_loader/interface/Makefile create mode 100644 am335x/app_loader/interface/__prussdrv.h create mode 100644 am335x/app_loader/interface/prussdrv.c create mode 100644 am335x/pasm/LICENCE.txt create mode 100644 am335x/pasm/dosbuild.bat create mode 100755 am335x/pasm/linuxbuild create mode 100644 am335x/pasm/macbuild create mode 100644 am335x/pasm/pasm.c create mode 100644 am335x/pasm/pasm.h create mode 100644 am335x/pasm/pasmdbg.h create mode 100644 am335x/pasm/pasmdot.c create mode 100644 am335x/pasm/pasmexp.c create mode 100644 am335x/pasm/pasmmacro.c create mode 100644 am335x/pasm/pasmop.c create mode 100644 am335x/pasm/pasmpp.c create mode 100644 am335x/pasm/pasmstruct.c create mode 100644 am335x/pasm/pru_ins.h diff --git a/am335x/app_loader/include/pruss_intc_mapping.h b/am335x/app_loader/include/pruss_intc_mapping.h new file mode 100644 index 00000000..0923008e --- /dev/null +++ b/am335x/app_loader/include/pruss_intc_mapping.h @@ -0,0 +1,104 @@ +/* + * pruss_intc_mapping.h + * + * Example PRUSS INTC mapping for the application + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +/* + * ============================================================================ + * Copyright (c) Texas Instruments Inc 2010-11 + * + * Use of this software is controlled by the terms and conditions found in the + * license agreement under which this software has been supplied or provided. + * ============================================================================ +*/ + +#define AM33XX +#ifdef AM33XX +#define PRU0_PRU1_INTERRUPT 17 +#define PRU1_PRU0_INTERRUPT 18 +#define PRU0_ARM_INTERRUPT 19 +#define PRU1_ARM_INTERRUPT 20 +#define ARM_PRU0_INTERRUPT 21 +#define ARM_PRU1_INTERRUPT 22 +#else +#define PRU0_PRU1_INTERRUPT 32 +#define PRU1_PRU0_INTERRUPT 33 +#define PRU0_ARM_INTERRUPT 34 +#define PRU1_ARM_INTERRUPT 35 +#define ARM_PRU0_INTERRUPT 36 +#define ARM_PRU1_INTERRUPT 37 +#endif +#define CHANNEL0 0 +#define CHANNEL1 1 +#define CHANNEL2 2 +#define CHANNEL3 3 +#define CHANNEL4 4 +#define CHANNEL5 5 +#define CHANNEL6 6 +#define CHANNEL7 7 +#define CHANNEL8 8 +#define CHANNEL9 9 + +#define PRU0 0 +#define PRU1 1 +#define PRU_EVTOUT0 2 +#define PRU_EVTOUT1 3 +#define PRU_EVTOUT2 4 +#define PRU_EVTOUT3 5 +#define PRU_EVTOUT4 6 +#define PRU_EVTOUT5 7 +#define PRU_EVTOUT6 8 +#define PRU_EVTOUT7 9 + +#define PRU0_HOSTEN_MASK 0x0001 +#define PRU1_HOSTEN_MASK 0x0002 +#define PRU_EVTOUT0_HOSTEN_MASK 0x0004 +#define PRU_EVTOUT1_HOSTEN_MASK 0x0008 +#define PRU_EVTOUT2_HOSTEN_MASK 0x0010 +#define PRU_EVTOUT3_HOSTEN_MASK 0x0020 +#define PRU_EVTOUT4_HOSTEN_MASK 0x0040 +#define PRU_EVTOUT5_HOSTEN_MASK 0x0080 +#define PRU_EVTOUT6_HOSTEN_MASK 0x0100 +#define PRU_EVTOUT7_HOSTEN_MASK 0x0200 + + +#define PRUSS_INTC_INITDATA { \ +{ PRU0_PRU1_INTERRUPT, PRU1_PRU0_INTERRUPT, PRU0_ARM_INTERRUPT, PRU1_ARM_INTERRUPT, ARM_PRU0_INTERRUPT, ARM_PRU1_INTERRUPT, -1 }, \ +{ {PRU0_PRU1_INTERRUPT,CHANNEL1}, {PRU1_PRU0_INTERRUPT, CHANNEL0}, {PRU0_ARM_INTERRUPT,CHANNEL2}, {PRU1_ARM_INTERRUPT, CHANNEL3}, {ARM_PRU0_INTERRUPT, CHANNEL0}, {ARM_PRU1_INTERRUPT, CHANNEL1}, {-1,-1}}, \ + { {CHANNEL0,PRU0}, {CHANNEL1, PRU1}, {CHANNEL2, PRU_EVTOUT0}, {CHANNEL3, PRU_EVTOUT1}, {-1,-1} }, \ + (PRU0_HOSTEN_MASK | PRU1_HOSTEN_MASK | PRU_EVTOUT0_HOSTEN_MASK | PRU_EVTOUT1_HOSTEN_MASK) /*Enable PRU0, PRU1, PRU_EVTOUT0 */ \ +} \ + diff --git a/am335x/app_loader/include/prussdrv.h b/am335x/app_loader/include/prussdrv.h new file mode 100644 index 00000000..90c489b3 --- /dev/null +++ b/am335x/app_loader/include/prussdrv.h @@ -0,0 +1,160 @@ +/* + * prussdrv.h + * + * Describes PRUSS userspace driver for Industrial Communications + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +/* + * ============================================================================ + * Copyright (c) Texas Instruments Inc 2010-11 + * + * Use of this software is controlled by the terms and conditions found in the + * license agreement under which this software has been supplied or provided. + * ============================================================================ +*/ + +#ifndef _PRUSSDRV_H +#define _PRUSSDRV_H + +#include +#include + +#if defined (__cplusplus) +extern "C" { +#endif + +#define NUM_PRU_HOSTIRQS 8 +#define NUM_PRU_HOSTS 10 +#define NUM_PRU_CHANNELS 10 +#define NUM_PRU_SYS_EVTS 64 + +#define PRUSS0_PRU0_DATARAM 0 +#define PRUSS0_PRU1_DATARAM 1 +#define PRUSS0_PRU0_IRAM 2 +#define PRUSS0_PRU1_IRAM 3 + +//Available in AM33xx series - begin +#define PRUSS0_SHARED_DATARAM 4 +#define PRUSS0_CFG 5 +#define PRUSS0_UART 6 +#define PRUSS0_IEP 7 +#define PRUSS0_ECAP 8 +#define PRUSS0_MII_RT 9 +#define PRUSS0_MDIO 10 +//Available in AM33xx series - end + +#define PRU_EVTOUT_0 0 +#define PRU_EVTOUT_1 1 +#define PRU_EVTOUT_2 2 +#define PRU_EVTOUT_3 3 +#define PRU_EVTOUT_4 4 +#define PRU_EVTOUT_5 5 +#define PRU_EVTOUT_6 6 +#define PRU_EVTOUT_7 7 + + typedef void *(*prussdrv_function_handler) (void *); + typedef struct __sysevt_to_channel_map { + short sysevt; + short channel; + } tsysevt_to_channel_map; + typedef struct __channel_to_host_map { + short channel; + short host; + } tchannel_to_host_map; + typedef struct __pruss_intc_initdata { + //Enabled SYSEVTs - Range:0..63 + //{-1} indicates end of list + char sysevts_enabled[NUM_PRU_SYS_EVTS]; + //SysEvt to Channel map. SYSEVTs - Range:0..63 Channels -Range: 0..9 + //{-1, -1} indicates end of list + tsysevt_to_channel_map sysevt_to_channel_map[NUM_PRU_SYS_EVTS]; + //Channel to Host map.Channels -Range: 0..9 HOSTs - Range:0..9 + //{-1, -1} indicates end of list + tchannel_to_host_map channel_to_host_map[NUM_PRU_CHANNELS]; + //10-bit mask - Enable Host0-Host9 {Host0/1:PRU0/1, Host2..9 : PRUEVT_OUT0..7) + unsigned int host_enable_bitmask; + } tpruss_intc_initdata; + + int prussdrv_init(void); + + int prussdrv_open(unsigned int pru_evtout_num); + + int prussdrv_pru_reset(unsigned int prunum); + + int prussdrv_pru_disable(unsigned int prunum); + + int prussdrv_pru_enable(unsigned int prunum); + + int prussdrv_pru_write_memory(unsigned int pru_ram_id, + unsigned int wordoffset, + unsigned int *memarea, + unsigned int bytelength); + + int prussdrv_pruintc_init(tpruss_intc_initdata * prussintc_init_data); + + int prussdrv_map_l3mem(void **address); + + int prussdrv_map_extmem(void **address); + + int prussdrv_map_prumem(unsigned int pru_ram_id, void **address); + + int prussdrv_map_peripheral_io(unsigned int per_id, void **address); + + unsigned int prussdrv_get_phys_addr(void *address); + + void *prussdrv_get_virt_addr(unsigned int phyaddr); + + int prussdrv_pru_wait_event(unsigned int pru_evtout_num); + + int prussdrv_pru_send_event(unsigned int eventnum); + + int prussdrv_pru_clear_event(unsigned int eventnum); + + int prussdrv_pru_send_wait_clear_event(unsigned int send_eventnum, + unsigned int pru_evtout_num, + unsigned int ack_eventnum); + + int prussdrv_exit(void); + + int prussdrv_exec_program(int prunum, char *filename); + + int prussdrv_start_irqthread(unsigned int pru_evtout_num, int priority, + prussdrv_function_handler irqhandler); + + +#if defined (__cplusplus) +} +#endif +#endif diff --git a/am335x/app_loader/interface/Makefile b/am335x/app_loader/interface/Makefile new file mode 100644 index 00000000..0cb0893f --- /dev/null +++ b/am335x/app_loader/interface/Makefile @@ -0,0 +1,66 @@ +ROOTDIR = .. +TARGET = libprussdrv +CROSS_COMPILE?=arm-arago-linux-gnueabi- + +CC = $(CROSS_COMPILE)gcc +AR = $(CROSS_COMPILE)ar + +INCLUDEDIR = ../include +LIBDIR = ../lib + +C_FLAGS += -I. -Wall -I$(INCLUDEDIR) + +COMPILE.c = $(CC) $(C_FLAGS) $(CPP_FLAGS) -c +AR.c = $(AR) rc + +DBGTARGET = $(LIBDIR)/$(TARGET)d.a +RELTARGET = $(LIBDIR)/$(TARGET).a + +DBGCFLAGS = -g -O0 -D__DEBUG +RELCFLAGS = -O3 -mtune=cortex-a8 -march=armv7-a + +SOURCES = $(wildcard *.c) +HEADERS = $(wildcard *.h) + +TARGETHEADERS = $(addprefix $(INCLUDEDIR)/, $(HEADERS)) + +DBGOBJFILES = $(SOURCES:%.c=debug/%.o) +RELOBJFILES = $(SOURCES:%.c=release/%.o) + +.PHONY: clean debug release install + +all: debug release + +install: + +release: $(RELTARGET) +#release: $(RELTARGET) $(TARGETHEADERS) + +debug: $(DBGTARGET) +#debug: $(DBGTARGET) $(TARGETHEADERS) + + +$(RELTARGET): $(RELOBJFILES) + @mkdir -p $(ROOTDIR)/lib + $(AR.c) $@ $(RELOBJFILES) + +$(DBGTARGET): $(DBGOBJFILES) + @mkdir -p $(ROOTDIR)/lib + $(AR.c) $@ $(DBGOBJFILES) + +$(RELOBJFILES): release/%.o: %.c $(HEADERS) + @mkdir -p release + $(COMPILE.c) $(RELCFLAGS) -o $@ $< + +$(DBGOBJFILES): debug/%.o: %.c $(HEADERS) + @mkdir -p debug + $(COMPILE.c) $(DBGCFLAGS) -o $@ $< + +$(TARGETHEADERS): $(HEADERS) + @echo Installing headers... + @install -d $(INCLUDEDIR) + @install -c $< $@ + +clean: + -rm -rf release debug *~ ../lib/* + diff --git a/am335x/app_loader/interface/__prussdrv.h b/am335x/app_loader/interface/__prussdrv.h new file mode 100644 index 00000000..08d69375 --- /dev/null +++ b/am335x/app_loader/interface/__prussdrv.h @@ -0,0 +1,275 @@ +/* + * __prussdrv.h + * + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +/* + * ============================================================================ + * Copyright (c) Texas Instruments Inc 2010-12 + * + * Use of this software is controlled by the terms and conditions found in the + * license agreement under which this software has been supplied or provided. + * ============================================================================ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#define DISABLE_L3RAM_SUPPORT + +#define PAGE_SIZE 4096 + +#define PRUSS_V1 1 +#define PRUSS_V2 2 + +#define AM33XX_PRUSS_INTC_REV 0x4E82A900 +#define AM18XX_PRUSS_INTC_REV 0x4E825900 + +#define PRUSS_MAX_IRAM_SIZE 8192 + +#define AM33XX_PRUSS_IRAM_SIZE 8192 +#define AM33XX_PRUSS_MMAP_SIZE 0x40000 +#define AM33XX_DATARAM0_PHYS_BASE 0x4a300000 +#define AM33XX_DATARAM1_PHYS_BASE 0x4a302000 +#define AM33XX_INTC_PHYS_BASE 0x4a320000 +#define AM33XX_PRU0CONTROL_PHYS_BASE 0x4a322000 +#define AM33XX_PRU0DEBUG_PHYS_BASE 0x4a322400 +#define AM33XX_PRU1CONTROL_PHYS_BASE 0x4a324000 +#define AM33XX_PRU1DEBUG_PHYS_BASE 0x4a324400 +#define AM33XX_PRU0IRAM_PHYS_BASE 0x4a334000 +#define AM33XX_PRU1IRAM_PHYS_BASE 0x4a338000 +#define AM33XX_PRUSS_SHAREDRAM_BASE 0x4a310000 +#define AM33XX_PRUSS_CFG_BASE 0x4a326000 +#define AM33XX_PRUSS_UART_BASE 0x4a328000 +#define AM33XX_PRUSS_IEP_BASE 0x4a32e000 +#define AM33XX_PRUSS_ECAP_BASE 0x4a330000 +#define AM33XX_PRUSS_MIIRT_BASE 0x4a332000 +#define AM33XX_PRUSS_MDIO_BASE 0x4a332400 + +#define AM18XX_PRUSS_IRAM_SIZE 4096 +#define AM18XX_PRUSS_MMAP_SIZE 0x7C00 +#define AM18XX_DATARAM0_PHYS_BASE 0x01C30000 +#define AM18XX_DATARAM1_PHYS_BASE 0x01C32000 +#define AM18XX_INTC_PHYS_BASE 0x01C34000 +#define AM18XX_PRU0CONTROL_PHYS_BASE 0x01C37000 +#define AM18XX_PRU0DEBUG_PHYS_BASE 0x01C37400 +#define AM18XX_PRU1CONTROL_PHYS_BASE 0x01C37800 +#define AM18XX_PRU1DEBUG_PHYS_BASE 0x01C37C00 +#define AM18XX_PRU0IRAM_PHYS_BASE 0x01C38000 +#define AM18XX_PRU1IRAM_PHYS_BASE 0x01C3C000 + +//PRUSS INTC register offsets +#define PRU_INTC_REVID_REG 0x000 +#define PRU_INTC_CR_REG 0x004 +#define PRU_INTC_HCR_REG 0x00C +#define PRU_INTC_GER_REG 0x010 +#define PRU_INTC_GNLR_REG 0x01C +#define PRU_INTC_SISR_REG 0x020 +#define PRU_INTC_SICR_REG 0x024 +#define PRU_INTC_EISR_REG 0x028 +#define PRU_INTC_EICR_REG 0x02C +#define PRU_INTC_HIEISR_REG 0x034 +#define PRU_INTC_HIDISR_REG 0x038 +#define PRU_INTC_GPIR_REG 0x080 + +#define PRU_INTC_SRSR1_REG 0x200 +#define PRU_INTC_SRSR2_REG 0x204 + +#define PRU_INTC_SECR1_REG 0x280 +#define PRU_INTC_SECR2_REG 0x284 + +#define PRU_INTC_ESR1_REG 0x300 +#define PRU_INTC_ESR2_REG 0x304 + +#define PRU_INTC_ECR1_REG 0x380 +#define PRU_INTC_ECR2_REG 0x384 + +#define PRU_INTC_CMR1_REG 0x400 +#define PRU_INTC_CMR2_REG 0x404 +#define PRU_INTC_CMR3_REG 0x408 +#define PRU_INTC_CMR4_REG 0x40C +#define PRU_INTC_CMR5_REG 0x410 +#define PRU_INTC_CMR6_REG 0x414 +#define PRU_INTC_CMR7_REG 0x418 +#define PRU_INTC_CMR8_REG 0x41C +#define PRU_INTC_CMR9_REG 0x420 +#define PRU_INTC_CMR10_REG 0x424 +#define PRU_INTC_CMR11_REG 0x428 +#define PRU_INTC_CMR12_REG 0x42C +#define PRU_INTC_CMR13_REG 0x430 +#define PRU_INTC_CMR14_REG 0x434 +#define PRU_INTC_CMR15_REG 0x438 +#define PRU_INTC_CMR16_REG 0x43C + +#define PRU_INTC_HMR1_REG 0x800 +#define PRU_INTC_HMR2_REG 0x804 +#define PRU_INTC_HMR3_REG 0x808 + +#define PRU_INTC_SIPR1_REG 0xD00 +#define PRU_INTC_SIPR2_REG 0xD04 + +#define PRU_INTC_SITR1_REG 0xD80 +#define PRU_INTC_SITR2_REG 0xD84 + +#define PRU_INTC_HIER_REG 0x1500 + + +#define MAX_HOSTS_SUPPORTED 10 + +//UIO driver expects user space to map PRUSS_UIO_MAP_OFFSET_XXX to +//access corresponding memory regions - region offset is N*PAGE_SIZE + +#define PRUSS_UIO_MAP_OFFSET_PRUSS 0*PAGE_SIZE +#define PRUSS_UIO_DRV_PRUSS_BASE "/sys/class/uio/uio0/maps/map0/addr" +#define PRUSS_UIO_DRV_PRUSS_SIZE "/sys/class/uio/uio0/maps/map0/size" + +#ifndef DISABLE_L3RAM_SUPPORT + +#define PRUSS_UIO_MAP_OFFSET_L3RAM 1*PAGE_SIZE +#define PRUSS_UIO_DRV_L3RAM_BASE "/sys/class/uio/uio0/maps/map1/addr" +#define PRUSS_UIO_DRV_L3RAM_SIZE "/sys/class/uio/uio0/maps/map1/size" + +#define PRUSS_UIO_MAP_OFFSET_EXTRAM 2*PAGE_SIZE +#define PRUSS_UIO_DRV_EXTRAM_BASE "/sys/class/uio/uio0/maps/map2/addr" +#define PRUSS_UIO_DRV_EXTRAM_SIZE "/sys/class/uio/uio0/maps/map2/size" + +#else + +#define PRUSS_UIO_MAP_OFFSET_EXTRAM 1*PAGE_SIZE +#define PRUSS_UIO_DRV_EXTRAM_BASE "/sys/class/uio/uio0/maps/map1/addr" +#define PRUSS_UIO_DRV_EXTRAM_SIZE "/sys/class/uio/uio0/maps/map1/size" + + +#endif + + +typedef struct __prussdrv { + int version; + int fd[NUM_PRU_HOSTIRQS]; + void *pru0_dataram_base; + void *pru1_dataram_base; + void *intc_base; + void *pru0_control_base; + void *pru0_debug_base; + void *pru1_control_base; + void *pru1_debug_base; + void *pru0_iram_base; + void *pru1_iram_base; + void *l3ram_base; + void *extram_base; + pthread_t irq_thread[NUM_PRU_HOSTIRQS]; + int mmap_fd; + void *pruss_sharedram_base; + void *pruss_cfg_base; + void *pruss_uart_base; + void *pruss_iep_base; + void *pruss_ecap_base; + void *pruss_miirt_base; + void *pruss_mdio_base; + unsigned int pru0_dataram_phy_base; + unsigned int pru1_dataram_phy_base; + unsigned int intc_phy_base; + unsigned int pru0_control_phy_base; + unsigned int pru0_debug_phy_base; + unsigned int pru1_control_phy_base; + unsigned int pru1_debug_phy_base; + unsigned int pru0_iram_phy_base; + unsigned int pru1_iram_phy_base; + unsigned int l3ram_phy_base; + unsigned int extram_phy_base; + unsigned int pruss_sharedram_phy_base; + unsigned int pruss_cfg_phy_base; + unsigned int pruss_uart_phy_base; + unsigned int pruss_iep_phy_base; + unsigned int pruss_ecap_phy_base; + unsigned int pruss_miirt_phy_base; + unsigned int pruss_mdio_phy_base; + unsigned int pruss_phys_base; + unsigned int pruss_map_size; + unsigned int l3ram_phys_base; + unsigned int l3ram_map_size; + unsigned int extram_phys_base; + unsigned int extram_map_size; +} tprussdrv; + + +int __pruss_detect_hw_version(unsigned int *pruss_io) +{ + + if (pruss_io[(AM18XX_INTC_PHYS_BASE - AM18XX_DATARAM0_PHYS_BASE) >> 2] + == AM18XX_PRUSS_INTC_REV) + return PRUSS_V1; + else { + if (pruss_io + [(AM33XX_INTC_PHYS_BASE - AM33XX_DATARAM0_PHYS_BASE) >> 2] == + AM33XX_PRUSS_INTC_REV) + return PRUSS_V2; + else + return -1; + } +} + +void __prussintc_set_cmr(unsigned int *pruintc_io, unsigned short sysevt, + unsigned short channel) +{ + pruintc_io[(PRU_INTC_CMR1_REG + (sysevt & ~(0x3))) >> 2] |= + ((channel & 0xF) << ((sysevt & 0x3) << 3)); + +} + + +void __prussintc_set_hmr(unsigned int *pruintc_io, unsigned short channel, + unsigned short host) +{ + pruintc_io[(PRU_INTC_HMR1_REG + (channel & ~(0x3))) >> 2] = + pruintc_io[(PRU_INTC_HMR1_REG + + (channel & ~(0x3))) >> 2] | (((host) & 0xF) << + (((channel) & 0x3) << 3)); + +} diff --git a/am335x/app_loader/interface/prussdrv.c b/am335x/app_loader/interface/prussdrv.c new file mode 100644 index 00000000..21e4ba4c --- /dev/null +++ b/am335x/app_loader/interface/prussdrv.c @@ -0,0 +1,660 @@ +/* + * prussdrv.c + * + * User space driver for PRUSS + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + + +/* + * ============================================================================ + * Copyright (c) Texas Instruments Inc 2010-12 + * + * Use of this software is controlled by the terms and conditions found in the + * license agreement under which this software has been supplied or provided. + * ============================================================================ + */ + + +#include +#include "__prussdrv.h" +#include + +#define PRUSS_UIO_PRAM_PATH_LEN 128 +#define PRUSS_UIO_PARAM_VAL_LEN 20 +#define HEXA_DECIMAL_BASE 16 + +static tprussdrv prussdrv; + +int __prussdrv_memmap_init(void) +{ + int i, fd; + char hexstring[PRUSS_UIO_PARAM_VAL_LEN]; + + if (prussdrv.mmap_fd == 0) { + for (i = 0; i < NUM_PRU_HOSTIRQS; i++) { + if (prussdrv.fd[i]) + break; + } + if (i == NUM_PRU_HOSTIRQS) + return -1; + else + prussdrv.mmap_fd = prussdrv.fd[i]; + } + fd = open(PRUSS_UIO_DRV_PRUSS_BASE, O_RDONLY); + if (fd >= 0) { + read(fd, hexstring, PRUSS_UIO_PARAM_VAL_LEN); + prussdrv.pruss_phys_base = + strtoul(hexstring, NULL, HEXA_DECIMAL_BASE); + close(fd); + } else + return -1; + fd = open(PRUSS_UIO_DRV_PRUSS_SIZE, O_RDONLY); + if (fd >= 0) { + read(fd, hexstring, PRUSS_UIO_PARAM_VAL_LEN); + prussdrv.pruss_map_size = + strtoul(hexstring, NULL, HEXA_DECIMAL_BASE); + close(fd); + } else + return -1; + + prussdrv.pru0_dataram_base = + mmap(0, prussdrv.pruss_map_size, PROT_READ | PROT_WRITE, + MAP_SHARED, prussdrv.mmap_fd, PRUSS_UIO_MAP_OFFSET_PRUSS); + prussdrv.version = + __pruss_detect_hw_version(prussdrv.pru0_dataram_base); + + switch (prussdrv.version) { + case PRUSS_V1: + { + printf("AM18XX\n"); + prussdrv.pru0_dataram_phy_base = AM18XX_DATARAM0_PHYS_BASE; + prussdrv.pru1_dataram_phy_base = AM18XX_DATARAM1_PHYS_BASE; + prussdrv.intc_phy_base = AM18XX_INTC_PHYS_BASE; + prussdrv.pru0_control_phy_base = AM18XX_PRU0CONTROL_PHYS_BASE; + prussdrv.pru0_debug_phy_base = AM18XX_PRU0DEBUG_PHYS_BASE; + prussdrv.pru1_control_phy_base = AM18XX_PRU1CONTROL_PHYS_BASE; + prussdrv.pru1_debug_phy_base = AM18XX_PRU1DEBUG_PHYS_BASE; + prussdrv.pru0_iram_phy_base = AM18XX_PRU0IRAM_PHYS_BASE; + prussdrv.pru1_iram_phy_base = AM18XX_PRU1IRAM_PHYS_BASE; + } + break; + case PRUSS_V2: + { + printf("AM33XX\n"); + prussdrv.pru0_dataram_phy_base = AM33XX_DATARAM0_PHYS_BASE; + prussdrv.pru1_dataram_phy_base = AM33XX_DATARAM1_PHYS_BASE; + prussdrv.intc_phy_base = AM33XX_INTC_PHYS_BASE; + prussdrv.pru0_control_phy_base = AM33XX_PRU0CONTROL_PHYS_BASE; + prussdrv.pru0_debug_phy_base = AM33XX_PRU0DEBUG_PHYS_BASE; + prussdrv.pru1_control_phy_base = AM33XX_PRU1CONTROL_PHYS_BASE; + prussdrv.pru1_debug_phy_base = AM33XX_PRU1DEBUG_PHYS_BASE; + prussdrv.pru0_iram_phy_base = AM33XX_PRU0IRAM_PHYS_BASE; + prussdrv.pru1_iram_phy_base = AM33XX_PRU1IRAM_PHYS_BASE; + prussdrv.pruss_sharedram_phy_base = + AM33XX_PRUSS_SHAREDRAM_BASE; + prussdrv.pruss_cfg_phy_base = AM33XX_PRUSS_CFG_BASE; + prussdrv.pruss_uart_phy_base = AM33XX_PRUSS_UART_BASE; + prussdrv.pruss_iep_phy_base = AM33XX_PRUSS_IEP_BASE; + prussdrv.pruss_ecap_phy_base = AM33XX_PRUSS_ECAP_BASE; + prussdrv.pruss_miirt_phy_base = AM33XX_PRUSS_MIIRT_BASE; + prussdrv.pruss_mdio_phy_base = AM33XX_PRUSS_MDIO_BASE; + } + break; + default: + printf("UNKNOWN\n"); + } + + prussdrv.pru1_dataram_base = + prussdrv.pru0_dataram_base + prussdrv.pru1_dataram_phy_base - + prussdrv.pru0_dataram_phy_base; + prussdrv.intc_base = + prussdrv.pru0_dataram_base + prussdrv.intc_phy_base - + prussdrv.pru0_dataram_phy_base; + prussdrv.pru0_control_base = + prussdrv.pru0_dataram_base + prussdrv.pru0_control_phy_base - + prussdrv.pru0_dataram_phy_base; + prussdrv.pru0_debug_base = + prussdrv.pru0_dataram_base + prussdrv.pru0_debug_phy_base - + prussdrv.pru0_dataram_phy_base; + prussdrv.pru1_control_base = + prussdrv.pru0_dataram_base + prussdrv.pru1_control_phy_base - + prussdrv.pru0_dataram_phy_base; + prussdrv.pru1_debug_base = + prussdrv.pru0_dataram_base + prussdrv.pru1_debug_phy_base - + prussdrv.pru0_dataram_phy_base; + prussdrv.pru0_iram_base = + prussdrv.pru0_dataram_base + prussdrv.pru0_iram_phy_base - + prussdrv.pru0_dataram_phy_base; + prussdrv.pru1_iram_base = + prussdrv.pru0_dataram_base + prussdrv.pru1_iram_phy_base - + prussdrv.pru0_dataram_phy_base; + if (prussdrv.version == PRUSS_V2) { + prussdrv.pruss_sharedram_base = + prussdrv.pru0_dataram_base + + prussdrv.pruss_sharedram_phy_base - + prussdrv.pru0_dataram_phy_base; + prussdrv.pruss_cfg_base = + prussdrv.pru0_dataram_base + prussdrv.pruss_cfg_phy_base - + prussdrv.pru0_dataram_phy_base; + prussdrv.pruss_uart_base = + prussdrv.pru0_dataram_base + prussdrv.pruss_uart_phy_base - + prussdrv.pru0_dataram_phy_base; + prussdrv.pruss_iep_base = + prussdrv.pru0_dataram_base + prussdrv.pruss_iep_phy_base - + prussdrv.pru0_dataram_phy_base; + prussdrv.pruss_ecap_base = + prussdrv.pru0_dataram_base + prussdrv.pruss_ecap_phy_base - + prussdrv.pru0_dataram_phy_base; + prussdrv.pruss_miirt_base = + prussdrv.pru0_dataram_base + prussdrv.pruss_miirt_phy_base - + prussdrv.pru0_dataram_phy_base; + prussdrv.pruss_mdio_base = + prussdrv.pru0_dataram_base + prussdrv.pruss_mdio_phy_base - + prussdrv.pru0_dataram_phy_base; + } +#ifndef DISABLE_L3RAM_SUPPORT + fd = open(PRUSS_UIO_DRV_L3RAM_BASE, O_RDONLY); + if (fd >= 0) { + read(fd, hexstring, PRUSS_UIO_PARAM_VAL_LEN); + prussdrv.l3ram_phys_base = + strtoul(hexstring, NULL, HEXA_DECIMAL_BASE); + close(fd); + } else + return -1; + + + fd = open(PRUSS_UIO_DRV_L3RAM_SIZE, O_RDONLY); + if (fd >= 0) { + read(fd, hexstring, PRUSS_UIO_PARAM_VAL_LEN); + prussdrv.l3ram_map_size = + strtoul(hexstring, NULL, HEXA_DECIMAL_BASE); + close(fd); + } else + return -1; + + prussdrv.l3ram_base = + mmap(0, prussdrv.l3ram_map_size, PROT_READ | PROT_WRITE, + MAP_SHARED, prussdrv.mmap_fd, PRUSS_UIO_MAP_OFFSET_L3RAM); +#endif + + fd = open(PRUSS_UIO_DRV_EXTRAM_BASE, O_RDONLY); + if (fd >= 0) { + read(fd, hexstring, PRUSS_UIO_PARAM_VAL_LEN); + prussdrv.extram_phys_base = + strtoul(hexstring, NULL, HEXA_DECIMAL_BASE); + close(fd); + } else + return -1; + + fd = open(PRUSS_UIO_DRV_EXTRAM_SIZE, O_RDONLY); + if (fd >= 0) { + read(fd, hexstring, PRUSS_UIO_PARAM_VAL_LEN); + prussdrv.extram_map_size = + strtoul(hexstring, NULL, HEXA_DECIMAL_BASE); + close(fd); + } else + return -1; + + + prussdrv.extram_base = + mmap(0, prussdrv.extram_map_size, PROT_READ | PROT_WRITE, + MAP_SHARED, prussdrv.mmap_fd, PRUSS_UIO_MAP_OFFSET_EXTRAM); + + return 0; + +} + +int prussdrv_init(void) +{ + memset(&prussdrv, 0, sizeof(prussdrv)); + return 0; + +} + +int prussdrv_open(unsigned int pru_evtout_num) +{ + char name[PRUSS_UIO_PRAM_PATH_LEN]; + if (!prussdrv.fd[pru_evtout_num]) { + sprintf(name, "/dev/uio%d", pru_evtout_num); + prussdrv.fd[pru_evtout_num] = open(name, O_RDWR | O_SYNC); + return __prussdrv_memmap_init(); + } else { + return -1; + + } +} + + + + +int prussdrv_pru_reset(unsigned int prunum) +{ + unsigned int *prucontrolregs; + if (prunum == 0) + prucontrolregs = (unsigned int *) prussdrv.pru0_control_base; + else if (prunum == 1) + prucontrolregs = (unsigned int *) prussdrv.pru1_control_base; + else + return -1; + *prucontrolregs = 0; + return 0; +} + +int prussdrv_pru_enable(unsigned int prunum) +{ + unsigned int *prucontrolregs; + if (prunum == 0) + prucontrolregs = (unsigned int *) prussdrv.pru0_control_base; + else if (prunum == 1) + prucontrolregs = (unsigned int *) prussdrv.pru1_control_base; + else + return -1; + + *prucontrolregs = 2; + return 0; + +} + +int prussdrv_pru_disable(unsigned int prunum) +{ + unsigned int *prucontrolregs; + if (prunum == 0) + prucontrolregs = (unsigned int *) prussdrv.pru0_control_base; + else if (prunum == 1) + prucontrolregs = (unsigned int *) prussdrv.pru1_control_base; + else + return -1; + *prucontrolregs = 1; + return 0; + +} + +int prussdrv_pru_write_memory(unsigned int pru_ram_id, + unsigned int wordoffset, + unsigned int *memarea, + unsigned int bytelength) +{ + unsigned int *pruramarea, i, wordlength; + switch (pru_ram_id) { + case PRUSS0_PRU0_IRAM: + pruramarea = (unsigned int *) prussdrv.pru0_iram_base; + break; + case PRUSS0_PRU1_IRAM: + pruramarea = (unsigned int *) prussdrv.pru1_iram_base; + break; + case PRUSS0_PRU0_DATARAM: + pruramarea = (unsigned int *) prussdrv.pru0_dataram_base; + break; + case PRUSS0_PRU1_DATARAM: + pruramarea = (unsigned int *) prussdrv.pru1_dataram_base; + break; + case PRUSS0_SHARED_DATARAM: + if (prussdrv.version != PRUSS_V2) + return -1; + pruramarea = (unsigned int *) prussdrv.pruss_sharedram_base; + break; + default: + return -1; + } + + + wordlength = (bytelength + 3) >> 2; //Adjust length as multiple of 4 bytes + for (i = 0; i < wordlength; i++) { + *(pruramarea + i + wordoffset) = *(memarea + i); + } + return wordlength; + +} + + +int prussdrv_pruintc_init(tpruss_intc_initdata * prussintc_init_data) +{ + unsigned int *pruintc_io = (unsigned int *) prussdrv.intc_base; + unsigned int i, mask1, mask2; + + pruintc_io[PRU_INTC_SIPR1_REG >> 2] = 0xFFFFFFFF; + pruintc_io[PRU_INTC_SIPR2_REG >> 2] = 0xFFFFFFFF; + + for (i = 0; i < (NUM_PRU_SYS_EVTS + 3) >> 2; i++) + pruintc_io[(PRU_INTC_CMR1_REG >> 2) + i] = 0; + for (i = 0; + ((prussintc_init_data->sysevt_to_channel_map[i].sysevt != -1) + && (prussintc_init_data->sysevt_to_channel_map[i].channel != + -1)); i++) { + __prussintc_set_cmr(pruintc_io, + prussintc_init_data->sysevt_to_channel_map[i]. + sysevt, + prussintc_init_data->sysevt_to_channel_map[i]. + channel); + } + for (i = 0; i < (NUM_PRU_HOSTS + 3) >> 2; i++) + pruintc_io[(PRU_INTC_HMR1_REG >> 2) + i] = 0; + for (i = 0; + ((prussintc_init_data->channel_to_host_map[i].channel != -1) + && (prussintc_init_data->channel_to_host_map[i].host != -1)); + i++) { + + __prussintc_set_hmr(pruintc_io, + prussintc_init_data->channel_to_host_map[i]. + channel, + prussintc_init_data->channel_to_host_map[i]. + host); + } + + pruintc_io[PRU_INTC_SITR1_REG >> 2] = 0x0; + pruintc_io[PRU_INTC_SITR2_REG >> 2] = 0x0; + + + mask1 = mask2 = 0; + for (i = 0; prussintc_init_data->sysevts_enabled[i] != 255; i++) { + if (prussintc_init_data->sysevts_enabled[i] < 32) { + mask1 = + mask1 + (1 << (prussintc_init_data->sysevts_enabled[i])); + } else if (prussintc_init_data->sysevts_enabled[i] < 64) { + mask2 = + mask2 + + (1 << (prussintc_init_data->sysevts_enabled[i] - 32)); + } else { + printf("Error: SYS_EVT%d out of range\n", + prussintc_init_data->sysevts_enabled[i]); + return -1; + } + } + pruintc_io[PRU_INTC_ESR1_REG >> 2] = mask1; + pruintc_io[PRU_INTC_SECR1_REG >> 2] = mask1; + pruintc_io[PRU_INTC_ESR2_REG >> 2] = mask2; + pruintc_io[PRU_INTC_SECR2_REG >> 2] = mask2; + + for (i = 0; i < MAX_HOSTS_SUPPORTED; i++) + if (prussintc_init_data->host_enable_bitmask & (1 << i)) { + pruintc_io[PRU_INTC_HIEISR_REG >> 2] = i; + } + + pruintc_io[PRU_INTC_GER_REG >> 2] = 0x1; + + return 0; +} + + +int prussdrv_pru_send_event(unsigned int eventnum) +{ + unsigned int *pruintc_io = (unsigned int *) prussdrv.intc_base; + if (eventnum < 32) + pruintc_io[PRU_INTC_SRSR1_REG >> 2] = 1 << eventnum; + else + pruintc_io[PRU_INTC_SRSR2_REG >> 2] = 1 << (eventnum - 32); + return 0; +} + +int prussdrv_pru_wait_event(unsigned int pru_evtout_num) +{ + int event_count; + unsigned int *pruintc_io = (unsigned int *) prussdrv.intc_base; + read(prussdrv.fd[pru_evtout_num], &event_count, sizeof(int)); + pruintc_io[PRU_INTC_HIEISR_REG >> 2] = pru_evtout_num+2; + return 0; + +} + +int prussdrv_pru_clear_event(unsigned int eventnum) +{ + unsigned int *pruintc_io = (unsigned int *) prussdrv.intc_base; + if (eventnum < 32) + pruintc_io[PRU_INTC_SECR1_REG >> 2] = 1 << eventnum; + else + pruintc_io[PRU_INTC_SECR2_REG >> 2] = 1 << (eventnum - 32); + return 0; +} + +int prussdrv_pru_send_wait_clear_event(unsigned int send_eventnum, + unsigned int pru_evtout_num, + unsigned int ack_eventnum) +{ + prussdrv_pru_send_event(send_eventnum); + prussdrv_pru_wait_event(pru_evtout_num); + prussdrv_pru_clear_event(ack_eventnum); + return 0; + +} + + +int prussdrv_map_l3mem(void **address) +{ + *address = prussdrv.l3ram_base; + return 0; +} + + + +int prussdrv_map_extmem(void **address) +{ + + *address = prussdrv.extram_base; + return 0; + +} + + +int prussdrv_map_prumem(unsigned int pru_ram_id, void **address) +{ + switch (pru_ram_id) { + case PRUSS0_PRU0_DATARAM: + *address = prussdrv.pru0_dataram_base; + break; + case PRUSS0_PRU1_DATARAM: + *address = prussdrv.pru1_dataram_base; + break; + case PRUSS0_SHARED_DATARAM: + if (prussdrv.version != PRUSS_V2) + return -1; + *address = prussdrv.pruss_sharedram_base; + break; + default: + *address = 0; + return -1; + } + return 0; +} + +int prussdrv_map_peripheral_io(unsigned int per_id, void **address) +{ + if (prussdrv.version != PRUSS_V2) + return -1; + + switch (per_id) { + case PRUSS0_CFG: + *address = prussdrv.pruss_cfg_base; + break; + case PRUSS0_UART: + *address = prussdrv.pruss_uart_base; + break; + case PRUSS0_IEP: + *address = prussdrv.pruss_iep_base; + break; + case PRUSS0_ECAP: + *address = prussdrv.pruss_ecap_base; + break; + case PRUSS0_MII_RT: + *address = prussdrv.pruss_miirt_base; + break; + case PRUSS0_MDIO: + *address = prussdrv.pruss_mdio_base; + break; + default: + *address = 0; + return -1; + } + return 0; +} + +unsigned int prussdrv_get_phys_addr(void *address) +{ + unsigned int retaddr = 0; + if ((address >= prussdrv.pru0_dataram_base) + && (address < + prussdrv.pru0_dataram_base + prussdrv.pruss_map_size)) { + retaddr = + ((unsigned int) (address - prussdrv.pru0_dataram_base) + + prussdrv.pru0_dataram_phy_base); + } else if ((address >= prussdrv.l3ram_base) + && (address < + prussdrv.l3ram_base + prussdrv.l3ram_map_size)) { + retaddr = + ((unsigned int) (address - prussdrv.l3ram_base) + + prussdrv.l3ram_phys_base); + } else if ((address >= prussdrv.extram_base) + && (address < + prussdrv.extram_base + prussdrv.extram_map_size)) { + retaddr = + ((unsigned int) (address - prussdrv.extram_base) + + prussdrv.extram_phys_base); + } + return retaddr; + +} + +void *prussdrv_get_virt_addr(unsigned int phyaddr) +{ + void *address = 0; + if ((phyaddr >= prussdrv.pru0_dataram_phy_base) + && (phyaddr < + prussdrv.pru0_dataram_phy_base + prussdrv.pruss_map_size)) { + address = + (void *) ((unsigned int) prussdrv.pru0_dataram_base + + (phyaddr - prussdrv.pru0_dataram_phy_base)); + } else if ((phyaddr >= prussdrv.l3ram_phys_base) + && (phyaddr < + prussdrv.l3ram_phys_base + prussdrv.l3ram_map_size)) { + address = + (void *) ((unsigned int) prussdrv.l3ram_base + + (phyaddr - prussdrv.l3ram_phys_base)); + } else if ((phyaddr >= prussdrv.extram_phys_base) + && (phyaddr < + prussdrv.extram_phys_base + prussdrv.extram_map_size)) { + address = + (void *) ((unsigned int) prussdrv.extram_base + + (phyaddr - prussdrv.extram_phys_base)); + } + return address; + +} + + +int prussdrv_exit() +{ + int i; + munmap(prussdrv.pru0_dataram_base, prussdrv.pruss_map_size); + munmap(prussdrv.l3ram_base, prussdrv.l3ram_map_size); + munmap(prussdrv.extram_base, prussdrv.extram_map_size); + for (i = 0; i < NUM_PRU_HOSTIRQS; i++) { + if (prussdrv.fd[i]) + close(prussdrv.fd[i]); + if (prussdrv.irq_thread[i]) + pthread_join(prussdrv.irq_thread[i], NULL); + } + return 0; +} + +int prussdrv_exec_program(int prunum, char *filename) +{ + FILE *fPtr; + unsigned char fileDataArray[PRUSS_MAX_IRAM_SIZE]; + int fileSize = 0; + unsigned int pru_ram_id; + + if (prunum == 0) + pru_ram_id = PRUSS0_PRU0_IRAM; + else if (prunum == 1) + pru_ram_id = PRUSS0_PRU1_IRAM; + else + return -1; + + // Open an File from the hard drive + fPtr = fopen(filename, "rb"); + if (fPtr == NULL) { + printf("File %s open failed\n", filename); + } else { + printf("File %s open passed\n", filename); + } + // Read file size + fseek(fPtr, 0, SEEK_END); + fileSize = ftell(fPtr); + + if (fileSize == 0) { + printf("File read failed.. Closing program\n"); + fclose(fPtr); + return -1; + } + + fseek(fPtr, 0, SEEK_SET); + + if (fileSize != + fread((unsigned char *) fileDataArray, 1, fileSize, fPtr)) { + printf("WARNING: File Size mismatch\n"); + } + + fclose(fPtr); + + // Make sure PRU sub system is first disabled/reset + prussdrv_pru_disable(prunum); + prussdrv_pru_write_memory(pru_ram_id, 0, + (unsigned int *) fileDataArray, fileSize); + prussdrv_pru_enable(prunum); + + return 0; +} + +int prussdrv_start_irqthread(unsigned int pru_evtout_num, int priority, + prussdrv_function_handler irqhandler) +{ + pthread_attr_t pthread_attr; + struct sched_param sched_param; + pthread_attr_init(&pthread_attr); + if (priority != 0) { + pthread_attr_setinheritsched(&pthread_attr, + PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedpolicy(&pthread_attr, SCHED_FIFO); + sched_param.sched_priority = priority; + pthread_attr_setschedparam(&pthread_attr, &sched_param); + } + + pthread_create(&prussdrv.irq_thread[pru_evtout_num], &pthread_attr, + irqhandler, NULL); + + pthread_attr_destroy(&pthread_attr); + + return 0; + +} diff --git a/am335x/pasm/LICENCE.txt b/am335x/pasm/LICENCE.txt new file mode 100644 index 00000000..4295a9e2 --- /dev/null +++ b/am335x/pasm/LICENCE.txt @@ -0,0 +1,39 @@ +/* +* {module name} +* +* {module description} +* +* Copyright (C) {YEAR} Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the +* distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ + + diff --git a/am335x/pasm/dosbuild.bat b/am335x/pasm/dosbuild.bat new file mode 100644 index 00000000..3db51046 --- /dev/null +++ b/am335x/pasm/dosbuild.bat @@ -0,0 +1,3 @@ +cl -W3 -D_CRT_SECURE_NO_WARNINGS pasm.c pasmpp.c pasmexp.c pasmop.c pasmdot.c pasmstruct.c pasmmacro.c /Fe..\pasm.exe +del *.obj + diff --git a/am335x/pasm/linuxbuild b/am335x/pasm/linuxbuild new file mode 100755 index 00000000..550101e9 --- /dev/null +++ b/am335x/pasm/linuxbuild @@ -0,0 +1,4 @@ +#!/bin/sh +gcc -Wall -D_UNIX_ pasm.c pasmpp.c pasmexp.c pasmop.c pasmdot.c pasmstruct.c pasmmacro.c -o ../pasm + + diff --git a/am335x/pasm/macbuild b/am335x/pasm/macbuild new file mode 100644 index 00000000..37f9a3e8 --- /dev/null +++ b/am335x/pasm/macbuild @@ -0,0 +1,4 @@ +#!/bin/sh +gcc -Wall -D_UNIX_ pasm.c pasmpp.c pasmexp.c pasmop.c pasmdot.c pasmstruct.c pasmmacro.c -o ../pasm.mac + + diff --git a/am335x/pasm/pasm.c b/am335x/pasm/pasm.c new file mode 100644 index 00000000..380899be --- /dev/null +++ b/am335x/pasm/pasm.c @@ -0,0 +1,1358 @@ +/* + * pasm.c + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +/*=========================================================================== + * Copyright (c) Texas Instruments Inc 2010-12 + * + * Use of this software is controlled by the terms and conditions found in the + * license agreement under which this software has been supplied or provided. + * ============================================================================ + */ + +/*=========================================================================== +// PASM - PRU Assembler +//--------------------------------------------------------------------------- +// +// File : pasm.c +// +// Description: +// Main assembler control program. +// - Processes command line and flags +// - Runs the main assembler engine (dual pass) +// - Handles error reporting +// - Handles label creation and matching +// - Handle output file generation +// +//--------------------------------------------------------------------------- +// Revision: +// 21-Jun-13: 0.84 - Open source version +============================================================================*/ + +#include +#include +#include +#if !defined(__APPLE__) +#include +#else +#include +#endif +#include +#include "pasm.h" +#include "pasmdbg.h" + +/* +// Multiple Core Revision Support +// ------------------------------ +// +// -V0 PRU Legacy (same as -x) +// -V1 PRU Generation 1 (default) +// Adds [LMBD,SCAN,HALT,ZERO(1),MVI(1),SLP(1)] Removes [LFC,STC] +// -V2 PRU Generation 2 (same as -X) +// Adds [ZERO(2),FILL,XIN,XOUT,XCHG,MVI(2)] Removes [SCAN] +// -V3 PRU Generation 3 +// Adds [SLP(2),LOOP,ILOOP,SXIN,SXOUT,SXCHG,NOPx] +// +// ZERO(1) : Zero is multi-cycle pseudo op encoded via moves +// ZERO(2) : Zero is single-cycle pseudo op encoded via XFR +// +// MVI(1) : Pseudo op forms of MVI only +// MVI(2) : Pseudo op forms of MVI only +// +// SLP(1) : SLP with trailing NOP +// SLP(2) : SLP without trailing NOP +*/ + + +/* ---------- Local Macro Definitions ----------- */ + +#define PROCESSOR_NAME_STRING ("PRU") +#define VERSION_STRING ("0.84") + +#define MAXFILE (256) /* Max file length for output files */ +#define MAX_PROGRAM (16384) /* Max instruction count */ +#define MAX_CMD_EQUATE (8) /* Max equates that can be put on command line */ + +#define RET_ERROR (1) +#define RET_SUCCESS (0) + +/* Big/Little Endian Conversions */ +#define HNC16(a) ((((a)>>8)&0xff)+(((a)<<8)&0xff00)) +#define HNC32(a) ((((a)>>24)&0xff)+(((a)>>8)&0xff00)+(((a)<<8)&0xff0000)+(((a)<<24)&0xff000000)) + +/* User Options */ +unsigned int Options = 0; +unsigned int Core = CORE_NONE; +FILE *ListingFile = 0; + +/* Assembler Engine */ +int Pass; /* Pass 1 or 2 of parser */ +int HaveEntry; /* Entrypont flag (init to 0) */ +int EntryPoint; /* Entrypont (init to -1) */ +int CodeOffset; /* Current instruction "word" offset (zero based) */ +int Errors; /* Total number or errors */ +int FatalError; /* Set on fatal error */ +int Warnings; /* Total number of warnings */ +uint RetRegValue; /* Return register index */ +uint RetRegField; /* Return register field */ + +LABEL *pLabelList=0; /* List of installed labels */ +int LabelCount=0; + +CODEGEN ProgramImage[MAX_PROGRAM]; + +SOURCEFILE cmdLine = { 0, 0, 0, 0, 0, 0, 0, 0, "[CommandLine]", "" }; +char cmdLineName[MAX_CMD_EQUATE][EQUATE_NAME_LEN]; +char cmdLineData[MAX_CMD_EQUATE][EQUATE_DATA_LEN]; +int cmdLineEquates = 0; + +char nameCArray[EQUATE_DATA_LEN]; +int nameCArraySet = 0; + +/* Local Support Funtions */ +static int ValidateOffset( SOURCEFILE *ps ); +static int PrintLine( FILE *pfOut, SOURCEFILE *ps ); +static int GetInfoFromAddr( uint address, uint *pIndex, uint *pLineNo, uint *pCodeWord ); +static int ListFile( FILE *pfOut, SOURCEFILE *ps ); + +/* +// Main Assembler Entry Point +// +*/ +int main(int argc, char *argv[]) +{ + int i,j; + int CodeOffsetPass1 = 0; + char *infile, *outfile, *flags; + SOURCEFILE *mainsource; + char outbase[MAXFILE],outfilename[MAXFILE]; + + printf("\n\n%s Assembler Version %s\n",PROCESSOR_NAME_STRING, VERSION_STRING); + printf("Copyright (C) 2005-2013 by Texas Instruments Inc.\n\n"); + + /* Scan argv[0] to the final '/' in program name */ + i=0; + j=-1; + while( argv[0][i] ) + { + if( argv[0][i] == '/' || argv[0][i] == '\\') + j=i; + i++; + } + argv[0]+=(j+1); + + /* + // Process command line + */ + infile=0; + flags=0; + outfile=0; + + if( argc<2 ) + { +USAGE: + printf("Usage: %s [-V#EBbcmLldz] [-Dname=value] [-Cname] InFile [OutFileBase]\n\n",argv[0]); + printf(" V# - Specify core version (V0,V1,V2,V3). (Default is V1)\n"); + printf(" E - Assemble for big endian core\n"); + printf(" B - Create big endian binary output (*.bib)\n"); + printf(" b - Create little endian binary output (*.bin)\n"); + printf(" c - Create 'C array' binary output (*_bin.h)\n"); + printf(" m - Create 'image' binary output (*.img)\n"); + printf(" L - Create annotated source file style listing (*.txt)\n"); + printf(" l - Create raw listing file (*.lst)\n"); + printf(" d - Create pView debug file (*.dbg)\n"); + printf(" z - Enable debug messages\n"); + printf("\n D - Set equate 'name' to 1 using '-Dname', or to any\n"); + printf(" value using '-Dname=value'\n"); + printf(" C - Name the C array in 'C array' binary output\n"); + printf(" to 'name' using '-Cname'\n"); + printf("\n"); + return(RET_ERROR); + } + + /* Get all non-flag arguments */ + for( i=1; i'3' ) + { + printf("\nExpected a number (0-3) after option 'V'\n\n"); + goto USAGE; + } + if( Core != CORE_NONE ) + { + printf("\nDo not specify more than one core version or use -V with -X or -x\n\n"); + goto USAGE; + } + Core = CORE_V0 + *flags - '0'; + } + else if( *flags == 'x' ) + { + if( Core != CORE_NONE ) + { + printf("\nDo not use -x with -X or -V\n\n"); + goto USAGE; + } + Core = CORE_V0; + } + else if( *flags == 'X' ) + { + if( Core != CORE_NONE ) + { + printf("\nDo not use -X with -x or -V\n\n"); + goto USAGE; + } + Core = CORE_V2; + } + else if( *flags == 'E' ) + Options |= OPTION_BIGENDIAN; + else if( *flags == 'b' ) + Options |= OPTION_BINARY; + else if( *flags == 'B' ) + Options |= OPTION_BINARYBIG; + else if( *flags == 'c' ) + Options |= OPTION_CARRAY; + else if( *flags == 'm' ) + Options |= OPTION_IMGFILE; + else if( *flags == 'l' ) + Options |= OPTION_LISTING; + else if( *flags == 'L' ) + Options |= OPTION_SOURCELISTING; + else if( *flags == 'd' ) + Options |= OPTION_DBGFILE; + else if( *flags == 'z' ) + Options |= OPTION_DEBUG; + else + { + printf("\nUnknown flag '%c'\n\n",*flags); + goto USAGE; + } + flags++; + } + } + } + + if( Core==CORE_NONE ) + Core = CORE_V1; + + /* Check input file */ + if( !infile ) + goto USAGE; + + /* Check output file base - make sure no '.' */ + if( outfile ) + { + if( strlen(outfile) > (MAXFILE-5) ) + { Report(0,REP_ERROR,"Outfile name too long"); return(RET_ERROR); } + i=0; + while( outfile[i] ) + { + if( outfile[i]=='.' ) + { + if( outfile[i+1]=='.' ) + i++; + else + { Report(0,REP_ERROR,"Outfile should be basename only - no '.'"); return(RET_ERROR); } + } + i++; + } + strcpy( outbase, outfile ); + } + + /* Test opening the main source file */ + if( !(mainsource=InitSourceFile(0,infile)) ) + return(RET_ERROR); + + /* Setup outfile base */ + if( !outfile ) + { + for(i=0; mainsource->SourceName[i] && mainsource->SourceName[i]!='.'; i++ ) + outbase[i]=mainsource->SourceName[i]; + outbase[i] = 0; + } + if( Options & OPTION_DEBUG ) + printf("Output base filename: '%s'\n",outbase); + + /* Close the source file for now */ + CloseSourceFile( mainsource ); + + /* If no output specified, default to 'C' array */ + if( !(Options & (OPTION_BINARY|OPTION_CARRAY|OPTION_BINARYBIG|OPTION_IMGFILE|OPTION_DBGFILE)) ) + { + printf("Note: Using default output '-c' (C array *_bin.h)\n\n"); + Options |= OPTION_CARRAY; + } + + /* Open listing file */ + if( Options & OPTION_LISTING ) + { + strcpy( outfilename, outbase ); + strcat( outfilename, ".lst" ); + if (!(ListingFile = fopen(outfilename,"wb"))) + { Report(0,REP_ERROR,"Unable to open output file: %s",outfilename); return(RET_ERROR); } + } + + /* Clear the binary image */ + memset( ProgramImage, 0, sizeof(ProgramImage) ); + + /* Make 2 assembler passes */ + Pass = 0; + Errors = 0; + Warnings = 0; + FatalError = 0; + RetRegValue = DEFAULT_RETREGVAL; + RetRegField = DEFAULT_RETREGFLD; + while( !Errors && Pass<2 ) + { + Pass++; + CodeOffset = -1; + HaveEntry = 0; + EntryPoint = -1; + + /* Initialize the PP and DOT modules */ + for(i=0; iOffset; + strcpy(lbl.Name,pLabel->Name); + if(BigEndian) + lbl.AddrOffset = HNC32(lbl.AddrOffset); + if( fwrite(&lbl,1,sizeof(DBGFILE_LABEL),Outfile) != sizeof(DBGFILE_LABEL) ) + Report(0,REP_ERROR,"File write error"); + pLabel = pLabel->pNext; + } + } + + for(i=0; i<(int)hdr.FileCount; i++) + { + memset( &file, 0, sizeof(DBGFILE_FILE) ); + if( !strcmp( sfArray[i].SourceBaseDir,"./") || + ((strlen(sfArray[i].SourceName)+strlen(sfArray[i].SourceBaseDir)) >= DBGFILE_NAMELEN_SHORT) ) + strcpy(file.SourceName,sfArray[i].SourceName); + else + { + strcpy(file.SourceName,sfArray[i].SourceBaseDir); + strcat(file.SourceName,sfArray[i].SourceName); + } + if( fwrite(&file,1,sizeof(DBGFILE_FILE),Outfile) != sizeof(DBGFILE_FILE) ) + Report(0,REP_ERROR,"File write error"); + } + + for(i=0; i<(int)hdr.CodeCount; i++) + { + memset( &code, 0, sizeof(DBGFILE_CODE) ); + code.Flags = ProgramImage[i].Flags; + code.Resv8 = ProgramImage[i].Resv8; + code.FileIndex = ProgramImage[i].FileIndex; + code.Line = ProgramImage[i].Line; + code.AddrOffset = ProgramImage[i].AddrOffset; + code.CodeWord = ProgramImage[i].CodeWord; + if(BigEndian) + { + code.FileIndex = HNC16(code.FileIndex); + code.Line = HNC32(code.Line); + code.AddrOffset = HNC32(code.AddrOffset); + code.CodeWord = HNC32(code.CodeWord); + } + if( fwrite(&code,1,sizeof(DBGFILE_CODE),Outfile) != sizeof(DBGFILE_CODE) ) + Report(0,REP_ERROR,"File write error"); + } + fclose( Outfile ); + } + } + if( Options & OPTION_SOURCELISTING ) + { + FILE *Outfile; + + strcpy( outfilename, outbase ); + strcat( outfilename, ".txt" ); + if (!(Outfile = fopen(outfilename,"wb"))) + Report(0,REP_ERROR,"Unable to open output file: %s",outfilename); + else + { + char FullPath[SOURCE_BASE_DIR+SOURCE_NAME]; + + for( i=0; i<(int)sfIndex; i++ ) + { + fprintf(Outfile, "Source File %d : '%s' ", i+1, sfArray[i].SourceName); + strcpy(FullPath,sfArray[i].SourceBaseDir); + strcat(FullPath,sfArray[i].SourceName); + sfArray[i].FilePtr=fopen(FullPath,"rb"); + if( sfArray[i].FilePtr!=0 ) + { + sfArray[i].CurrentLine = 1; + sfArray[i].CurrentColumn = 1; + sfArray[i].LastChar = 0; + ListFile(Outfile,&sfArray[i]); + fclose(sfArray[i].FilePtr); + fprintf(Outfile, "\n\n"); + } + else + fprintf(Outfile, "(File Not Found '%s')\n\n",FullPath); + } + + fclose(Outfile); + } + } + if( Options & OPTION_BINARY ) + { + FILE *Outfile; + + strcpy( outfilename, outbase ); + strcat( outfilename, ".bin" ); + if (!(Outfile = fopen(outfilename,"wb"))) + Report(0,REP_ERROR,"Unable to open output file: %s",outfilename); + else + { + unsigned char tmp; + + /* Write out as Little Endian */ + for(i=0;i>8); + fwrite(&tmp,1,1,Outfile); + tmp = (unsigned char)(ProgramImage[i].CodeWord>>16); + fwrite(&tmp,1,1,Outfile); + tmp = (unsigned char)(ProgramImage[i].CodeWord>>24); + fwrite(&tmp,1,1,Outfile); + } + fclose( Outfile ); + } + } + if( Options & OPTION_BINARYBIG ) + { + FILE *Outfile; + + strcpy( outfilename, outbase ); + strcat( outfilename, ".bib" ); + if (!(Outfile = fopen(outfilename,"wb"))) + Report(0,REP_ERROR,"Unable to open output file: %s",outfilename); + else + { + unsigned char tmp; + + /* Write out as Big Endian */ + for(i=0;i>24); + fwrite(&tmp,1,1,Outfile); + tmp = (unsigned char)(ProgramImage[i].CodeWord>>16); + fwrite(&tmp,1,1,Outfile); + tmp = (unsigned char)(ProgramImage[i].CodeWord>>8); + fwrite(&tmp,1,1,Outfile); + tmp = (unsigned char)ProgramImage[i].CodeWord; + fwrite(&tmp,1,1,Outfile); + } + fclose( Outfile ); + } + } + + /* Assember label cleanup */ + while( pLabelList ) + LabelDestroy( pLabelList ); + + if( Errors || CodeOffset<=0 ) + return(RET_ERROR); + return(RET_SUCCESS); +} + + +/* +// ProcessSourceFile +// +// New source file to assemble. +// +// Returns 1 on success, 0 on error +*/ +#define MAX_SOURCE_LINE 256 +int ProcessSourceFile( SOURCEFILE *ps ) +{ + char src[MAX_SOURCE_LINE]; + int i; + + for(;;) + { + /* Abort on a total disaster */ + if( FatalError || Errors >= 25 ) + { printf("Aborting...\n"); return(0); } + + /* Get a line of source code */ + i = GetSourceLine( ps, src, MAX_SOURCE_LINE ); + if( !i ) + return(1); + if( i<0 ) + continue; + + if( !ProcessSourceLine(ps, i, src) && Pass==2 ) + return(0); + } +} + + +/* +// ProcessSourceLine +// +// New source line to assemble. +// +// Returns 1 on success, 0 on error +*/ +int ProcessSourceLine( SOURCEFILE *ps, int length, char *src ) +{ + char *pParams[MAX_TOKENS]; + SRCLINE sl; + int i,rc; + +REPEAT: + if( !ParseSourceLine(ps,length,src,&sl) ) + return(0); + + /* Process Label */ + if( sl.Flags & SRC_FLG_LABEL ) + { + /* Make sure offset is ready */ + if( !ValidateOffset(ps) ) + return(0); + + /* Create Label */ + if( Pass==1 ) + { + LabelCreate(ps, sl.Label, CodeOffset); + } + + /* Note it in listing file */ + if( Pass==2 && (Options & OPTION_LISTING) ) + { + fprintf(ListingFile,"%s(%5d) : 0x%04x = Label : %s:\n", + ps->SourceName,ps->CurrentLine,CodeOffset,sl.Label); + } + } + + /* Process Command/Opcode */ + if( sl.Terms ) + { + /* Get the parameters into a collection of string pointers */ + for(i=0; i<(int)sl.Terms; i++) + pParams[i]=sl.Term[i]; + for( ; iFlags = 0; + pa->Terms = 0; + +PROCESS_LINE: + /* Make sure character 1 is legal */ + c = src[srcIdx++]; + if( !LabelChar(c,1) && c!='.' ) + { + Report(ps,REP_ERROR,"Syntax error in Cmd/Opcode"); + return(0); + } + + /* Get the Opcode or Command */ + wordIdx = 0; + while( LabelChar(c,0) || c=='.' ) + { + if( wordIdx>=(TOKEN_MAX_LEN-1) ) + { Report(ps,REP_ERROR,"Cmd/Opcode too long"); return(0); } + pa->Term[0][wordIdx++] = c; + c = src[srcIdx++]; + } + pa->Term[0][wordIdx]=0; + + /* See if it is a label */ + if( c==':' ) + { + if( pa->Flags & SRC_FLG_LABEL ) + { Report(ps,REP_ERROR,"Two labels found on the same line"); return(0); } + pa->Flags |= SRC_FLG_LABEL; + strcpy(pa->Label,pa->Term[0]); + + /* Process any assembly after the label */ + c = src[srcIdx]; + if( c!=0 ) + { + while( c==' ' || c==0x9 ) + c = src[++srcIdx]; + goto PROCESS_LINE; + } + return(1); + } + + if( c!=' ' && c!=0 && c!=0x9 ) + { + Report(ps,REP_ERROR,"Syntax error in Cmd/Opcode"); + return(0); + } + + /* Get up to "MAX_TOKENS-1" parameters (comma delimited) */ + parmCnt=0; + while(c) + { + wordIdx=0; + parmCnt++; + if( parmCnt==MAX_TOKENS ) + { Report(ps,REP_ERROR,"Too many parameters on line"); return(0); } + + /* Trim off leading white space */ + while( c==' ' || c==0x9 ) + c = src[srcIdx++]; + + if( !LabelChar(c,0) && + c!='.' && c!='#' && c!='-' && c!='(' && c!='"' && c!='&' && c!='*' ) + { Report(ps,REP_ERROR,"Syntax error in parameter %d",parmCnt); return(0); } + + if( parmCnt==1 && c=='.' ) + { + while( c!=0 && c!=',' && c!=' ' && c!=0x9 ) + { + if( wordIdx>=(TOKEN_MAX_LEN-1) ) + { Report(ps,REP_ERROR,"Parameter %d too long",parmCnt); return(0); } + pa->Term[parmCnt][wordIdx++] = c; + c = src[srcIdx++]; + + } + if(c==' ' || c==0x9) + c=','; + + pa->Flags |= SRC_FLG_DOTCMD2; + } + else + { + while( c!=0 && c!=',' ) + { + if( wordIdx>=(TOKEN_MAX_LEN-1) ) + { Report(ps,REP_ERROR,"Parameter %d too long",parmCnt); return(0); } + pa->Term[parmCnt][wordIdx++] = c; + c = src[srcIdx++]; + } + } + pa->Term[parmCnt][wordIdx] = 0; + + /* Trim off trailing white space */ + while( wordIdx && (pa->Term[parmCnt][wordIdx-1]==0x9 || pa->Term[parmCnt][wordIdx-1]==' ') ) + pa->Term[parmCnt][--wordIdx]=0; + + /* This character must be a comma or NULL */ + if( c==',' ) + c = src[srcIdx++]; + else if( c ) + { Report(ps,REP_ERROR,"Syntax error in parameter %d",parmCnt); return(0); } + } + + parmCnt++; + pa->Terms = parmCnt; + + /* If its a dot command, mark it */ + if( pa->Term[0][0]=='.' ) + pa->Flags |= SRC_FLG_DOTCMD1; + + return(1); +} + + +/* +// GenOp +// +// Generate an opcode to the ouput file +// +// ps - Pointer to source file record +// TermCnt - Number of terms (including the command) +// pTerms - Pointer to the terms +// opcode - Generated Opcode +*/ +void GenOp( SOURCEFILE *ps, int TermCnt, char **pTerms, uint opcode ) +{ + int i; + + if( !ValidateOffset(ps) ) + return; + + if( (Options & OPTION_LISTING) && Pass==2 ) + { + fprintf(ListingFile,"%s(%5d) : 0x%04x = 0x%08x : ", + ps->SourceName,ps->CurrentLine,CodeOffset,opcode); + fprintf(ListingFile,"%-8s ",pTerms[0]); + for(i=1; i1 ) + fprintf(ListingFile,", %s",pTerms[i]); + else + fprintf(ListingFile,"%s",pTerms[i]); + } + if( opcode==0xFFFFFFFF ) + fprintf(ListingFile," // *** ERROR ***"); + + fprintf(ListingFile,"\n"); + } + + ProgramImage[CodeOffset].Flags = CODEGEN_FLG_FILEINFO|CODEGEN_FLG_CANMAP; + ProgramImage[CodeOffset].FileIndex = ps->FileIndex; + ProgramImage[CodeOffset].Line = ps->CurrentLine; + ProgramImage[CodeOffset].AddrOffset = CodeOffset; + ProgramImage[CodeOffset++].CodeWord = opcode; +} + + +/* +// Report +// +// Report an abnormal condition +*/ +void Report( SOURCEFILE *ps, int Level, char *fmt, ... ) +{ + va_list arg_ptr; + + if( Pass==1 && Level==REP_WARN2 ) + return; + if( Pass==2 && (Level==REP_INFO || Level==REP_WARN1) ) + return; + + /* Log to stdout */ + if( ps ) + printf("%s(%d) ",ps->SourceName,ps->CurrentLine); + + if( Level == REP_FATAL ) + { + printf("Fatal Error: "); + FatalError=1; + Errors++; + } + else if( Level == REP_ERROR ) + { + printf("Error: "); + Errors++; + } + else if( Level==REP_WARN1 || Level==REP_WARN2 ) + { + printf("Warning: "); + Warnings++; + } + else + printf("Note: "); + + va_start( arg_ptr, fmt ); + vprintf( fmt, arg_ptr ); + va_end( arg_ptr ); + + if( !ps ) + printf("\n"); + printf("\n"); +} + + +/* +// LabelChar +// +// Return whether the character is legal for a label. +// Numbers are not allowed when FlagFirstChar is set. +// +// Returns 1 on success, 0 on error +*/ +int LabelChar( char c, int FlagFirstChar ) +{ + if( FlagFirstChar ) + { + if( (c>='A'&&c<='Z')||(c>='a'&&c<='z')||(c=='_') ) + return(1); + else + return(0); + } + if( (c>='A'&&c<='Z')||(c>='a'&&c<='z')||(c>='0'&&c<='9')||(c=='_')) + return(1); + else + return(0); +} + + +/* +// LabelCreate +// +// Create a label with the supplied offset value +// +// Returns 1 on success, 0 on error +*/ +int LabelCreate( SOURCEFILE *ps, char *label, int value ) +{ + LABEL *pl; + + if( strlen(label) >= LABEL_NAME_LEN ) + { Report(ps,REP_ERROR,"Label too long"); return(0); } + + /* Make sure this name is OK to use */ + if( !CheckName(ps,label) ) + return(0); + + /* Allocate a new record */ + pl = malloc(sizeof(LABEL)); + if( !pl ) + { Report(ps,REP_FATAL,"Memory allocation failed"); return(0); } + + strcpy( pl->Name, label ); + pl->Offset = value; + + /* Put this label in the master list */ + pl->pPrev = 0; + pl->pNext = pLabelList; + if( pLabelList ) + pLabelList->pPrev = pl; + pLabelList = pl; + LabelCount++; + + if( (Options & OPTION_DEBUG) ) + printf("%s(%5d) : LABEL : '%s' = %05d\n", ps->SourceName,ps->CurrentLine,label,value); + + return(1); +} + + +/* +// LabelFind +// +// Searches for an equate by name. If found, returns the record pointer. +// +// Returns LABEL * on success, 0 on error +*/ +LABEL *LabelFind( char *name ) +{ + LABEL *pl; + + pl = pLabelList; + while( pl ) + { + if( !strcmp( name, pl->Name ) ) + break; + pl = pl->pNext; + } + return(pl); +} + + +/* +// LabelDestroy +// +// Frees and label record. +// +// void +*/ +void LabelDestroy( LABEL *pl ) +{ + if( !pl->pPrev ) + pLabelList = pl->pNext; + else + pl->pPrev->pNext = pl->pNext; + + if( pl->pNext ) + pl->pNext->pPrev = pl->pPrev; + + LabelCount--; + + free(pl); +} + + +/* +// Check Name +// +// Returns 1 if the name is free, or 0 if it is in use +*/ +int CheckName( SOURCEFILE *ps, char *name ) +{ + /* Make sure its not a reserved word */ + if( CheckTokenType(name)!=TOKENTYPE_UNRESERVED ) + { Report(ps,REP_ERROR,"Illegal use of reserved word '%s'",name); return(0); } + if( LabelFind(name) ) + { Report(ps,REP_ERROR,"'%s' is already a label",name); return(0); } + if( CheckEquate(name) ) + { Report(ps,REP_ERROR,"'%s' is already an equate",name); return(0); } + if( CheckStruct(name) ) + { Report(ps,REP_ERROR,"'%s' is already a structure or scope",name); return(0); } + if( CheckMacro(name) ) + { Report(ps,REP_ERROR,"'%s' is already a macro",name); return(0); } + return(1); +} + + +/*=================================================================== +// +// Private Functions +// +====================================================================*/ + +/* +// ValidateOffset +// +// Validates that the current offset is ready to be used +// +// Returns 1 on success, 0 on error +*/ +static int ValidateOffset( SOURCEFILE *ps ) +{ + uint opcode; + + if( CodeOffset==-1 ) + { + CodeOffset = 8; + if( EntryPoint<0 ) + EntryPoint = 8; + if( Core != CORE_V0 ) + Report(ps,REP_WARN1,"Using default code origin of 8"); + else + { + opcode = 0x21000900; + + /* Note it in listing file */ + if( Pass==2 && (Options & OPTION_LISTING) ) + { + fprintf(ListingFile, + "%s(%5d) : 0x%04x = 0x%08x : JMP #0x9 // Legacy Mode\n", + ps->SourceName,ps->CurrentLine,CodeOffset,opcode); + } + + ProgramImage[CodeOffset].Flags = CODEGEN_FLG_FILEINFO; + ProgramImage[CodeOffset].FileIndex = ps->FileIndex; + ProgramImage[CodeOffset].Line = ps->CurrentLine; + ProgramImage[CodeOffset].AddrOffset = CodeOffset; + ProgramImage[CodeOffset++].CodeWord = opcode; + } + } + + if( CodeOffset >= MAX_PROGRAM ) + { Report(ps,REP_FATAL,"Max program size exceeded"); return(0); } + + return(1); +} + +/* +// PrintLine +// +// Prints out a line of the source file for source listings +// +// Returns 1 on success, 0 on EOF +*/ +static int PrintLine( FILE *pfOut, SOURCEFILE *ps ) +{ + int i; + char c; + +AGAIN: + i = fread( &c, 1, 1, ps->FilePtr ); + if( i != 1 ) + return(0); + if( c == 0xd ) + goto AGAIN; + if( c == 0xa ) + { + ps->CurrentLine++; + fprintf(pfOut,"\n"); + return(1); + } + fprintf(pfOut,"%c",c); + goto AGAIN; +} + +/* +// GetInfoFromAddr +// +// Returns the SourceFileIndex, Line Number, and CodeWord for a given address offset +// +// Returns 0 on success, -1 on error +*/ +static int GetInfoFromAddr( uint address, uint *pIndex, uint *pLineNo, uint *pCodeWord ) +{ + int i; + + for(i=0; i<(int)CodeOffset; i++) + { + if( ProgramImage[i].AddrOffset == address ) + { + *pIndex = ProgramImage[i].FileIndex; + *pLineNo = ProgramImage[i].Line; + *pCodeWord = ProgramImage[i].CodeWord; + return 0; + } + } + return -1; +} + +/* +// ListFile +// +// Prints out an object code annotated listing of an original source file +// +// Returns 1 on success +*/ +static int ListFile( FILE *pfOut, SOURCEFILE *ps ) +{ + uint addr, index, line, code, count, output, cline; + + count = 0; + for( addr=0; addr<(uint)CodeOffset; addr++ ) + { + if( GetInfoFromAddr( addr, &index, &line, &code ) >= 0 ) + { + if( index == ps->FileIndex ) + count++; + } + } + + if( !count ) + { + // No code section + fprintf(pfOut,"(No Ouput Generated)\n\n"); + + for(;;) + { + fprintf(pfOut,"%5d : : ",ps->CurrentLine ); + if( !PrintLine(pfOut,ps) ) + return(1); + } + } + else + { + fprintf(pfOut,"(%d Instructions Generated)\n\n",count); + + for(;;) + { + output = 0; + cline = ps->CurrentLine; + + for( addr=0; addr<(uint)CodeOffset; addr++ ) + { + if( (GetInfoFromAddr( addr, &index, &line, &code ) < 0) || index!=ps->FileIndex || lineCurrentLine ); + if( !PrintLine(pfOut,ps) ) + return(1); + } + } + } + return(1); +} + + diff --git a/am335x/pasm/pasm.h b/am335x/pasm/pasm.h new file mode 100644 index 00000000..dccbeeed --- /dev/null +++ b/am335x/pasm/pasm.h @@ -0,0 +1,645 @@ +/* + * pasm.h + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +/*=========================================================================== + * Copyright (c) Texas Instruments Inc 2010-12 + * + * Use of this software is controlled by the terms and conditions found in the + * license agreement under which this software has been supplied or provided. + * ============================================================================ + */ + +/*=========================================================================== +// PASM - PRU Assembler +//--------------------------------------------------------------------------- +// +// File : pasm.h +// +// Description: +// Main include file +// - Global data structures and assembler state +// - Declarations of all public functions +// +//--------------------------------------------------------------------------- +// Revision: +// 21-Jun-13: 0.84 - Open source version +============================================================================*/ +typedef unsigned int uint; + +#include "pru_ins.h" + +#define TOKEN_MAX_LEN 128 + +/* Label Record */ +#define LABEL_NAME_LEN TOKEN_MAX_LEN +typedef struct _LABEL { + struct _LABEL *pPrev; /* Previous in LABEL list */ + struct _LABEL *pNext; /* Next in LABEL list */ + int Offset; /* Offset Value */ + char Name[LABEL_NAME_LEN]; +} LABEL; + +/* Source File Record */ +#define SOURCE_NAME 64 +#define SOURCE_BASE_DIR 256 +typedef struct _SOURCEFILE { + struct _SOURCE *pParent; /* The file that included this file */ + FILE *FilePtr; /* Open file handle */ + unsigned int InUse; /* Set to '1' if file is active */ + unsigned int FileIndex; /* Index of this source file in CODEGEN */ + unsigned int CurrentLine; /* The current line being read */ + unsigned int CurrentColumn; /* The current column being read */ + unsigned int ccDepthIn; /* Original condition code depth */ + char LastChar; /* Last character read from file */ + char SourceName[SOURCE_NAME]; + char SourceBaseDir[SOURCE_BASE_DIR]; +} SOURCEFILE; + +/* Source Line Record */ +#define MAX_TOKENS 12 +#define SRC_FLG_LABEL (1<<0) +#define SRC_FLG_DOTCMD1 (1<<1) +#define SRC_FLG_DOTCMD2 (1<<2) +typedef struct _SRCLINE { + uint Flags; + uint Terms; + char Label[TOKEN_MAX_LEN]; + char Term[MAX_TOKENS][TOKEN_MAX_LEN]; +} SRCLINE; + +/* CodeGen Record */ +typedef struct _CODEGEN { + unsigned char Flags; /* Record flags */ +#define CODEGEN_FLG_FILEINFO 0x01 +#define CODEGEN_FLG_CANMAP 0x02 + unsigned char Resv8; /* Reserved */ + unsigned short FileIndex; /* Source file index */ + unsigned int Line; /* The line number */ + unsigned int AddrOffset; /* Code address offset */ + unsigned int CodeWord; /* Code */ +} CODEGEN; + +/* User Options */ +extern unsigned int Options; +#define OPTION_BINARY (1<<0) +#define OPTION_BINARYBIG (1<<1) +#define OPTION_CARRAY (1<<2) +#define OPTION_IMGFILE (1<<3) +#define OPTION_DBGFILE (1<<4) +#define OPTION_LISTING (1<<5) +#define OPTION_DEBUG (1<<6) +#define OPTION_BIGENDIAN (1<<7) +#define OPTION_RETREGSET (1<<8) +#define OPTION_SOURCELISTING (1<<9) +extern unsigned int Core; +#define CORE_NONE 0 +#define CORE_V0 1 +#define CORE_V1 2 +#define CORE_V2 3 +#define CORE_V3 4 +extern FILE *CArrayFile; +extern FILE *ListingFile; + +/* Assembler Engine */ +extern int Pass; /* Pass 1 or 2 of parser */ +extern int HaveEntry; /* Entrypont flag (init to 0) */ +extern int EntryPoint; /* Entrypont (init to -1) */ +extern int CodeOffset; /* Current instruction "word" offset (zero based) */ +extern int Errors; /* Total number or errors */ +extern int FatalError; /* Set on fatal error */ +extern int Warnings; /* Total number of warnings */ +extern uint RetRegValue; /* Return register index */ +extern uint RetRegField; /* Return register field */ + +#define DEFAULT_RETREGVAL 30 +#define DEFAULT_RETREGFLD FIELDTYPE_15_0 + +#define SOURCEFILE_MAX 64 +extern SOURCEFILE sfArray[SOURCEFILE_MAX]; +extern unsigned int sfIndex; + +/* Use platform appropriate function for case-insensitive string compare */ +#ifdef _MSC_VER + #define stricmp _stricmp +#elif defined(__GNUC__) + #define stricmp strcasecmp +#endif + + +/*===================================================================== +// +// Functions Implemented by the Opcode Module +// +//====================================================================*/ + +/* +// CheckOpcode +// +// Called to see if the supplied token is a reserved word. +// +// Returns index of opcode, 0 if not an opcode +*/ +int CheckOpcode( char *word ); + + +/* +// CheckTokenType +// +// Called to see if the supplied token is reserved word. +// +// Returns token type flags +*/ +uint CheckTokenType( char *word ); +#define TOKENTYPE_UNRESERVED 0 +#define TOKENTYPE_FLG_OPCODE 0x0001 +#define TOKENTYPE_FLG_DIRECTIVE 0x0002 +#define TOKENTYPE_FLG_REG_BASE 0x0004 +#define TOKENTYPE_FLG_REG_ADDR 0x0008 +#define TOKENTYPE_FLG_REG_PTR 0x0010 +#define TOKENTYPE_FLG_REG_POSTINC 0x0020 +#define TOKENTYPE_FLG_REG_PREDEC 0x0040 + +/* +// ProcessOp +// +// Opcode processor +// +// This is the function that assembles opcode statements +// +// ps - Pointer to source file record +// TermCnt - Number of terms (including the command) +// pTerms - Pointer to the terms +// +// Returns: +// 1 : Success +// 0 : Error +*/ +int ProcessOp( SOURCEFILE *ps, int TermCnt, char **pTerms ); + +/* +// GetRegister +// +// Get Register Argument +// +// Parses the source string for a register and field +// +// ps - Pointer to source file record +// num - operand number (1 based) +// src - source string +// pa - Pointer to register structure +// fBitOk - Can accept Rxx.Txx +// termC - Set to non-zero if special terminating character ('+') +// +// Returns: +// 1 : Success +// 0 : Error +*/ +int GetRegister( SOURCEFILE *ps, int num, char *src, PRU_ARG *pa, int fBitOk, char termC ); + + +/*===================================================================== +// +// Functions Implemented by the DotCommand Module +// +//====================================================================*/ + +/* +// CheckDotCommand +// +// Check to see if supplied word is a dot command +// +// Returns 1 if the word is a command, else zero +*/ +int CheckDotCommand( char *word ); + +/* +// DotCommand +// +// Dot command processor +// +// This is the function where users add their assembler commands +// +// ps - Pointer to source file record +// TermCnt - Number of terms (including the command) +// pTerms - Pointer to the terms +// Src - Buffer to write any resulting assembly line +// MaxSrc - Size of assembly line buffer +// +// Returns: +// >=0 : Success - Length of assemby line (0 to MaxSrc) +// <0 : Illegal command +*/ +int DotCommand( SOURCEFILE *ps, int TermCnt, char **pTerms, char *Src, int MaxSrc ); + +/* +// DotInitialize +// +// Open the dot-command environment +// +// void +*/ +void DotInitialize(int pass); + +/* +// DotCleanup +// +// Clean up the dot environment +// +// void +*/ +void DotCleanup(int pass); + + + +/*===================================================================== +// +// Functions Implemented by the Structure/Scope Module +// +//====================================================================*/ + +/* +// ScopeEnter +// +// Returns: +// 0 - Success +// -1 - Error +*/ +int ScopeEnter( SOURCEFILE *ps, char *Name ); + + +/* +// ScopeLeave +// +// Returns: +// 0 - Success +// -1 - Error +*/ +int ScopeLeave( SOURCEFILE *ps, char *Name ); + + +/* +// ScopeUsing +// +// Returns: +// 0 - Success +// -1 - Error +*/ +int ScopeUsing( SOURCEFILE *ps, char *Name ); + + +/* +// StructInit +// +// Returns: void +*/ +void StructInit(); + + +/* +// StructCleanup +// +// Returns: void +*/ +void StructCleanup(); + + +/* +// StructNew +// +// Returns: +// 0 - Success +// -1 - Error +*/ +int StructNew( SOURCEFILE *ps, char *Name ); + + +/* +// StructEnd +// +// Returns: +// 0 - Success +// -1 - Error +*/ +int StructEnd( SOURCEFILE *ps ); + + +/* +// StructAddElement +// +// Create a new structure record +// +// Returns 0 on success, -1 on error +*/ +int StructAddElement( SOURCEFILE *ps, char *Name, uint size ); + + +/* +// StructAssign +// +// Assign a structure to an instance +// +// Returns 0 on success, -1 on error +*/ +int StructAssign( SOURCEFILE *ps, char *structName, char *rsName, + char *reName, char *defName ); + + +/* +// Struct Param Process +// +// Processes the supplied argument for stucture references or SIZE/OFFSET +// operations. When found, the structure definition is used to substitute +// in the proper register or numeric value. +// +// The string 'source' is assumed to be be able to hold a length of +// at least 'TOKEN_MAX_LEN' bytes. +// +// Returns 0 for OK, or -1 for Fatal Error +// +*/ +int StructParamProcess( SOURCEFILE *ps, int ParamIdx, char *source ); + + +/* +// CheckStruct +// +// Searches for struct template or struct by name. +// +// Returns 1 on success, 0 on error +*/ +int CheckStruct( char *name ); + + + +/*===================================================================== +// +// Main Assembler Functions +// +//====================================================================*/ + +/* +// ProcessSourceFile +// +// New source file to assemble. +// +// Returns 1 on success, 0 on error +*/ +int ProcessSourceFile( SOURCEFILE *ps ); + +/* +// ProcessSourceLine +// +// New source line to assemble. +// +// Returns 1 on success, 0 on error +*/ +int ProcessSourceLine( SOURCEFILE *ps, int length, char *src ); + +/* +// ParseSourceLine +// +// New source line to parse. +// +// Returns 1 on success, 0 on error +*/ +int ParseSourceLine( SOURCEFILE *ps, int length, char *src, SRCLINE *pa ); + +/* +// Report +// +// Report an abnormal condition +*/ +#define REP_INFO 0 /* Information only */ +#define REP_WARN1 1 /* Warn on pass1 */ +#define REP_WARN2 2 /* Warn on pass2 */ +#define REP_ERROR 3 +#define REP_FATAL 4 +void Report( SOURCEFILE *ps, int Level, char *fmt, ... ); + +/* +// LabelChar +// +// Return whether the character is legal for a label. +// Numbers are not allowed when FlagFirstChar is set. +// +// Returns 1 on success, 0 on error +*/ +int LabelChar( char c, int FlagFirstChar ); + + +/* +// LabelCreate +// +// Create a label with the supplied offset value +// +// Returns 1 on success, 0 on error +*/ +int LabelCreate( SOURCEFILE *ps, char *label, int value ); + + +/* +// LabelFind +// +// Searches for an equate by name. If found, returns the record pointer. +// +// Returns LABEL * on success, 0 on error +*/ +LABEL *LabelFind( char *name ); + + +/* +// LabelDestroy +// +// Frees and label record. +// +// void +*/ +void LabelDestroy( LABEL *pl ); + + +/* +// GenOp +// +// Generate an opcode to the ouput file +// +// ps - Pointer to source file record +// TermCnt - Number of terms (including the command) +// pTerms - Pointer to the terms +// opcode - Generated Opcode +*/ +void GenOp( SOURCEFILE *ps, int TermCnt, char **pTerms, uint opcode ); + + +/* +// Check Name +// +// Returns 1 if the name is free, or 0 if it is in use +*/ +int CheckName( SOURCEFILE *ps, char *name ); + + +/*======================================================================= +// +// Expression Analyzer +// +=======================================================================*/ + +/* +// Expression - Math Expression Parser +// +// Returns 0 on success, <0 on error +*/ +int Expression( SOURCEFILE *ps, char *s, uint *pResult, int *pIndex ); + + + +/*======================================================================= +// +// Pre-processor Functions +// +=======================================================================*/ + +/* +// InitSourceFile +// +// Initializes all the fields in SOURCEFILE, and attempts to to open the +// file. +// +// Returns 1 on success, 0 on error +*/ +SOURCEFILE *InitSourceFile( SOURCEFILE *pParent, char *filename ); + +/* +// CloseSourceFile +// +// Close the source file and free the block. +// +// void +*/ +void CloseSourceFile( SOURCEFILE *ps ); + +/* +// GetSourceLine +// +// Get a new line of source code. +// +// This module also processes: +// '#' directives +// #define expansion +// Comments +// +// Returns length of line, 0 on EOF, -1 on Error +*/ +int GetSourceLine( SOURCEFILE *ps, char *Dst, int MaxLen ); + +/* +// ppCleanup +// +// Clean up the pre-processor environment +// +// void +*/ +void ppCleanup(); + + +/* +// EquateCreate +// +// Creates an equate record +// +// Returns 0 on success, -1 on error +*/ +#define EQUATE_NAME_LEN TOKEN_MAX_LEN +#define EQUATE_DATA_LEN 256 +int EquateCreate( SOURCEFILE *ps, char *Name, char *Value ); + + +/* +// CheckEquate +// +// Searches for an equate by name. +// +// Returns 1 on success, 0 on error +*/ +int CheckEquate( char *name ); + + +/*======================================================================= +// +// Macro Functions +// +=======================================================================*/ + +/* +// MacroEnter +// Returns: +// 0 - Success +// -1 - Error +*/ +int MacroEnter( SOURCEFILE *ps, char *Name ); + + +/* +// ProcessMacro +// +// ps - Pointer to source file record +// TermCnt - Number of terms (including the command) +// pTerms - Pointer to the terms +// +// Returns: +// 1 : Success +// 0 : Error +*/ +int ProcessMacro( SOURCEFILE *ps, int TermCnt, char **pTerms ); + + +/* +// MacroCleanup +// +// Returns: void +*/ +void MacroCleanup(); + + +/* +// CheckMacro +// +// Searches for an macro by name. +// +// Returns 1 on success, 0 on error +*/ +int CheckMacro( char *name ); + diff --git a/am335x/pasm/pasmdbg.h b/am335x/pasm/pasmdbg.h new file mode 100644 index 00000000..9b2eefee --- /dev/null +++ b/am335x/pasm/pasmdbg.h @@ -0,0 +1,97 @@ +/* + * pasmdbg.h + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + + +/*=========================================================================== + * Copyright (c) Texas Instruments Inc 2010-12 + * + * Use of this software is controlled by the terms and conditions found in the + * license agreement under which this software has been supplied or provided. + * ============================================================================ + */ + + +/*=========================================================================== +// PASM - PRU Assembler +//--------------------------------------------------------------------------- +// +// File : pasmdbg.h +// +// Description: +// File format for pView debugger debug file +// +//--------------------------------------------------------------------------- +// Revision: +// 21-Jun-13: 0.84 - Open source version +============================================================================*/ + +#define DBGFILE_NAMELEN_SHORT 64 + +typedef struct _DBGFILE_HEADER { + unsigned int FileID; +#define DBGFILE_FILEID_VER3 (0x10150000 | 0x03) + unsigned int LabelCount; /* Number of label records */ + unsigned int LabelOffset; /* File offset to label records */ + unsigned int FileCount; /* Number of file records */ + unsigned int FileOffset; /* File offset to file records */ + unsigned int CodeCount; /* Number of code records */ + unsigned int CodeOffset; /* File offset to code records */ + unsigned int EntryPoint; /* Program entrypoint */ + unsigned int Flags; /* File format flags */ +#define DBGHDR_FLAGS_BIGENDIAN 0x00000001 +} DBGFILE_HEADER; + +typedef struct _DBGFILE_LABEL { + unsigned int AddrOffset; + char Name[DBGFILE_NAMELEN_SHORT]; +} DBGFILE_LABEL; + +typedef struct _DBGFILE_FILE { + char SourceName[DBGFILE_NAMELEN_SHORT]; +} DBGFILE_FILE; + +typedef struct _DBGFILE_CODE { + unsigned char Flags; /* Record flags */ +#define DBGFILE_CODE_FLG_FILEINFO 0x01 +#define DBGFILE_CODE_FLG_CANMAP 0x02 + unsigned char Resv8; /* Reserved */ + unsigned short FileIndex; /* Source file index */ + unsigned int Line; /* The line number */ + unsigned int AddrOffset; /* Code address offset */ + unsigned int CodeWord; /* Code */ +} DBGFILE_CODE; + + diff --git a/am335x/pasm/pasmdot.c b/am335x/pasm/pasmdot.c new file mode 100644 index 00000000..1ad4a5b4 --- /dev/null +++ b/am335x/pasm/pasmdot.c @@ -0,0 +1,446 @@ +/* + * pasmdot.c + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +/*=========================================================================== + * Copyright (c) Texas Instruments Inc 2010-12 + * + * Use of this software is controlled by the terms and conditions found in the + * license agreement under which this software has been supplied or provided. + * ============================================================================ + */ + +/*=========================================================================== +// PASM - PRU Assembler +//--------------------------------------------------------------------------- +// +// File : pasmdot.c +// +// Description: +// Processes the "dot" commands (.ret, .origin, .main, etc.) +// +//--------------------------------------------------------------------------- +// Revision: +// 21-Jun-13: 0.84 - Open source version +============================================================================*/ + +#include +#include +#include +#if !defined(__APPLE__) +#include +#else +#include +#endif +#include +#include "pasm.h" + +#define DOTCMD_MAIN 0 +#define DOTCMD_END 1 +#define DOTCMD_PROC 2 +#define DOTCMD_RET 3 +#define DOTCMD_ORIGIN 4 +#define DOTCMD_ENTRYPOINT 5 +#define DOTCMD_STRUCT 6 +#define DOTCMD_ENDS 7 +#define DOTCMD_U32 8 +#define DOTCMD_U16 9 +#define DOTCMD_U8 10 +#define DOTCMD_ASSIGN 11 +#define DOTCMD_SETCALLREG 12 +#define DOTCMD_ENTER 13 +#define DOTCMD_LEAVE 14 +#define DOTCMD_USING 15 +#define DOTCMD_MACRO 16 +#define DOTCMD_MPARAM 17 +#define DOTCMD_ENDM 18 +#define DOTCMD_CODEWORD 19 +#define DOTCMD_MAX 19 +char *DotCmds[] = { ".main",".end",".proc",".ret",".origin",".entrypoint", + ".struct",".ends",".u32",".u16",".u8",".assign", + ".setcallreg", ".enter", ".leave", ".using", + ".macro", ".mparam", ".endm", ".codeword" }; + +/*=================================================================== +// +// Public Functions +// +====================================================================*/ + +/* +// CheckDotCommand +// +// Check to see if supplied word is a dot command +// +// Returns 1 if the word is a command, else zero +*/ +int CheckDotCommand( char *word ) +{ + int i; + + /* Commands are reserved */ + for(i=0; i<=DOTCMD_MAX; i++) + { + if( !stricmp( word, DotCmds[i] ) ) + return(1); + } + return(0); +} + +/* +// DotCommand +// +// Dot command processor +// +// This is the function where users add their assembler commands +// +// ps - Pointer to source file record +// TermCnt - Number of terms (including the command) +// pTerms - Pointer to the terms +// Src - Buffer to write any resulting assembly line +// MaxSrc - Size of assembly line buffer +// +// Returns: +// >=0 : Success - Length of assemby line (0 to MaxSrc) +// <0 : Illegal command +*/ +int DotCommand( SOURCEFILE *ps, int TermCnt, char **pTerms, char *Src, int MaxSrc ) +{ + int i; + + for(i=0; i<=DOTCMD_MAX; i++) + { + if( !stricmp( pTerms[0], DotCmds[i] ) ) + break; + } + if( i>DOTCMD_MAX ) + { + Report(ps,REP_ERROR,"Unrecognized dot command"); + return(-1); + } + + if( i==DOTCMD_MAIN ) + { + char c,cs; + int quote=0; + int idx=0,nameidx=0; + + /* + // .main command + // + // Just print a warning - its only here for compatibility + */ + if( TermCnt != 2 ) + { Report(ps,REP_ERROR,"Expected 1 operand"); return(-1); } + + /* If the string is in quotes, skip the first charater */ + if( pTerms[1][0]=='"' ) + { + quote++; + idx++; + } + c = pTerms[1][idx++]; + cs = ps->SourceName[nameidx++]; + while( c && c!='"' ) + { + if( toupper(c) != toupper(cs) ) + { +NO_MATCH: + Report(ps,REP_WARN1,".main name '%s' doesn't match '%s'", + pTerms[1],ps->SourceName); + return(0); + } + c = pTerms[1][idx++]; + cs = ps->SourceName[nameidx++]; + } + if( cs && cs!='.' ) + goto NO_MATCH; + if( c=='"' ) + { + quote--; + c = pTerms[1][idx++]; + } + if( c ) + { Report(ps,REP_ERROR,"Trailing characters on name"); return(-1); } + if( quote ) + { Report(ps,REP_ERROR,"Unbalanced quotes on name"); return(-1); } + return(0); + } + else if( i==DOTCMD_END ) + { + /* + // .end command + // + // Do nothing - its only here for compatibility + */ + if( TermCnt != 1 ) + { Report(ps,REP_ERROR,"Expected no operands"); return(-1); } + return(0); + } + else if( i==DOTCMD_PROC ) + { + /* + // .proc command + // + // Create a label from the proc name, with a leading '.' + // (this is for compatibility) + */ + if( TermCnt != 2 ) + { Report(ps,REP_ERROR,"Expected 1 operand"); return(-1); } + sprintf( Src, ".%s:", pTerms[1] ); + return(strlen(Src)); + } + else if( i==DOTCMD_RET ) + { + /* + // .ret command + // + // Generate the line "jmp r30.w0" + // This makes us compatible with "CALL", although inexplicably, + // the CALL command is not a "dot" command. + // + */ + if( TermCnt != 1 ) + { Report(ps,REP_ERROR,"Expected no operands"); return(-1); } + if( Options & OPTION_RETREGSET ) + { Report(ps,REP_ERROR,".ret incompatible with .setcallreg, use ret"); return(-1); } + if( Core > CORE_V1 ) + { Report(ps,REP_ERROR,".ret illegal with specified core version, use ret"); return(-1); } + strcpy( Src, "jmp r30.w0" ); + return(strlen(Src)); + } + else if( i==DOTCMD_ORIGIN ) + { + int val,tmp; + char tstr[TOKEN_MAX_LEN]; + + /* + // .origin command + // + // Alter the origin for writing code + */ + if( TermCnt != 2 ) + { Report(ps,REP_ERROR,"Expected 1 operand"); return(-1); } + + strcpy( tstr, pTerms[1] ); + if( Expression(ps, tstr, (uint *)&val, &tmp)<0 ) + { Report(ps,REP_ERROR,"Error in processing .origin value"); return(-1); } + if( Core == CORE_V0 ) + { Report(ps,REP_ERROR,".origin illegal with specified core version"); return(-1); } + if( val=0 ) + Report(ps,REP_WARN1,"Resetting .origin value after use"); + if( EntryPoint<0 ) + EntryPoint = val; + + CodeOffset = val; + return(0); + } + else if( i==DOTCMD_ENTRYPOINT ) + { + int val,tmp; + char tstr[TOKEN_MAX_LEN]; + + /* + // .entrypoint command + // + // Alter the origin for writing code + */ + if( TermCnt != 2 ) + { Report(ps,REP_ERROR,"Expected 1 operand"); return(-1); } + + strcpy( tstr, pTerms[1] ); + if( Expression(ps, tstr, (uint *)&val, &tmp)<0 ) + { Report(ps,REP_ERROR,"Error in processing .entrypoint value"); return(-1); } + + if( Core == CORE_V0 ) + { Report(ps,REP_ERROR,".entrypoint illegal with specified core version"); return(-1); } + + if( HaveEntry ) + { Report(ps,REP_ERROR,"Multiple .entrypoint declarations"); return(-1); } + + EntryPoint = val; + HaveEntry = 1; + return(0); + } + else if( i==DOTCMD_STRUCT ) + { + if( TermCnt != 2 ) + { Report(ps,REP_ERROR,"Expected 1 operand"); return(-1); } + return( StructNew(ps,pTerms[1]) ); + + } + else if( i==DOTCMD_ENDS ) + { + if( TermCnt != 1 ) + { Report(ps,REP_ERROR,"Expected no operands"); return(-1); } + return( StructEnd(ps) ); + } + else if( i==DOTCMD_U32 ) + { + if( TermCnt != 2 ) + { Report(ps,REP_ERROR,"Expected 1 operand"); return(-1); } + return( StructAddElement( ps, pTerms[1], 4 ) ); + } + else if( i==DOTCMD_U16 ) + { + if( TermCnt != 2 ) + { Report(ps,REP_ERROR,"Expected 1 operand"); return(-1); } + return( StructAddElement( ps, pTerms[1], 2 ) ); + } + else if( i==DOTCMD_U8 ) + { + if( TermCnt != 2 ) + { Report(ps,REP_ERROR,"Expected 1 operand"); return(-1); } + return( StructAddElement( ps, pTerms[1], 1 ) ); + } + else if( i==DOTCMD_ASSIGN ) + { + if( TermCnt != 5 ) + { Report(ps,REP_ERROR,"Expected 4 operands"); return(-1); } + return( StructAssign(ps, pTerms[1], pTerms[2], pTerms[3], pTerms[4]) ); + } + else if( i==DOTCMD_SETCALLREG ) + { + PRU_ARG r; + + if( TermCnt != 2 ) + { Report(ps,REP_ERROR,"Expected 1 operand"); return(-1); } + if( Core == CORE_V0 ) + { Report(ps,REP_ERROR,".setcallreg illegal with specified core version"); return(-1); } + if( Pass==1 && (Options & OPTION_RETREGSET) ) + { Report(ps,REP_ERROR,".setcallreg redefinition"); return(-1); } + if( CodeOffset>=0 ) + { Report(ps,REP_ERROR,"Can not use .setcallreg after code generation"); return(-1); } + if( !GetRegister( ps, 1, pTerms[1], &r, 0, 0 ) ) + return -1; + + switch( r.Field ) + { + case FIELDTYPE_15_0: + case FIELDTYPE_23_8: + case FIELDTYPE_31_16: + if( r.Value<31 ) + { + RetRegValue = r.Value; + RetRegField = r.Field; + Options |= OPTION_RETREGSET; + return 0; + } + } + + Report(ps,REP_ERROR,"Register field must be r0 to r30 and 16 bits wide"); + return(-1); + } + else if( i==DOTCMD_ENTER ) + { + if( TermCnt != 2 ) + { Report(ps,REP_ERROR,"Expected 1 operand"); return(-1); } + return( ScopeEnter(ps, pTerms[1]) ); + } + else if( i==DOTCMD_LEAVE ) + { + if( TermCnt != 2 ) + { Report(ps,REP_ERROR,"Expected 1 operand"); return(-1); } + return( ScopeLeave(ps, pTerms[1]) ); + } + else if( i==DOTCMD_USING ) + { + if( TermCnt != 2 ) + { Report(ps,REP_ERROR,"Expected 1 operand"); return(-1); } + return( ScopeUsing(ps, pTerms[1]) ); + } + else if( i==DOTCMD_MACRO ) + { + if( TermCnt != 2 ) + { Report(ps,REP_ERROR,"Expected 1 operand"); return(-1); } + return( MacroEnter(ps, pTerms[1]) ); + } + else if( i==DOTCMD_MPARAM || i==DOTCMD_ENDM ) + { Report(ps,REP_ERROR,"%s can not be used outside of macro",pTerms[0]); return(-1); } + else if( i==DOTCMD_CODEWORD ) + { + uint opcode; + int tmp; + char tstr[TOKEN_MAX_LEN]; + + /* + // .codeword command + */ + if( TermCnt != 2 ) + { Report(ps,REP_ERROR,"Expected 1 operand"); return(-1); } + + strcpy( tstr, pTerms[1] ); + if( Expression(ps, tstr, &opcode, &tmp)<0 ) + { Report(ps,REP_ERROR,"Error in processing .codeword value"); return(-1); } + + GenOp( ps, TermCnt, pTerms, opcode ); + return(0); + } + + Report(ps,REP_ERROR,"Dot command - Internal Error"); + return(-1); +} + + +/* +// DotInitialize +// +// Open the dot-command environment +// +// void +*/ +void DotInitialize(int pass) +{ + StructInit(); +} + + + +/* +// DotCleanup +// +// Clean up the dot-command environment +// +// void +*/ +void DotCleanup(int pass) +{ + StructCleanup(); + MacroCleanup(); +} + + diff --git a/am335x/pasm/pasmexp.c b/am335x/pasm/pasmexp.c new file mode 100644 index 00000000..5b387096 --- /dev/null +++ b/am335x/pasm/pasmexp.c @@ -0,0 +1,585 @@ +/* + * pasmexp.c + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +/*=========================================================================== + * Copyright (c) Texas Instruments Inc 2010-12 + * + * Use of this software is controlled by the terms and conditions found in the + * license agreement under which this software has been supplied or provided. + * ============================================================================ + */ + +/*=========================================================================== +// PASM - PRU Assembler +//--------------------------------------------------------------------------- +// +// File : pasmexp.c +// +// Description: +// Expression analyzer. This module is a "drop in", and thus does't +// have much knowledge of the rest of the assembler. +// - Handles expression processing +// +// Note that the expression analyzer will only report errors on pass 2 +// +//--------------------------------------------------------------------------- +// Revision: +// 21-Jun-13: 0.84 - Open source version +============================================================================*/ + +#include +#include +#include +#if !defined(__APPLE__) +#include +#else +#include +#endif +#include +#include "pasm.h" + +#define MAXTERM 32 + +#define EOP_MULTIPLY 1 +#define EOP_DIVIDE 2 +#define EOP_MOD 3 +#define EOP_ADD 4 +#define EOP_SUBTRACT 5 +#define EOP_LEFTSHIFT 6 +#define EOP_RIGHTSHIFT 7 +#define EOP_AND 8 +#define EOP_XOR 9 +#define EOP_OR 10 + +uint prec[] = { 999, + 1, /* EOP_MULTIPLY */ + 1, /* EOP_DIVIDE */ + 1, /* EOP_MOD */ + 2, /* EOP_ADD */ + 2, /* EOP_SUBTRACT */ + 3, /* EOP_LEFTSHIFT */ + 3, /* EOP_RIGHTSHIFT */ + 4, /* EOP_AND */ + 5, /* EOP_XOR */ + 6 };/* EOP_OR */ + + +int EXP_getValue( SOURCEFILE *ps, char *s, int *pIdx, uint *pValue ); +int EXP_getOperation( SOURCEFILE *ps, char *s, int *pIdx, uint *pValue ); +static int GetRegisterOffset( char *src, uint *pValue ); + +/* +// Expression - Math Expression Parser +// +// Returns 0 on success, <0 on error +*/ +int Expression( SOURCEFILE *ps, char *s, uint *pResult, int *pIndex ) +{ + uint values[MAXTERM]; + uint ops[MAXTERM]; + int maxprec; + int i; + int validx,opidx,stridx; + + validx=0; + opidx=0; + stridx=0; + + while( validx= validx || !validx ) + return(-1); + + while( opidx ) + { + /* Find the highest prec op */ + maxprec = 0; + for( i=1; i> values[maxprec+1]; + break; + case EOP_AND: + values[maxprec] = values[maxprec] & values[maxprec+1]; + break; + case EOP_XOR: + values[maxprec] = values[maxprec] ^ values[maxprec+1]; + break; + case EOP_OR: + values[maxprec] = values[maxprec] | values[maxprec+1]; + break; + } + + // Remove this op and 2nd value term from the list + i = MAXTERM-2-maxprec; + if( i>0 ) + { + memcpy( &values[maxprec+1], &values[maxprec+2], i*sizeof(uint)); + memcpy( &ops[maxprec], &ops[maxprec+1], i*sizeof(uint)); + } + + opidx--; + validx--; + } + + if( validx != 1 ) + { Report(ps,REP_ERROR,"Exp internal error"); return(-1); } + + *pResult = values[0]; + return(0); +} + + +/* +// EXP_getValue - Get a value from the supplied string +// +// Returns 0 no value, 1 on success, <0 on error +*/ +int EXP_getValue( SOURCEFILE *ps, char *s, int *pIdx, uint *pValue ) +{ + int base = 10,index,i,j,k; + int rc = 1; + uint tval = 0; + char c; + + index = *pIdx; + + c = s[index]; + while( c==' ' || c==9 ) + { + index++; + c = s[index]; + } + + if( !c ) + return(0); + + /* Look for a label */ + if( LabelChar(c,1) || c=='.' || c=='&' ) + { + LABEL *pl; + char lblstr[LABEL_NAME_LEN]; + int lblidx = 0; + + for(;;) + { + lblstr[lblidx++]=c; + index++; + c = s[index]; + if( !LabelChar(c,0) && c!='.' ) + break; + } + lblstr[lblidx]=0; + *pIdx = index; + + if( CheckTokenType(lblstr) & TOKENTYPE_FLG_REG_ADDR ) + { + if( GetRegisterOffset(lblstr+1,&tval) ) + { + *pValue = tval; + return(1); + } + } + pl = LabelFind(lblstr); + if(!pl && Pass==1) + *pValue = 0; + else if( !pl ) + { Report(ps,REP_ERROR,"Not found: '%s'",lblstr); return(0); } + else + *pValue = pl->Offset; + return(1); + } + + if( c=='-' ) + { + index++; + i = EXP_getValue( ps, s, &index, &tval ); + if( i<0 ) + rc = i; + else + tval = (uint)(-(int)tval); + goto EGV_EXIT; + } + if( c=='~' ) + { + index++; + i = EXP_getValue( ps, s, &index, &tval ); + if( i<0 ) + rc = i; + else + tval = ~tval; + goto EGV_EXIT; + } + if( c=='(' ) + { + /* Scan to the far ')' */ + index++; + j = index; + i=1; + for(;;) + { + c = *(s+j); + if( !c ) + { + rc = -1; + goto EGV_EXIT; + } + if( c=='(' ) + i++; + if( c==')' ) + { + i--; + if(!i) + { + /* Terminate the string and eval the () */ + *(s+j) = 0; + i = Expression( 0, s+index, &tval, &k ); + if( i<0 ) + { + index+=k; + rc=i; + } + else + index=j+1; + goto EGV_EXIT; + } + } + j++; + } + } + + /* This character must be a number */ + if( c<'0' || c>'9' ) + { + rc = -1; + goto EGV_EXIT; + } + index++; + tval = c-'0'; + if( tval==0 ) + { + c = s[index]; + if( c=='x' ) + { + base=16; + index++; + } + else if( c=='b' ) + { + base=2; + index++; + } + else + base=8; + } + + for(;;) + { + c = s[index]; + if( c>='0' && c<='9' ) + i = c-'0'; + else if( c>='a' && c<='f' ) + i = c-'a'+10; + else if( c>='A' && c<='F' ) + i = c-'A'+10; + else + break; + + if( i>=base ) + { + rc = -1; + goto EGV_EXIT; + } + tval *= base; + tval += i; + index++; + } + +EGV_EXIT: + *pValue = tval; + *pIdx = index; + return(rc); +} + + +/* +// EXP_getOperation - Get an operation from the supplied string +// +// Returns 0 no value, 1 on success, <0 on error +*/ +int EXP_getOperation( SOURCEFILE *ps, char *s, int *pIdx, uint *pValue ) +{ + int index; + char c; + int rc = 1; + + index = *pIdx; + + c = s[index]; + while( c==' ' || c==9 ) + { + index++; + c = s[index]; + } + + if( !c ) + return(0); + else if( c=='*' ) + *pValue = EOP_MULTIPLY; + else if( c=='/' ) + *pValue = EOP_DIVIDE; + else if( c=='%' ) + *pValue = EOP_MOD; + else if( c=='+' ) + *pValue = EOP_ADD; + else if( c=='-' ) + *pValue = EOP_SUBTRACT; + else if( c=='<' ) + { + index++; + c = s[index]; + if( c != '<' ) + rc=-1; + else + *pValue = EOP_LEFTSHIFT; + } + else if( c=='>' ) + { + index++; + c = s[index]; + if( c != '>' ) + rc=-1; + else + *pValue = EOP_RIGHTSHIFT; + } + else if( c=='&' ) + *pValue = EOP_AND; + else if( c=='^' ) + *pValue = EOP_XOR; + else if( c=='|' ) + *pValue = EOP_OR; + else + rc = -1; + + if( rc == 1) + index++; + + *pIdx = index; + return(rc); +} + + +/* +// GetRegisterOffset +// +// Get Register Offset +// +// Returns: +// 1 : Success +// 0 : Error +*/ +static int GetRegisterOffset( char *src, uint *pValue ) +{ + uint idx; + char c,field; + int val,reg,width,offset; + + if( Core == CORE_V0 ) + return(0); + + /* + // The following register syntaxes are valid: + // Raa aa=(0-31) + // Raa.Wb aa=(0-31) b=(0-2) + // Raa.Bc aa=(0-31) c=(0-3) + // Raa.Tdd aa=(0-31) dd=(0-31) + // Raa.Wb.Be aa=(0-31) b=(0-2) e=(0-1) + */ + + idx=0; + c = src[idx++]; + /* Get initial 'R##' */ + if( toupper(c) != 'R' ) + return(0); + c = src[idx++]; + if( !isdigit(c) ) + return(0); + val = 0; + while( isdigit(c) ) + { + val *= 10; + val += c-'0'; + c = src[idx++]; + } + if( val>31 ) + return(0); + + reg = val; + width = 32; + offset = 0; + + for(;;) + { + /* This char must be '.', or terminator */ + + /* If terminated, we're done */ + if( !c ) + break; + if( c != '.' ) + return(0); + + c = src[idx++]; + + /* This char must be 'W', or 'B' */ + c = toupper(c); + if( c!='W' && c!='B' ) + return(0); + field=c; + c = src[idx++]; + if( !isdigit(c) ) + return(0); + val = 0; + while( isdigit(c) ) + { + val *= 10; + val += c-'0'; + c = src[idx++]; + } + if( field=='W' ) + { + if( ((val*8)+16)>width ) + return(0); + width = 16; + offset += val; + } + if( field=='B' ) + { + if( ((val*8)+8)>width ) + return(0); + width = 8; + offset += val; + } + } + + if( !(Options & OPTION_BIGENDIAN) ) + *pValue = reg * 4 + offset; + else + { + width /= 8; + offset = 4 - offset - width; + *pValue = reg * 4 + offset; + } + + return(1); +} + diff --git a/am335x/pasm/pasmmacro.c b/am335x/pasm/pasmmacro.c new file mode 100644 index 00000000..710a538c --- /dev/null +++ b/am335x/pasm/pasmmacro.c @@ -0,0 +1,560 @@ +/* + * pasmmacro.c + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +/*=========================================================================== + * Copyright (c) Texas Instruments Inc 2010-12 + * + * Use of this software is controlled by the terms and conditions found in the + * license agreement under which this software has been supplied or provided. + * ============================================================================ + */ + +/*=========================================================================== +// PASM - PRU Assembler +//--------------------------------------------------------------------------- +// +// File : pasmmacro.c +// +// Description: +// Processes the macro commands +// +//--------------------------------------------------------------------------- +// Revision: +// 21-Jun-13: 0.84 - Open source version +============================================================================*/ + +#include +#include +#include +#if !defined(__APPLE__) +#include +#else +#include +#endif +#include +#include "pasm.h" + +/* Local Macro Definitions */ + +#define MACRO_NAME_LEN TOKEN_MAX_LEN +#define MACRO_MAX_ARGS 8 +#define MACRO_MAX_LINES 128 +#define MACRO_LINE_LENGTH 256 +#define MACRO_MAX_LABELS 32 +#define MAX_SOURCE_LINE 256 + +/* Macro Struct Record */ +typedef struct _MACRO { + struct _MACRO *pPrev; /* Previous in MACRO list */ + struct _MACRO *pNext; /* Next in MACRO list */ + char Name[MACRO_NAME_LEN]; + int InUse; /* Macro is in use */ + int Id; /* Macro ID */ + int Arguments; /* Number of arguments */ + int Required; /* Number of required arguments */ + int Labels; /* Number of labels */ + int Expands; /* Number of label expansions */ + int CodeLines; /* Number of code lines */ + char ArgName[MACRO_MAX_ARGS][TOKEN_MAX_LEN]; + char ArgDefault[MACRO_MAX_ARGS][TOKEN_MAX_LEN]; + char LableName[MACRO_MAX_LABELS][TOKEN_MAX_LEN]; + char Code[MACRO_MAX_LINES][MACRO_LINE_LENGTH]; +} MACRO; + + +/* Local Support Funtions */ +static int _strncat( char *dst, int len, char *src ); +static MACRO *MacroFind( char *Name ); +static MACRO *MacroCreate( SOURCEFILE *ps, char *Name ); +int MacroAddArg( SOURCEFILE *ps, MACRO *pm, char *ArgText ); +static void MacroDestroy( MACRO *pm ); + +/* Local macro list */ +int MacroId=0; +MACRO *pMacroList=0; /* List of declared structs */ +MACRO *pMacroCurrent=0; + + +/*=================================================================== +// +// Public Functions +// +====================================================================*/ + +/* +// MacroEnter +// Returns: +// 0 - Success +// -1 - Error +*/ +int MacroEnter( SOURCEFILE *ps, char *Name ) +{ + SRCLINE sl; + MACRO *pm; + char src[MAX_SOURCE_LINE]; + int i; + + if( Core == CORE_V0 ) + { Report(ps,REP_ERROR,".macro illegal with specified core version"); return(-1); } + + /* Create the macro */ + pm = MacroCreate( ps, Name ); + if( !pm ) + return(-1); + + /* Scan source lines until we see .endm */ + for(;;) + { + /* Abort on a total disaster */ + if( FatalError || Errors >= 25 ) + return(-1); + + /* Get a line of source code */ + i = GetSourceLine( ps, src, MAX_SOURCE_LINE ); + if( !i ) + { Report(ps,REP_ERROR,"Missing .endm on macro"); return(-1); } + if( i<0 ) + continue; + + if( !ParseSourceLine(ps,i,src,&sl) ) + continue; + + /* Check for a label */ + if( sl.Flags & SRC_FLG_LABEL ) + { + if( pm->Labels==MACRO_MAX_LABELS ) + Report(ps,REP_ERROR,"Macro contains too many labels"); + else + { + strcpy( pm->LableName[pm->Labels], sl.Label ); + pm->Labels++; + } + } + + /* Check for a macro related dot command */ + if( sl.Terms && (sl.Flags & SRC_FLG_DOTCMD1) ) + { + if( !stricmp( sl.Term[0], ".mparam" ) ) + { + if( sl.Terms==1 ) + { Report(ps,REP_ERROR,"Expected at least 1 parameter on .mparam"); continue; } + for( i=1; i<(int)sl.Terms; i++) + MacroAddArg(ps,pm,sl.Term[i]); + continue; + } + else if( !stricmp( sl.Term[0], ".macro" ) ) + { Report(ps,REP_ERROR,"Macro definitions may not be nested"); continue; } + else if( !stricmp( sl.Term[0], ".endm" ) ) + { + pm->InUse = 0; + return(0); + } + } + /* Else store the line as part of the macro */ + else + { + if( pm->CodeLines == MACRO_MAX_LINES ) + { Report(ps,REP_ERROR,"Macro line count exceeded"); continue; } + strcpy(pm->Code[pm->CodeLines],src); + pm->CodeLines++; + } + } +} + + +/* +// ProcessMacro +// +// ps - Pointer to source file record +// TermCnt - Number of terms (including the command) +// pTerms - Pointer to the terms +// +// Returns: +// 1 : Success +// 0 : Error +*/ +int ProcessMacro( SOURCEFILE *ps, int TermCnt, char **pTerms ) +{ + MACRO *pm; + int cidx,sidx,nidx,i; + char src[MAX_SOURCE_LINE]; + char namebuf[MACRO_NAME_LEN]; + char c; + + pm = MacroFind(pTerms[0]); + if( !pm ) + return(0); + + if( pm->InUse ) + { Report(ps,REP_ERROR,"Illegal recursive use of macro '%s'",pTerms[0]); return(0); } + + if( pm->Required >= TermCnt ) + { Report(ps,REP_ERROR,"Expected at least %d arguments on '%s'",pm->Required,pTerms[0]); return(0); } + + if( pm->Arguments < (TermCnt-1) ) + { Report(ps,REP_ERROR,"Expected no more than %d arguments on '%s'",pm->Arguments,pTerms[0]); return(0); } + + /* Bump expansion count */ + pm->Expands++; + pm->InUse = 1; + + for( cidx=0; cidxCodeLines; cidx++ ) + { + /* Build the assembly statement */ + sidx=0; + nidx=0; + src[0] = 0; + for(;;) + { + c=pm->Code[cidx][sidx++]; + /* Check for start of name */ + if( !nidx ) + { + if(LabelChar(c,1)) + { + namebuf[nidx++]=c; + continue; + } + } + /* Else continue a previously started name */ + else + { + if(LabelChar(c,0)) + { + /* Check for name too long */ + if( nidx==(MACRO_NAME_LEN-1) ) + { Report(ps,REP_ERROR,"Term too long in macro assembly text"); pm->InUse=0; return(0); } + namebuf[nidx++]=c; + continue; + } + + /* This name is done */ + namebuf[nidx]=0; + + /* Look for an argument match */ + for(i=0;iArguments;i++) + { + if(!strcmp(namebuf,pm->ArgName[i])) + { + /* Match! */ + if( (i+1)>=TermCnt ) + _strncat( src, MAX_SOURCE_LINE, pm->ArgDefault[i] ); + else + _strncat( src, MAX_SOURCE_LINE, pTerms[i+1] ); + goto SUBTEXTDONE; + } + } + + /* Look for a label match */ + for(i=0;iLabels;i++) + { + if(!strcmp(namebuf,pm->LableName[i])) + { + char labeltext[TOKEN_MAX_LEN+32]; + + /* Match! */ + sprintf(labeltext,"_%s_%d_%d_", pm->LableName[i],pm->Id,pm->Expands); + _strncat( src, MAX_SOURCE_LINE, labeltext ); + goto SUBTEXTDONE; + } + } + + /* Sub in the original text */ + _strncat( src, MAX_SOURCE_LINE, namebuf ); +SUBTEXTDONE: + nidx = 0; + } + /* Check for text too long */ + i=strlen(src); + if( i==(MAX_SOURCE_LINE-1) ) + { Report(ps,REP_ERROR,"Macro expansion too long"); pm->InUse=0; return(0); } + src[i++]=c; + src[i]=0; + if( !c ) + break; + } + + i=strlen(src); + if(i) + { + if( !ProcessSourceLine(ps, i, src) ) + { + Report(ps,REP_ERROR,"(While expanding code line %d of macro '%s')",(cidx+1),pm->Name); + pm->InUse=0; + return(0); + } + } + } + pm->InUse = 0; + return(1); +} + + +/* +// MacroCleanup +// +// Returns: void +*/ +void MacroCleanup() +{ + while( pMacroList ) + MacroDestroy( pMacroList ); + MacroId = 0; +} + +/* +// CheckMacro +// +// Searches for an macro by name. +// +// Returns 1 on success, 0 on error +*/ +int CheckMacro( char *name ) +{ + if( MacroFind(name) ) + return(1); + return(0); +} + + + +/*=================================================================== +// +// Private Functions +// +====================================================================*/ + +static int _strncat( char *dst, int len, char *src ) +{ + int sidx,didx; + + didx = 0; + while( didx(len-1) ) + return(-1); + sidx = 0; + while( src[sidx] ) + { + if( didx>(len-1) ) + { + dst[didx] = 0; + return(-1); + } + dst[didx++] = src[sidx++]; + } + dst[didx] = 0; + return(didx); +} + + +/* +// MacroFind +// +// Searches for a macro record by name. If found, returns the record pointer. +// +// Returns MACRO * on success, 0 on error +*/ +static MACRO *MacroFind( char *Name ) +{ + MACRO *pm; + + pm = pMacroList; + while( pm ) + { + if( !strcmp( Name, pm->Name ) ) + break; + pm = pm->pNext; + } + return(pm); +} + + +/* +// MacroCreate +// +// Create a new macro record +// +// Returns MACRO * on success, 0 on error +*/ +static MACRO *MacroCreate( SOURCEFILE *ps, char *Name ) +{ + MACRO *pm; + + /* Make sure this name is OK to use */ + if( !CheckName(ps,Name) ) + return(0); + + /* Make sure its not too long */ + if( strlen(Name)>=MACRO_NAME_LEN ) + { Report(ps,REP_ERROR,"Macro name too long"); return(0); } + + /* Allocate a new record */ + pm = malloc(sizeof(MACRO)); + if( !pm ) + { Report(ps,REP_ERROR,"Memory allocation failed"); return(0); } + + strcpy( pm->Name, Name ); + pm->InUse = 1; + pm->Id = MacroId++; + pm->Arguments = 0; + pm->Required = 0; + pm->CodeLines = 0; + pm->Labels = 0; + pm->Expands = 0; + + /* Put this equate in the master list */ + pm->pPrev = 0; + pm->pNext = pMacroList; + pMacroList = pm; + + if( Pass==1 && (Options & OPTION_DEBUG) ) + printf("%s(%5d) : DOTCMD : Macro '%s' declared\n", + ps->SourceName,ps->CurrentLine,pm->Name); + + return(pm); +} + + +/* +// MacroAddArg +// +// Add an argument to a macro record +// +// Returns 0 on success, -1 on error +*/ +int MacroAddArg( SOURCEFILE *ps, MACRO *pm, char *ArgText ) +{ + int i,sidx; + + if( Pass==1 && (Options & OPTION_DEBUG) ) + printf("%s(%5d) : DOTCMD : Macro Parameter '%s' declared\n", + ps->SourceName,ps->CurrentLine,ArgText); + + if( pm->Arguments == MACRO_MAX_ARGS ) + { Report(ps,REP_ERROR,"Too many macro arguments"); return(-1); } + + /* Scan in the argument */ + sidx=0; + while( ArgText[sidx]==' ' || ArgText[sidx]==9 ) + sidx++; + i=0; + while( ArgText[sidx]!=' ' && ArgText[sidx]!=9 && ArgText[sidx]!='=' && ArgText[sidx]!=0 ) + { + if(i==TOKEN_MAX_LEN) + { Report(ps,REP_ERROR,"Macro argument name too long"); return(-1); } + if( (i==0 && !LabelChar(ArgText[sidx],1)) || + (i!=0 && !LabelChar(ArgText[sidx],0)) ) + { Report(ps,REP_ERROR,"Illegal character in macro argument name"); return(-1); } + pm->ArgName[pm->Arguments][i++] = ArgText[sidx++]; + } + pm->ArgName[pm->Arguments][i] = 0; + if( !i ) + goto MARG_SYNTAX; + + /* Verify no duplicate naming */ + for(i=0; iArguments; i++) + { + if( !strcmp(pm->ArgName[i],pm->ArgName[pm->Arguments]) ) + { + Report(ps,REP_ERROR,"Duplicate macro argument name '%s'",pm->ArgName[i]); + return(-1); + } + } + + /* Scan in the default value (if any) */ + while( ArgText[sidx]==' ' || ArgText[sidx]==9 ) + sidx++; + + if( ArgText[sidx]=='=' ) + { + sidx++; + while( ArgText[sidx]==' ' || ArgText[sidx]==9 ) + sidx++; + i=0; + while( ArgText[sidx]!=' ' && ArgText[sidx]!=9 && ArgText[sidx]!='=' && ArgText[sidx]!=0 ) + { + if(i==TOKEN_MAX_LEN) + { Report(ps,REP_ERROR,"Macro argument value too long"); return(-1); } + if( !LabelChar(ArgText[sidx],0) && ArgText[sidx]!='.' ) + goto MARG_SYNTAX; + pm->ArgDefault[pm->Arguments][i++] = ArgText[sidx++]; + } + pm->ArgDefault[pm->Arguments][i] = 0; + if( !i ) + goto MARG_SYNTAX; + pm->Arguments++; + } + else + { + pm->ArgDefault[pm->Arguments][0] = 0; + if(pm->Arguments > pm->Required) + { Report(ps,REP_ERROR,"Optional macro arguments must be listed last"); return(-1); } + pm->Arguments++; + pm->Required++; + } + + if( ArgText[sidx]!=0 ) + { +MARG_SYNTAX: + Report(ps,REP_ERROR,"Syntax error in macro argument '%s' around character %d",ArgText,sidx+1); + return(-1); + } + + return(0); +} + + +/* +// MacroDestroy +// +// Frees a macro record. +// +// void +*/ +static void MacroDestroy( MACRO *pm ) +{ + if( !pm->pPrev ) + pMacroList = pm->pNext; + else + pm->pPrev->pNext = pm->pNext; + + if( pm->pNext ) + pm->pNext->pPrev = pm->pPrev; + + free(pm); +} + diff --git a/am335x/pasm/pasmop.c b/am335x/pasm/pasmop.c new file mode 100644 index 00000000..617c37c4 --- /dev/null +++ b/am335x/pasm/pasmop.c @@ -0,0 +1,2132 @@ +/* + * pasmop.c + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +/*=========================================================================== + * Copyright (c) Texas Instruments Inc 2010-12 + * + * Use of this software is controlled by the terms and conditions found in the + * license agreement under which this software has been supplied or provided. + * ============================================================================ + */ + +/*=========================================================================== +// PASM - PRU Assembler +//--------------------------------------------------------------------------- +// +// File : pasmop.c +// +// Description: +// Handles the processing of PRU opcodes. +// - Provides a function to test for reserved words +// - Processes assembly lines and generates opcodes +// - Contains private functions to process operand fields +// +//--------------------------------------------------------------------------- +// Revision: +// 21-Jun-13: 0.84 - Open source version +============================================================================*/ + +#include +#include +#include +#if !defined(__APPLE__) +#include +#else +#include +#endif +#include +#include "pasm.h" + +char *OpText[] = { + "$ERROR$","ADD","ADC","SUB","SUC","LSL","LSR","RSB","RSC","AND","OR", + "XOR","NOT","MIN","MAX","CLR","SET","LDI","LBBO","LBCO","SBBO", + "SBCO","LFC","STC","JAL","JMP","QBGT","QBLT","QBEQ","QBGE","QBLE", + "QBNE","QBA","QBBS","QBBC","LMBD","CALL","WBC","WBS","MOV","MVIB", + "MVIW","MVID","SCAN","HALT","SLP", "RET", "ZERO", "FILL", "XIN", "XOUT", + "XCHG","SXIN","SXOUT","SXCHG","LOOP","ILOOP","NOP0","NOP1","NOP2","NOP3", + "NOP4","NOP5","NOP6","NOP7","NOP8","NOP9","NOPA","NOPB","NOPC","NOPD", + "NOPE","NOPF"}; + +/* Local Support Funtions */ +static int GetImValue( SOURCEFILE *ps, int num, char *src, PRU_ARG *pa, uint low, uint high ); +static int GetConstant( SOURCEFILE *ps, int num, char *src, PRU_ARG *pa ); +static int GetR0offset( SOURCEFILE *ps, int num, char *src, PRU_ARG *pa ); +static int GetJmpOffset( SOURCEFILE *ps, int num, char *src, PRU_ARG *pa ); +static int GetLoopOffset( SOURCEFILE *ps, int num, char *src, PRU_ARG *pa ); +static int Offset2Reg( SOURCEFILE *ps, int num, PRU_ARG *pa, uint addr, uint size ); + +/* +// CheckOpcode +// +// Called to see if the supplied token is an opcode. +// +// Returns index of opcode, 0 if not an opcode +*/ +int CheckOpcode( char *word ) +{ + int i; + + for(i=1; i<=OP_MAXIDX; i++) + { + if( !stricmp( word, OpText[i] ) ) + return(i); + } + return(0); +} + + +/* +// GetTokenType +// +// Called to see if the supplied token is reserved word. +// +// Returns 1 if reserved, 0 if not +*/ +uint CheckTokenType( char *word ) +{ + int i,parse_state; + uint flags; + char c; + + /* Opcodes are reserved */ + if( CheckOpcode(word) ) + return(TOKENTYPE_FLG_OPCODE); + + /* Check for command */ + if( CheckDotCommand( word ) ) + return(TOKENTYPE_FLG_DIRECTIVE); + + if( !strcmp(word,"SIZE") || !strcmp(word,"OFFSET") ) + return(TOKENTYPE_FLG_DIRECTIVE); + + /* + // [&,*][--](B,C,R,T,W)#[#][.(B,C,R,T,W)#[#]][++ ] is reserved + // + // For example: + // R - not reserved + // R23 - reserved + // R100 - not reserved + // C34.XYZ - not reserved + // C34.T34 - reserved + */ + i=0; + parse_state=0; + + if( word[i]=='*' ) + { + /* Mark as a pointer */ + flags = TOKENTYPE_FLG_REG_PTR; + i++; + + /* Check if its an immediate address */ + if( word[i]=='&' ) + { + flags |= TOKENTYPE_FLG_REG_ADDR; + i++; + } + /* Else its a register base */ + else + { + flags |= TOKENTYPE_FLG_REG_BASE; + + /* Registers can also be pre-dec */ + if( word[i]=='-' ) + { + if( word[i+1]!='-' ) + return(TOKENTYPE_UNRESERVED); + i+=2; + flags |= TOKENTYPE_FLG_REG_PREDEC; + } + } + } + else if( word[i]=='&' ) + { + flags = TOKENTYPE_FLG_REG_ADDR; + i++; + } + else + flags = TOKENTYPE_FLG_REG_BASE; + + for(;;) + { + c = word[i++]; + c = toupper(c); + switch( parse_state ) + { + case 0: + if( c=='B' || c=='C' || c=='R' || c=='T' || c=='W' ) + parse_state=1; + else + return(TOKENTYPE_UNRESERVED); + break; + + case 1: + if( isdigit(c) ) + parse_state=2; + else + return(TOKENTYPE_UNRESERVED); + break; + + case 2: + case 3: + if( isdigit(c) ) + { + parse_state++; + if( parse_state>3 ) + return(TOKENTYPE_UNRESERVED); + } + else if( c=='.' ) + parse_state=0; + else if( !c || c==' ' || c==0x9 ) + return(flags); + else if( c=='+' ) + { + /* Can not be an address or predec */ + if( flags & (TOKENTYPE_FLG_REG_ADDR|TOKENTYPE_FLG_REG_PREDEC) ) + return(TOKENTYPE_UNRESERVED); + + /* Rest of type must match */ + if( word[i]!=c || word[i+1]!=0 ) + return(TOKENTYPE_UNRESERVED); + + flags |= TOKENTYPE_FLG_REG_POSTINC; + return(flags); + } + else + return(TOKENTYPE_UNRESERVED); + break; + } + } +} + +/* +// ProcessOp +// +// Opcode processor +// +// This is the function that assembles opcode statements +// +// ps - Pointer to source file record +// TermCnt - Number of terms (including the command) +// pTerms - Pointer to the terms +// +// Returns: +// 1 : Success +// 0 : Error +*/ +int ProcessOp( SOURCEFILE *ps, int TermCnt, char **pTerms ) +{ + PRU_INST inst; + unsigned int opcode; + unsigned int utmp; + + /* Get opcode */ + inst.Op = CheckOpcode(pTerms[0]); + + if( !inst.Op ) + { Report(ps,REP_ERROR,"Invalid opcode"); return(0); } + + switch( inst.Op ) + { + case OP_NOT: + /* + // Instruction in the form of: + // NOT Rdst, Rsrc, OP(255) + // NOT Rdst, Rsrc + */ + if( TermCnt!=3 && TermCnt!=4 ) + { Report(ps,REP_ERROR,"Expected 2 or 3 operands on NOT"); return(0); } + goto PARSE_ARITHMETIC; + case OP_ADD: + case OP_ADC: + case OP_SUB: + case OP_SUC: + case OP_LSL: + case OP_LSR: + case OP_RSB: + case OP_RSC: + case OP_AND: + case OP_OR: + case OP_XOR: + case OP_MIN: + case OP_MAX: + case OP_LMBD: + case OP_NOP0: + case OP_NOP1: + case OP_NOP2: + case OP_NOP3: + case OP_NOP4: + case OP_NOP5: + case OP_NOP6: + case OP_NOP7: + case OP_NOP8: + case OP_NOP9: + case OP_NOPA: + case OP_NOPB: + case OP_NOPC: + case OP_NOPD: + case OP_NOPE: + case OP_NOPF: + /* + // Instruction in the form of: + // OPCODE Rdst, Rsrc, OP(255) + */ + if( inst.Op==OP_LMBD && Core=OP_NOP0 && inst.Op<=OP_NOPF && Core=OP_NOP0 && inst.Op<=OP_NOPF ) + opcode = (0x50+inst.Op-OP_NOP0) << 25; + else if( inst.Op == OP_LMBD ) + opcode = 0x13 << 25; + else if( inst.Op == OP_SCAN ) + opcode = 0x14 << 25; + else + opcode = (inst.Op-OP_ADD) << 25; + opcode |= inst.Arg[0].Value; + opcode |= inst.Arg[0].Field << 5; + opcode |= inst.Arg[1].Value << 8; + opcode |= inst.Arg[1].Field << 13; + if( inst.Arg[2].Type == ARGTYPE_REGISTER ) + { + opcode |= inst.Arg[2].Value << 16; + opcode |= inst.Arg[2].Field << 21; + } + else + { + opcode |= inst.Arg[2].Value << 16; + opcode |= 1<<24; + } + GenOp( ps, TermCnt, pTerms, opcode ); + return(1); + + + case OP_CLR: + case OP_SET: + /* + // Instruction in the form of: + // OPCODE Rdst, Rsrc, OP(255) -or- + // OPCODE Rdst, Rsrc.Tnn -or- + // OPCODE Rdst, OP(255) -or- + // OPCODE Rdst.Tnn + */ + if( TermCnt<2 || TermCnt>4 ) + { Report(ps,REP_ERROR,"Expected 1 to 3 operands"); return(0); } + + /* The 3 argument (4 term) variant can be parsed as arithmetic */ + if( TermCnt==4 ) + goto PARSE_ARITHMETIC; + else if( TermCnt==2 ) + { + /* + // Hande "OPCODE Rdst.Tnn" + */ + if( !GetRegister( ps, 1, pTerms[1], &(inst.Arg[0]), 1, 0 ) ) + return(0); + if( inst.Arg[0].Type != ARGTYPE_REGISTERBIT ) + { Report(ps,REP_ERROR,"Single operand mode must specify .T field"); return(0); } + /* 2nd arg = 1st arg, move bit# to 3rd arg */ + inst.Arg[0].Type = ARGTYPE_REGISTER; + inst.Arg[1] = inst.Arg[0]; + inst.Arg[2].Type = ARGTYPE_IMMEDIATE; + inst.Arg[2].Value = inst.Arg[0].Bit; + } + else + { + /* + // Handle "OPCODE Rdst, Rsrc.Tnn", and + // "OPCODE Rdst, OP(255)" + */ + if( !GetRegister( ps, 1, pTerms[1], &(inst.Arg[0]), 0, 0 ) ) + return(0); + if( CheckTokenType(pTerms[2]) & TOKENTYPE_FLG_REG_BASE ) + { + if( !GetRegister( ps, 2, pTerms[2], &(inst.Arg[1]), 1, 0 ) ) + return(0); + } + else + { + if( !GetImValue( ps, 2, pTerms[2], &(inst.Arg[1]), 0, 31 ) ) + return(0); + } + + /* Patch up the args to the standard "arithmetic" form */ + if( inst.Arg[1].Type == ARGTYPE_REGISTERBIT ) + { + /* Here the 2nd arg is Rsrc.Tnn, move bit# to 3rd arg */ + inst.Arg[1].Type = ARGTYPE_REGISTER; + inst.Arg[2].Type = ARGTYPE_IMMEDIATE; + inst.Arg[2].Value = inst.Arg[1].Bit; + } + else + { + /* Here the 2nd arg is OP(255), 3rd arg = 2nd arg, 2nd=1st */ + inst.Arg[2] = inst.Arg[1]; + inst.Arg[1] = inst.Arg[0]; + } + } + goto CODE_ARITHMETIC; + + + case OP_LDI: + /* + // Instruction in the form of: + // LDI Rdst, &Rsrc + // LDI Rdst, #Im65535 + */ + if( TermCnt != 3 ) + { Report(ps,REP_ERROR,"Expected 2 operands"); return(0); } + if( !GetRegister( ps, 1, pTerms[1], &(inst.Arg[0]), 0, 0 ) ) + { + return(0); + } + if( !GetImValue( ps, 2, pTerms[2], &(inst.Arg[1]), 0, 65535 ) ) + { + return(0); + } + opcode = 0x24 << 24; + opcode |= inst.Arg[0].Value; + opcode |= inst.Arg[0].Field << 5; + opcode |= inst.Arg[1].Value << 8; + GenOp( ps, TermCnt, pTerms, opcode ); + return(1); + + + case OP_MOV: + /* + // Instruction in the form of: + // MOV Rdst, Rsrc -or- + // MOV Rdst, &Rsrc -or- + // MOV Rdst, #Imm + */ + if( TermCnt != 3 ) + { Report(ps,REP_ERROR,"Expected 2 operands"); return(0); } + /* If the second term is not reg, treat similar to LDI */ + if( !(CheckTokenType(pTerms[2]) & TOKENTYPE_FLG_REG_BASE) ) + { + // Unlike LDI, we will auto-select the best opcodes to implement the move + if( !GetRegister( ps, 1, pTerms[1], &(inst.Arg[0]), 0, 0 ) ) + { + return(0); + } + + switch( inst.Arg[0].Field ) + { + case FIELDTYPE_7_0: + case FIELDTYPE_15_8: + case FIELDTYPE_23_16: + case FIELDTYPE_31_24: + if( !GetImValue( ps, 2, pTerms[2], &(inst.Arg[1]), 0, 255 ) ) + return(0); + break; + case FIELDTYPE_15_0: + case FIELDTYPE_23_8: + case FIELDTYPE_31_16: + if( !GetImValue( ps, 2, pTerms[2], &(inst.Arg[1]), 0, 65535 ) ) + return(0); + break; + case FIELDTYPE_31_0: + if( !GetImValue( ps, 2, pTerms[2], &(inst.Arg[1]), 0, 0xFFFFFFFF ) ) + return(0); + // If the value is greater than 0xFFFF, code the upper half here + if( inst.Arg[1].Value > 0xFFFF ) + { + opcode = 0x24 << 24; + opcode |= inst.Arg[0].Value; + opcode |= FIELDTYPE_31_16 << 5; + opcode |= (inst.Arg[1].Value>>16) << 8; + GenOp( ps, TermCnt, pTerms, opcode ); + inst.Arg[0].Field = FIELDTYPE_15_0; + inst.Arg[1].Value &= 0xFFFF; + } + break; + default: + return(0); + } + opcode = 0x24 << 24; + opcode |= inst.Arg[0].Value; + opcode |= inst.Arg[0].Field << 5; + opcode |= inst.Arg[1].Value << 8; + GenOp( ps, TermCnt, pTerms, opcode ); + return(1); + } + if( !GetRegister( ps, 1, pTerms[1], &(inst.Arg[0]), 0, 0 ) ) + return(0); + if( !GetRegister( ps, 2, pTerms[2], &(inst.Arg[1]), 0, 0 ) ) + return(0); + /* Code as an AND */ + inst.Op = OP_AND; + inst.Arg[2] = inst.Arg[1]; + goto CODE_ARITHMETIC; + + + case OP_SCAN: + /* + // Instruction in the form of: + // SCAN Rdst, OP(255) + */ + if( Core!=CORE_V1 ) + { Report(ps,REP_ERROR,"Instruction illegal with specified core version"); return(0); } + if( TermCnt!=3 ) + { Report(ps,REP_ERROR,"Expected 2 operands"); return(0); } + if( !GetRegister( ps, 1, pTerms[1], &(inst.Arg[0]), 0, 0 ) ) + return(0); + if( inst.Arg[0].Field != FIELDTYPE_31_0 ) + { Report(ps,REP_ERROR,"Register fields not allowed on operand 1"); return(0); } + inst.Arg[1] = inst.Arg[0]; + if( CheckTokenType(pTerms[2]) & TOKENTYPE_FLG_REG_BASE ) + { + if( !GetRegister( ps, 2, pTerms[2], &(inst.Arg[2]), 0, 0 ) ) + return(0); + } + else + { + if( !GetImValue( ps, 2, pTerms[2], &(inst.Arg[2]), 0, 255 ) ) + return(0); + } + goto CODE_ARITHMETIC; + + case OP_MVIB: + /* + // Instruction in the form of: + // MVIB [*][&][--]Rdst[++], [*][&][--]Rsrc[++] [, bn] + */ + utmp = 1; + goto CODE_MVI; + case OP_MVIW: + /* + // Instruction in the form of: + // MVIW [*][&][--]Rdst[++], [*][&][--]Rsrc[++] [, bn] + */ + utmp = 2; + goto CODE_MVI; + case OP_MVID: + /* + // Instruction in the form of: + // MVID [*][&][--]Rdst[++], [*][&][--]Rsrc[++] [, bn] + */ + utmp = 4; +CODE_MVI: + if( Core=4 && (inst.Arg[0].Value!=1 || inst.Arg[0].Field>FIELDTYPE_31_24)) || + (itype%4 && (inst.Arg[1].Value!=1 || inst.Arg[1].Field>FIELDTYPE_31_24)) ) + { Report(ps,REP_ERROR,"RegFile pointers must be R1.b0 through R1.b3"); return(0); } + + if( itype==0 ) + { Report(ps,REP_ERROR,"No indirection specified (use MOV)"); return(0); } + + opcode = 0x16 << 25; + opcode |= itype << 21; + if( TermCnt==4 ) + { + opcode |= 1 << 20; + opcode |= inst.Arg[2].Value << 18; + } + opcode |= (utmp/2) << 16; + opcode |= inst.Arg[0].Value; + opcode |= inst.Arg[0].Field << 5; + opcode |= inst.Arg[1].Value << 8; + opcode |= inst.Arg[1].Field << 13; + } + GenOp( ps, TermCnt, pTerms, opcode ); + return(1); + + case OP_HALT: + if( Core>2) & 0x1F; + opcode |= (inst.Arg[0].Value&0x3) << 5; + } + else + { + opcode |= inst.Arg[0].Value; + + if( !(Options & OPTION_BIGENDIAN) ) + { + /* + // ** Little Endian Version ** + */ + switch( inst.Arg[0].Field ) + { + case FIELDTYPE_15_8: + case FIELDTYPE_23_8: + opcode |= 1<<5; + break; + case FIELDTYPE_23_16: + case FIELDTYPE_31_16: + opcode |= 2<<5; + break; + case FIELDTYPE_31_24: + opcode |= 3<<5; + break; + } + } + else + { + /* + // ** Big Endian Version ** + */ + switch( inst.Arg[0].Field ) + { + case FIELDTYPE_23_16: + case FIELDTYPE_23_8: + opcode |= 1<<5; + break; + + case FIELDTYPE_15_0: + case FIELDTYPE_15_8: + opcode |= 2<<5; + break; + + case FIELDTYPE_7_0: + opcode |= 3<<5; + break; + } + } + } + + opcode |= inst.Arg[1].Value << 8; + if( inst.Arg[2].Type == ARGTYPE_REGISTER ) + { + opcode |= inst.Arg[2].Value << 16; + opcode |= inst.Arg[2].Field << 21; + } + else + { + opcode |= inst.Arg[2].Value << 16; + opcode |= 1<<24; + } + if( inst.Arg[3].Type == ARGTYPE_R0BYTE ) + utmp = inst.Arg[3].Value + 124; + else + utmp = inst.Arg[3].Value - 1; + opcode |= (utmp&0x70)<<(25-4); + opcode |= (utmp&0x0E)<<(13-1); + opcode |= (utmp&0x01)<<7; + GenOp( ps, TermCnt, pTerms, opcode ); + return(1); + + case OP_SXIN: + opcode = (0x5D << 23) | (1 << 14); + goto CODE_XFR_V3; + + case OP_SXOUT: + opcode = (0x5E << 23) | (1 << 14); + goto CODE_XFR_V3; + + case OP_SXCHG: + opcode = (0x5F << 23) | (1 << 14); + goto CODE_XFR_V3; + + case OP_XIN: + opcode = 0x5D << 23; + goto CODE_XFR; + + case OP_XOUT: + opcode = 0x5E << 23; + goto CODE_XFR; + + case OP_XCHG: + opcode = 0x5F << 23; + goto CODE_XFR; + +CODE_XFR_V3: + if( Core>2) & 0x1F; + opcode |= (inst.Arg[1].Value&0x3) << 5; + } + else + { + opcode |= inst.Arg[1].Value; + + if( !(Options & OPTION_BIGENDIAN) ) + { + /* + // ** Little Endian Version ** + */ + switch( inst.Arg[1].Field ) + { + case FIELDTYPE_15_8: + case FIELDTYPE_23_8: + opcode |= 1<<5; + break; + case FIELDTYPE_23_16: + case FIELDTYPE_31_16: + opcode |= 2<<5; + break; + case FIELDTYPE_31_24: + opcode |= 3<<5; + break; + } + } + else + { + /* + // ** Big Endian Version ** + */ + switch( inst.Arg[1].Field ) + { + case FIELDTYPE_23_16: + case FIELDTYPE_23_8: + opcode |= 1<<5; + break; + + case FIELDTYPE_15_0: + case FIELDTYPE_15_8: + opcode |= 2<<5; + break; + + case FIELDTYPE_7_0: + opcode |= 3<<5; + break; + } + } + } + + opcode |= inst.Arg[0].Value << 15; + if( inst.Arg[2].Type == ARGTYPE_R0BYTE ) + utmp = inst.Arg[2].Value + 124; + else + utmp = inst.Arg[2].Value - 1; + opcode |= utmp<<7; + GenOp( ps, TermCnt, pTerms, opcode ); + return(1); + + + case OP_LFC: + /* + // Instruction in the form of: + // LFC Rdst, #Im255 + */ + if( Core!=CORE_V0 ) + { Report(ps,REP_ERROR,"Instruction illegal with specified core version"); return(0); } + if( TermCnt != 3 ) + { Report(ps,REP_ERROR,"Expected 2 operands"); return(0); } + if( !GetRegister( ps, 1, pTerms[1], &(inst.Arg[0]), 0, 0 ) ) + return(0); + if( !GetImValue( ps, 2, pTerms[2], &(inst.Arg[1]), 0, 255 ) ) + return(0); + + opcode = 0xb << 28; + opcode |= inst.Arg[0].Value; + opcode |= inst.Arg[0].Field << 5; + opcode |= inst.Arg[1].Value << 8; + opcode |= 1 << 24; + GenOp( ps, TermCnt, pTerms, opcode ); + return(1); + + + case OP_STC: + /* + // Instruction in the form of: + // STC Rsrc, #Im255 + // STC Rsrc, #Im255, OP(255) + */ + if( Core!=CORE_V0 ) + { Report(ps,REP_ERROR,"Instruction illegal with specified core version"); return(0); } + if( TermCnt!=3 && TermCnt!=4 ) + { Report(ps,REP_ERROR,"Expected 2 or 3 operands"); return(0); } + if( !GetRegister( ps, 1, pTerms[1], &(inst.Arg[0]), 0, 0 ) ) + return(0); + if( !GetImValue( ps, 2, pTerms[2], &(inst.Arg[1]), 0, 255 ) ) + return(0); + if( TermCnt==4 ) + { + if( CheckTokenType(pTerms[3]) & TOKENTYPE_FLG_REG_BASE ) + { + if( !GetRegister( ps, 3, pTerms[3], &(inst.Arg[2]), 0, 0 ) ) + return(0); + } + else + { + if( !GetImValue( ps, 3, pTerms[3], &(inst.Arg[2]), 0, 255 ) ) + return(0); + } + } + + opcode = 0xa << 28; + opcode |= inst.Arg[0].Value; + opcode |= inst.Arg[0].Field << 5; + opcode |= inst.Arg[1].Value << 8; + if( TermCnt==4 ) + { + if( inst.Arg[2].Type == ARGTYPE_REGISTER ) + { + opcode |= inst.Arg[2].Value << 16; + opcode |= inst.Arg[2].Field << 21; + } + else + { + opcode |= inst.Arg[2].Value << 16; + opcode |= 1<<24; + } + } + else + { + /* When a 32 bit reg is used, we need the 8 MS bits from that reg */ + if( inst.Arg[0].Field==FIELDTYPE_31_0 ) + { + opcode |= inst.Arg[0].Value << 16; + opcode |= FIELDTYPE_31_24 << 21; + } + /* Less than 32 bits were used, so clear the 8 MS bits via #0 */ + else + opcode |= 1<<24; + } + + GenOp( ps, TermCnt, pTerms, opcode ); + return(1); + + + case OP_JAL: + /* + // Instruction in the form of: + // JAL Rdst, Rjmp + // JAL Rdst, #Im65535 + */ + if( TermCnt != 3 ) + { Report(ps,REP_ERROR,"Expected 2 operands"); return(0); } + if( !GetRegister( ps, 1, pTerms[1], &(inst.Arg[0]), 0, 0 ) ) + return(0); + if( CheckTokenType(pTerms[2]) & TOKENTYPE_FLG_REG_BASE ) + { + if( !GetRegister( ps, 2, pTerms[2], &(inst.Arg[1]), 0, 0 ) ) + return(0); + } + else + { + if( !GetImValue( ps, 2, pTerms[2], &(inst.Arg[1]), 0, 65535 ) ) + return(0); + } + +CODE_JAL: + opcode = 0x11 << 25; + opcode |= inst.Arg[0].Value; + opcode |= inst.Arg[0].Field << 5; + if( inst.Arg[1].Type == ARGTYPE_REGISTER ) + { + opcode |= inst.Arg[1].Value << 16; + opcode |= inst.Arg[1].Field << 21; + } + else + { + opcode |= inst.Arg[1].Value << 8; + opcode |= 1<<24; + } + GenOp( ps, TermCnt, pTerms, opcode ); + return(1); + + case OP_RET: + if( TermCnt != 1 ) + { Report(ps,REP_ERROR,"Expected no operands"); return(0); } + inst.Arg[1].Type = ARGTYPE_REGISTER; + inst.Arg[1].Value = RetRegValue; + inst.Arg[1].Field = RetRegField; + goto CODE_JMP; + + case OP_JMP: + case OP_CALL: + /* + // Instruction in the form of: + // OPCODE Rjmp + // OPCODE #Im65535 + */ + if( TermCnt != 2 ) + { Report(ps,REP_ERROR,"Expected 1 operand"); return(0); } + if( CheckTokenType(pTerms[1]) & TOKENTYPE_FLG_REG_BASE ) + { + if( !GetRegister( ps, 1, pTerms[1], &(inst.Arg[1]), 0, 0 ) ) + return(0); + } + else + { + if( !GetImValue( ps, 1, pTerms[1], &(inst.Arg[1]), 0, 65535 ) ) + return(0); + } + + if( inst.Op==OP_CALL ) + { + inst.Arg[0].Type = ARGTYPE_REGISTER; + inst.Arg[0].Value = RetRegValue; + inst.Arg[0].Field = RetRegField; + goto CODE_JAL; + } + +CODE_JMP: + opcode = 0x10 << 25; + if( inst.Arg[1].Type == ARGTYPE_REGISTER ) + { + opcode |= inst.Arg[1].Value << 16; + opcode |= inst.Arg[1].Field << 21; + } + else + { + opcode |= inst.Arg[1].Value << 8; + opcode |= 1<<24; + } + GenOp( ps, TermCnt, pTerms, opcode ); + return(1); + + case OP_ILOOP: + opcode = (3<<28) | (1<<15); + goto CODE_LOOP; + + case OP_LOOP: + opcode = (3<<28); +CODE_LOOP: + /* + // Instruction in the form of: + // LOOP LoopDest, OP(255) + */ + if( Core3 ) + { Report(ps,REP_ERROR,"Expected 1 to 2 operands"); return(0); } + + inst.Arg[0].Type = ARGTYPE_OFFSET; + inst.Arg[0].Value = 0; + inst.Arg[0].Field = 0; + + if( !GetRegister( ps, 1, pTerms[1], &(inst.Arg[1]), 1, 0 ) ) + return(0); + if( TermCnt==2 ) + { + /* + // Handle "OPCODE JmpDest, Rtest.Tnn" + */ + if( inst.Arg[1].Type != ARGTYPE_REGISTERBIT ) + { Report(ps,REP_ERROR,"Two operand mode must specify .T field"); return(0); } + /* Move bit# to 3rd arg */ + inst.Arg[1].Type = ARGTYPE_REGISTER; + inst.Arg[2].Type = ARGTYPE_IMMEDIATE; + inst.Arg[2].Value = inst.Arg[1].Bit; + } + else + { + /* + // Handle "OPCODE JmpDest, Rtest, OP(255)" + */ + if( inst.Arg[1].Type != ARGTYPE_REGISTER ) + { Report(ps,REP_ERROR,"Three operand mode may not use .T field"); return(0); } + if( CheckTokenType(pTerms[2]) & TOKENTYPE_FLG_REG_BASE ) + { + if( !GetRegister( ps, 2, pTerms[2], &(inst.Arg[2]), 0, 0 ) ) + return(0); + } + else + { + if( !GetImValue( ps, 2, pTerms[2], &(inst.Arg[2]), 0, 31 ) ) + return(0); + } + } + + goto CODE_QB; + + + case OP_FILL: + /* + // Instruction in the form of: + // FILL &Rdst, #Im124 + // FILL #Im123, #Im124 + */ + if( Core124 ) + { Report(ps,REP_ERROR,"Length exceeds register file length"); return(0); } + if( !inst.Arg[1].Value ) + { Report(ps,REP_ERROR,"Zero length fill"); return(0); } + + /* Implement with XIN */ + opcode = 0x5D << 23; + opcode |= (inst.Arg[0].Value>>2) & 0x1F; + opcode |= (inst.Arg[0].Value&0x3) << 5; + opcode |= 254 << 15; + inst.Arg[1].Value--; + opcode |= inst.Arg[1].Value<<7; + GenOp( ps, TermCnt, pTerms, opcode ); + return(1); + + + case OP_ZERO: + /* + // Instruction in the form of: + // ZERO &Rdst, #Im124 + // ZERO #Im123, #Im124 + */ + if( Core124 ) + { Report(ps,REP_ERROR,"Clear length exceeds register file length"); return(0); } + if( !inst.Arg[1].Value ) + { Report(ps,REP_ERROR,"Zero length clear"); return(0); } + + if( Core>=CORE_V2 ) + { + /* Implement with XIN */ + opcode = 0x5D << 23; + opcode |= (inst.Arg[0].Value>>2) & 0x1F; + opcode |= (inst.Arg[0].Value&0x3) << 5; + opcode |= 255 << 15; + inst.Arg[1].Value--; + opcode |= inst.Arg[1].Value<<7; + GenOp( ps, TermCnt, pTerms, opcode ); + return(1); + } + + while( inst.Arg[1].Value ) + { + uint reg,field=0,size=0; + + reg = inst.Arg[0].Value/4; + + if( !(Options & OPTION_BIGENDIAN) ) + { + /* + // Little Endian Version + */ + switch( inst.Arg[0].Value & 0x3 ) + { + case 0: + if( inst.Arg[1].Value >= 4 ) + { + size = 4; + field = FIELDTYPE_31_0; + } + else if( inst.Arg[1].Value >= 2 ) + { + size = 2; + field = FIELDTYPE_15_0; + } + else + { + size = 1; + field = FIELDTYPE_7_0; + } + break; + + case 1: + if( inst.Arg[1].Value >= 2 ) + { + size = 2; + field = FIELDTYPE_23_8; + } + else + { + size = 1; + field = FIELDTYPE_15_8; + } + break; + + case 2: + if( inst.Arg[1].Value >= 2 ) + { + size = 2; + field = FIELDTYPE_31_16; + } + else + { + size = 1; + field = FIELDTYPE_23_16; + } + break; + + case 3: + size = 1; + field = FIELDTYPE_31_24; + break; + } + } + else + { + /* + // Big Endian Version + */ + switch( inst.Arg[0].Value & 0x3 ) + { + case 0: + if( inst.Arg[1].Value >= 4 ) + { + size = 4; + field = FIELDTYPE_31_0; + } + else if( inst.Arg[1].Value >= 2 ) + { + size = 2; + field = FIELDTYPE_31_16; + } + else + { + size = 1; + field = FIELDTYPE_31_24; + } + break; + + case 1: + if( inst.Arg[1].Value >= 2 ) + { + size = 2; + field = FIELDTYPE_23_8; + } + else + { + size = 1; + field = FIELDTYPE_23_16; + } + break; + + case 2: + if( inst.Arg[1].Value >= 2 ) + { + size = 2; + field = FIELDTYPE_15_0; + } + else + { + size = 1; + field = FIELDTYPE_15_8; + } + break; + + case 3: + size = 1; + field = FIELDTYPE_7_0; + break; + } + } + + inst.Arg[0].Value += size; + inst.Arg[1].Value -= size; + + /* LDI */ + opcode = 0x24 << 24; + opcode |= reg; + opcode |= field << 5; + GenOp( ps, TermCnt, pTerms, opcode ); + } + return(1); + } + + Report(ps,REP_ERROR,"Invalid opcode"); + return(0); +} + +/*=================================================================== +// +// Private Functions +// +====================================================================*/ + +/* +// GetRegister +// +// Get Register Argument +// +// Parses the source string for a register and field +// +// ps - Pointer to source file record +// num - operand number (1 based) +// src - source string +// pa - Pointer to register structure +// fBitOk - Can accept Rxx.Txx +// termC - Set to non-zero if special terminating character ('+') +// +// Returns: +// 1 : Success +// 0 : Error +*/ +int GetRegister( SOURCEFILE *ps, int num, char *src, PRU_ARG *pa, int fBitOk, char termC ) +{ + uint idx; + char c,field; + int val,reg,width,offset,bit; + + /* + // The following register syntaxes are valid: + // Raa aa=(0-31) + // Raa.Wb aa=(0-31) b=(0-2) + // Raa.Bc aa=(0-31) c=(0-3) + // Raa.Tdd aa=(0-31) dd=(0-31) + // Raa.Wb.Be aa=(0-31) b=(0-2) e=(0-1) + // Raa.Wb.Tff aa=(0-31) b=(0-2) ff=(0-15) + // Raa.Bc.Tgg aa=(0-31) c=(0-3) gg=(0-7) + // Raa.Wb.Be.Tgg aa=(0-31) b=(0-2) e=(0-1) gg=(0-7) + */ + + idx=0; + c = src[idx++]; + + /* Get initial 'R##' */ + if( toupper(c) != 'R' ) + goto INVALID_REG; + c = src[idx++]; + if( !isdigit(c) ) + goto INVALID_REG; + val = 0; + while( isdigit(c) ) + { + val *= 10; + val += c-'0'; + c = src[idx++]; + } + if( val>31 ) + goto INVALID_REG; + + reg = val; + width = 32; + offset = 0; + bit = -1; + + for(;;) + { + /* This char must be '.', or terminator */ + + /* If terminated, we're done */ + if( c==termC ) + break; + if( c != '.' ) + goto INVALID_REG; + + c = src[idx++]; + + /* This char must be 'W', 'B', or 'T' */ + c = toupper(c); + if( c!='T' && c!='W' && c!='B' ) + goto INVALID_REG; + field=c; + c = src[idx++]; + if( !isdigit(c) ) + goto INVALID_REG; + val = 0; + while( isdigit(c) ) + { + val *= 10; + val += c-'0'; + c = src[idx++]; + } + if( field=='W' ) + { + if( ((val*8)+16)>width ) + goto INVALID_REG; + width = 16; + offset += val; + } + if( field=='B' ) + { + if( ((val*8)+8)>width ) + goto INVALID_REG; + width = 8; + offset += val; + } + if( field=='T' ) + { + if( !fBitOk ) + { Report(ps,REP_ERROR,"Operand %d use of .T field not allowed here",num); return(0); } + if( val>=width ) + goto INVALID_REG; + if(c!=termC) + goto INVALID_REG; + bit = val; + } + + if( c!=termC && (Core==CORE_V0) ) + goto INVALID_REG; + } + + /* Build the record */ + pa->Type = ARGTYPE_REGISTER; + pa->Value = reg; + + if( width==32 ) + pa->Field = FIELDTYPE_31_0; + if( width==16 ) + { + if( !offset ) + pa->Field = FIELDTYPE_15_0; + else if( offset==1 ) + pa->Field = FIELDTYPE_23_8; + else + pa->Field = FIELDTYPE_31_16; + } + if( width==8 ) + { + if( !offset ) + pa->Field = FIELDTYPE_7_0; + else if( offset==1 ) + pa->Field = FIELDTYPE_15_8; + else if( offset==2 ) + pa->Field = FIELDTYPE_23_16; + else + pa->Field = FIELDTYPE_31_24; + } + if( bit>=0 ) + { + pa->Type = ARGTYPE_REGISTERBIT; + pa->Bit = bit; + } + + return(1); + +INVALID_REG: + Report(ps,REP_ERROR,"Operand %d '%s' invalid register or register mode",num,src); + return(0); +} + +/* +// GetImValue +// +// Get Register Argument +// +// Parses the source string for an immediate value +// +// ps - Pointer to source file record +// num - operand number (1 based) +// src - source string +// pa - Pointer to register structure +// min - Lowest legal value +// max - Highest legal value +// +// Returns: +// 1 : Success +// 0 : Error +*/ +static int GetImValue( SOURCEFILE *ps, int num, char *src, PRU_ARG *pa, uint min, uint max ) +{ + char tstr[TOKEN_MAX_LEN]; + uint val; + int idx; + + /* Handler register file offsets as immediates */ + val = CheckTokenType(src); + if( val!=TOKENTYPE_UNRESERVED && !(val&TOKENTYPE_FLG_REG_ADDR) ) + { + Report(ps,REP_ERROR,"Operand %d reserved word '%s' not legal here",num,src); + return(0); + } + + // Get our value from a an expression + if( *src=='#' ) + src++; + strcpy( tstr, src ); + if( Expression(ps, tstr, &val, &idx)<0 ) + { + Report(ps,REP_ERROR,"Operand %d error in expression",num); + return(0); + } + + if( Pass==2 && (Options & OPTION_DEBUG) ) + printf("%s(%5d) : EXP : '%s' = %d\n", ps->SourceName,ps->CurrentLine,src,val); + + /* Setup the record */ + pa->Type = ARGTYPE_IMMEDIATE; + pa->Value = val; + pa->Field = 0; + + if( valmax ) + { + Report(ps,REP_ERROR,"Operand %d immediate value out of range (%d-%d)",num,min,max); + return(0); + } + + return(1); +} + +/* +// GetConstant +// +// Get Constant Table Argument +// +// Parses the source string for a constant register +// +// ps - Pointer to source file record +// num - source line number +// src - source string +// pa - Pointer to register structure +// +// Returns: +// 1 : Success +// 0 : Error +*/ +static int GetConstant( SOURCEFILE *ps, int num, char *src, PRU_ARG *pa ) +{ + uint idx; + char c; + int val; + + idx=0; + c = src[idx++]; + + /* Get C## */ + if( toupper(c) != 'C' ) + goto INVALID_CONST; + c = src[idx++]; + if( !isdigit(c) ) + goto INVALID_CONST; + val = 0; + while( isdigit(c) ) + { + val *= 10; + val += c-'0'; + c = src[idx++]; + } + if( c || val>31 ) + goto INVALID_CONST; + + /* Setup the record */ + pa->Type = ARGTYPE_CONSTANT; + pa->Value = val; + pa->Field = 0; + + return(1); + +INVALID_CONST: + Report(ps,REP_ERROR,"Operand %d invalid constant table entry '%s'",num,src); + return(0); +} + + +/* +// GetR0offset +// +// Get "R0-offset" Argument for Burst Opcodes +// +// Parses the source string for a register and field +// +// ps - Pointer to source file record +// num - source line number +// src - source string +// pa - Pointer to register structure +// +// Returns: +// 1 : Success +// 0 : Error +*/ +static int GetR0offset( SOURCEFILE *ps, int num, char *src, PRU_ARG *pa ) +{ + uint idx; + char c; + int val; + + idx=0; + c = src[idx++]; + + /* Get B## */ + if( toupper(c) != 'B' ) + goto INVALID_R0BYTE; + c = src[idx++]; + if( !isdigit(c) ) + goto INVALID_R0BYTE; + val = 0; + while( isdigit(c) ) + { + val *= 10; + val += c-'0'; + c = src[idx++]; + } + if( c || val>3 ) + goto INVALID_R0BYTE; + + /* Setup the record */ + pa->Type = ARGTYPE_R0BYTE; + pa->Value = val; + pa->Field = 0; + + return(1); + +INVALID_R0BYTE: + Report(ps,REP_ERROR,"Operand %d invalid byte count '%s'",num,src); + return(0); +} + + +/* +// GetJmpOffset +// +// Get 10 bit Jump Offset for Quick Branch +// +// Parses the source string for a register and field +// +// ps - Pointer to source file record +// num - source line number +// src - source string +// pa - Pointer to register structure +// +// Returns: +// 1 : Success +// 0 : Error +*/ +static int GetJmpOffset( SOURCEFILE *ps, int num, char *src, PRU_ARG *pa ) +{ + char tstr[TOKEN_MAX_LEN]; + uint val; + int idx; + int jmpoff; + + strcpy( tstr, src ); + if( Expression(ps, tstr, &val, &idx)<0 ) + { + Report(ps,REP_ERROR,"Operand %d error in expression",num); + return(0); + } + + if( Pass==2 && (Options & OPTION_DEBUG) ) + printf("%s(%5d) : EXP : '%s' = %d\n", ps->SourceName,ps->CurrentLine,src,val); + + jmpoff = ((int)val) - CodeOffset; + if( Pass==2 && (jmpoff<-512 || jmpoff>511) ) + { Report(ps,REP_ERROR,"Operand %d relative jump out of range",num); return(0); } + + /* Setup the record */ + pa->Type = ARGTYPE_OFFSET; + pa->Value = (uint)jmpoff; + pa->Field = 0; + + return(1); +} + + +/* +// GetLoopOffset +// +// Get 8 bit Loop Offset +// +// Parses the source string for a register and field +// +// ps - Pointer to source file record +// num - source line number +// src - source string +// pa - Pointer to register structure +// +// Returns: +// 1 : Success +// 0 : Error +*/ +static int GetLoopOffset( SOURCEFILE *ps, int num, char *src, PRU_ARG *pa ) +{ + char tstr[TOKEN_MAX_LEN]; + uint val; + int idx; + int jmpoff; + + strcpy( tstr, src ); + if( Expression(ps, tstr, &val, &idx)<0 ) + { + Report(ps,REP_ERROR,"Operand %d error in expression",num); + return(0); + } + + if( Pass==2 && (Options & OPTION_DEBUG) ) + printf("%s(%5d) : EXP : '%s' = %d\n", ps->SourceName,ps->CurrentLine,src,val); + + jmpoff = ((int)val) - CodeOffset; + if( Pass==2 && (jmpoff<2 || jmpoff>255) ) + { Report(ps,REP_ERROR,"Operand %d invalid loop termination point",num); return(0); } + + /* Setup the record */ + pa->Type = ARGTYPE_OFFSET; + pa->Value = (uint)jmpoff; + pa->Field = 0; + + return(1); +} + + +/* +// Offset2Reg +// +// Convert Register Offset to Register +// +// ps - Pointer to source file record +// num - operand number (1 based) +// pa - Pointer to register structure +// addr - Field address (0 - 127) +// size - Field size (1, 2, or 4) +// +// Returns: +// 1 : Success +// 0 : Error +*/ +static int Offset2Reg( SOURCEFILE *ps, int num, PRU_ARG *pa, uint addr, uint size ) +{ + uint offset; + + offset = addr&3; + + if( addr+size > 128 ) + { Report(ps,REP_ERROR,"Operand %d, field extends past register file", num); return(0); } + + if( (size==2 && offset==3) || + (size==4 && offset!=0) ) + { Report(ps,REP_ERROR,"Operand %d, this field alignment not supported", num); return(0); } + + /* Build the record */ + pa->Type = ARGTYPE_REGISTER; + pa->Value = addr/4; + + /* Get field type */ + if( !(Options & OPTION_BIGENDIAN) ) + { + /* + // Little Endian Version + */ + if( size==4 ) + pa->Field = FIELDTYPE_31_0; + else if( size==2 ) + { + if( !offset ) + pa->Field = FIELDTYPE_15_0; + else if( offset==1 ) + pa->Field = FIELDTYPE_23_8; + else + pa->Field = FIELDTYPE_31_16; + } + else + { + if( !offset ) + pa->Field = FIELDTYPE_7_0; + else if( offset==1 ) + pa->Field = FIELDTYPE_15_8; + else if( offset==2 ) + pa->Field = FIELDTYPE_23_16; + else + pa->Field = FIELDTYPE_31_24; + } + } + else + { + /* + // Big Endian Version + */ + if( size==4 ) + pa->Field = FIELDTYPE_31_0; + else if( size==2 ) + { + if( !offset ) + pa->Field = FIELDTYPE_31_16; + else if( offset==1 ) + pa->Field = FIELDTYPE_23_8; + else + pa->Field = FIELDTYPE_15_0; + } + else + { + if( !offset ) + pa->Field = FIELDTYPE_31_24; + else if( offset==1 ) + pa->Field = FIELDTYPE_23_16; + else if( offset==2 ) + pa->Field = FIELDTYPE_15_8; + else + pa->Field = FIELDTYPE_7_0; + } + } + + return(1); +} + diff --git a/am335x/pasm/pasmpp.c b/am335x/pasm/pasmpp.c new file mode 100644 index 00000000..20453319 --- /dev/null +++ b/am335x/pasm/pasmpp.c @@ -0,0 +1,1165 @@ +/* + * pasmpp.c + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +/*=========================================================================== + * Copyright (c) Texas Instruments Inc 2010-12 + * + * Use of this software is controlled by the terms and conditions found in the + * license agreement under which this software has been supplied or provided. + * ============================================================================ + */ + +/*=========================================================================== +// PASM - PRU Assembler +//--------------------------------------------------------------------------- +// +// File : pasmpp.c +// +// Description: +// Assembler pre-processor. This module's operation is independent +// of the rest of the assembler. It contains no PRU specific +// functionality. +// - Preprocessor handles all source file opening and reading +// - Initial source parsing +// - Processes all '#' commands (#include and #define) +// - Handles equate creation, matching, and expansion +// +//--------------------------------------------------------------------------- +// Revision: +// 21-Jun-13: 0.84 - Open source version +============================================================================*/ + +#include +#include +#include +#if !defined(__APPLE__) +#include +#else +#include +#endif +#include +#include "pasm.h" + +/* Local Strcuture Types */ + +/* Equate Record */ +typedef struct _EQUATE { + struct _EQUATE *pPrev; /* Previous in EQUATE list */ + struct _EQUATE *pNext; /* Next in EQUATE list */ + int Busy; /* Is this record busy? */ + char name[EQUATE_NAME_LEN]; + char data[EQUATE_DATA_LEN]; +} EQUATE; + +/* Local Support Funtions */ +static int ReadCharacter( SOURCEFILE *ps ); +static int GetTextLine( SOURCEFILE *ps, char *Dst, int MaxLen, int *pLength, int *pEOF ); +static int ParseSource( SOURCEFILE *ps, char *Src, char *Dst, int *pIdx, int MaxLen ); +static int LoadInclude( SOURCEFILE *ps, char *Src ); +static int EquateProcess( SOURCEFILE *ps, char *Src ); +static int UndefProcess( SOURCEFILE *ps, char *Src ); +static EQUATE *EquateFind( char *name ); +static void EquateDestroy( EQUATE *peq ); + +static int IfDefProcess( SOURCEFILE *ps, char *Src, int fTrue ); +static int ElseProcess( SOURCEFILE *ps, char *Src ); +static int EndifProcess( SOURCEFILE *ps, char *Src ); + +int OpenFiles=0; /* Total number of open files */ +EQUATE *pEqList=0; /* List of installed equates */ + +SOURCEFILE sfArray[SOURCEFILE_MAX]; +unsigned int sfIndex = 0; + +#define CC_MAX_DEPTH 8 +uint ccDepth = 0; +uint ccStateFlags[CC_MAX_DEPTH]; +#define CCSTATEFLG_TRUE 1 // Currently accepting code +#define CCSTATEFLG_ELSE 2 // Else has been used + + +/*=================================================================== +// +// Public Functions +// +====================================================================*/ + +/* +// InitSourceFile +// +// Initializes all the fields in SOURCEFILE, and attempts to to open the +// file. +// +// Returns 1 on success, 0 on error +*/ +SOURCEFILE *InitSourceFile( SOURCEFILE *pParent, char *filename ) +{ + SOURCEFILE *ps; + int i,j,k; + char SourceName[SOURCE_NAME]; + char SourceBaseDir[SOURCE_BASE_DIR]; + + /* Put a reasonable cap on #include depth */ + if( OpenFiles==15 ) + { + Report(pParent,REP_FATAL,"Too many open files"); + return(0); + } + + /* + // Create a base directory for this file + // + // The base directory is used for any #include contained in the source + */ + strcpy( SourceBaseDir, "./" ); + i=0; + j=-1; + k=0; + while( filename[i] ) + { + if( filename[i]==':' ) + { + if(k) + { + Report(pParent,REP_FATAL,"Illegal source file name '%s'",filename); + goto FILEOP_ERROR; + } + j=i; + k=1; + } + if( filename[i]=='/' || filename[i]=='\\' ) + j=i; + i++; + } + if( j>=(SOURCE_BASE_DIR-4) ) + { + Report(pParent,REP_FATAL,"Pathname too long in '%s'",filename); + goto FILEOP_ERROR; + } + if( j>0 ) + { + if(k) + { + memcpy( SourceBaseDir, filename, j+1 ); + SourceBaseDir[j+1]='.'; + SourceBaseDir[j+2]='/'; + SourceBaseDir[j+3]=0; + } + else + { + if((filename[0]=='.' && filename[1]=='/') || filename[0]=='/' || filename[0]=='\\') + { + memcpy( SourceBaseDir, filename, j ); + SourceBaseDir[j]='/'; + SourceBaseDir[j+1]=0; + } + else + { + memcpy( SourceBaseDir+2, filename, j ); + SourceBaseDir[j+2]='/'; + SourceBaseDir[j+3]=0; + } + } + } + if( Options & OPTION_DEBUG ) + printf("Base source directory: '%s'\n",SourceBaseDir); + + /* Create the "friendly" filename for output messages */ + i=strlen(filename)-j; + if( i>SOURCE_NAME ) + { + Report(pParent,REP_FATAL,"Basename too long in '%s'",filename); + goto FILEOP_ERROR; + } + memcpy( SourceName, filename+j+1, i ); + + /* + // See if this file was used before, or allocate a new record + */ + for( i=0; i<(int)sfIndex; i++ ) + { + if( !sfArray[i].InUse && + !strcmp(SourceName, sfArray[i].SourceName) && + !strcmp(SourceBaseDir, sfArray[i].SourceBaseDir) ) + break; + } + + if( i<(int)sfIndex ) + ps = &sfArray[i]; + else + { + /* Allocate a new file */ + if( sfIndex==SOURCEFILE_MAX ) + { Report(pParent,REP_FATAL,"Max source files exceeded"); return(0); } + + ps = &sfArray[sfIndex]; + i = sfIndex++; + } + + /* + // Fill in file record + */ + memset( ps, 0, sizeof(SOURCEFILE) ); + + if( Options & OPTION_DEBUG ) + printf("New source file: '%s'\n",filename); + + /* Init the base fields */ + ps->pParent = 0; + ps->LastChar = 0; + ps->CurrentLine = 1; + ps->CurrentColumn = 1; + ps->ccDepthIn = ccDepth; + ps->InUse = 1; + ps->FileIndex = i; + + strcpy( ps->SourceName, SourceName ); + strcpy( ps->SourceBaseDir, SourceBaseDir ); + + + /* Open the file */ + ps->FilePtr = fopen(filename,"rb"); + if (!ps->FilePtr) + { + Report(pParent,REP_FATAL,"Can't open source file '%s'",filename); + goto FILEOP_ERROR; + } + OpenFiles++; + if( OpenFiles > 10 ) + Report(pParent,REP_WARN1,"%d open files - possible #include recursion",OpenFiles); + return(ps); + +FILEOP_ERROR: + return(0); +} + + +/* +// CloseSourceFile +// +// Close the source file and free the block. +// +// void +*/ +void CloseSourceFile( SOURCEFILE *ps ) +{ + OpenFiles--; + ps->InUse = 0; + fclose( ps->FilePtr ); +} + + +/* +// GetSourceLine +// +// Get a new line of source code. +// +// This module also processes: +// '#' directives +// #define expansion +// Comments +// +// Returns length of line, 0 on EOF, -1 on Error +*/ +#define RAW_SOURCE_MAX 255 +int GetSourceLine( SOURCEFILE *ps, char *Dst, int MaxLen ) +{ + char c,Src[RAW_SOURCE_MAX],word[TOKEN_MAX_LEN]; + int i,idx; + int len,eof; + +NEXT_LINE: + do + { + if( !GetTextLine(ps, Src, RAW_SOURCE_MAX, &len, &eof) ) + return(-1); + } while( !len && !eof ); + + if( !len && eof ) + { + if( ps->ccDepthIn != ccDepth ) + { Report(ps,REP_ERROR,"#endif mismatch in file"); return(0); } + return(0); + } + + /* + // Process any '#' directives + */ + if( Src[0]=='#' ) + { + idx = 1; + c = Src[idx++]; + if( (c<'A'||c>'Z') && (c<'a'||c>'z') ) + { Report(ps,REP_ERROR,"Expected {a-z} after #"); return(-1); } + i=0; + word[i++]=c; + while( i<(TOKEN_MAX_LEN-1) ) + { + c = Src[idx++]; + if( c==' ' || c==0x9 || !c ) + break; + word[i++]=c; + } + word[i]=0; + + /* Make sure the process functions see the final NULL */ + if( !c ) + idx--; + + if( !stricmp( word, "ifdef" ) ) + { + if( !IfDefProcess( ps, Src+idx, 1 ) ) + return(-1); + goto NEXT_LINE; + } + if( !stricmp( word, "ifndef" ) ) + { + if( !IfDefProcess( ps, Src+idx, 0 ) ) + return(-1); + goto NEXT_LINE; + } + if( !stricmp( word, "else" ) ) + { + if( !ElseProcess( ps, Src+idx ) ) + return(-1); + goto NEXT_LINE; + } + if( !stricmp( word, "endif" ) ) + { + if( !EndifProcess( ps, Src+idx ) ) + return(-1); + goto NEXT_LINE; + } + + if( ccDepth && !(ccStateFlags[ccDepth-1]&CCSTATEFLG_TRUE) ) + goto NEXT_LINE; + + if( !stricmp( word, "error" ) ) + { + Report(ps,REP_ERROR,"%s",Src+idx); + goto NEXT_LINE; + } + if( !stricmp( word, "warn" ) ) + { + Report(ps,REP_WARN1,"%s",Src+idx); + goto NEXT_LINE; + } + if( !stricmp( word, "note" ) ) + { + Report(ps,REP_INFO,"%s",Src+idx); + goto NEXT_LINE; + } + if( !stricmp( word, "include" ) ) + { + if( !LoadInclude( ps, Src+idx ) ) + return(-1); + goto NEXT_LINE; + } + if( !stricmp( word, "define" ) ) + { + EquateProcess( ps, Src+idx ); + goto NEXT_LINE; + } + if( !stricmp( word, "undef" ) ) + { + UndefProcess( ps, Src+idx ); + goto NEXT_LINE; + } + Report(ps,REP_ERROR,"Unknown # directive"); + return(-1); + } + + /* + // Not '#' directive, process as string + */ + + if( ccDepth && !(ccStateFlags[ccDepth-1]&CCSTATEFLG_TRUE) ) + goto NEXT_LINE; + + idx = 0; + if( !ParseSource( ps, Src, Dst, &idx, MaxLen ) ) + return(0); + + Dst[idx] = 0; + return(idx); +} + +/* +// ppCleanup +// +// Clean up the pre-processor environment +// +// void +*/ +void ppCleanup() +{ + ccDepth = 0; + while( pEqList ) + EquateDestroy( pEqList ); +} + + +/* +// EquateCreate +// +// Creates an equate record +// +// Returns 0 on success, -1 on error +*/ +int EquateCreate( SOURCEFILE *ps, char *Name, char *Value ) +{ + EQUATE *pd; + + /* Make sure this name is OK to use */ + if( !CheckName(ps,Name) ) + return(-1); + + /* Make sure its not a too long */ + if( strlen(Name)>=EQUATE_NAME_LEN ) + { Report(ps,REP_ERROR,"Equate name '%s' too long",Name); return(-1); } + if( strlen(Value)>=EQUATE_DATA_LEN ) + { Report(ps,REP_ERROR,"Equate data '%s' too long",Value); return(-1); } + + /* Allocate a new record */ + pd = malloc(sizeof(EQUATE)); + if( !pd ) + { Report(ps,REP_ERROR,"Memory allocation failed"); return(-1); } + + /* Load in the name and data */ + strcpy( pd->name, Name ); + strcpy( pd->data, Value ); + + /* Put this equate in the master list */ + pd->Busy = 0; + pd->pPrev = 0; + pd->pNext = pEqList; + if( pEqList ) + pEqList->pPrev = pd; + pEqList = pd; + + if( Pass==1 && (Options & OPTION_DEBUG) ) + printf("%s(%5d) : DEFINE : '%s' = '%s'\n", + ps->SourceName,ps->CurrentLine,pd->name,pd->data); + + return(0); +} + + +/* +// CheckEquate +// +// Searches for an equate by name. +// +// Returns 1 on success, 0 on error +*/ +int CheckEquate( char *name ) +{ + if( EquateFind(name) ) + return(1); + return(0); +} + + +/*=================================================================== +// +// Private Functions +// +====================================================================*/ + +/* +// ReadCharacter +// +// Read a charater from the source file and track line and column +// +// Returns character or -1 on error +*/ +static int ReadCharacter( SOURCEFILE *ps ) +{ + int i; + char c; + +AGAIN: + i = fread( &c, 1, 1, ps->FilePtr ); + if( i != 1 ) + return(-1); + if( c == 0xd ) + goto AGAIN; + if( ps->LastChar == 0xa ) + { + ps->CurrentLine++; + ps->CurrentColumn=1; + } + else + ps->CurrentColumn++; + ps->LastChar = c; + + return(c); +} + + +/* +// GetTextLine +// +// Gets a line of text from the source file without # directive +// processing, or processing past a EOL. +// +// Returns 1 on success, 0 on error +*/ +static int GetTextLine( SOURCEFILE *ps, char *Dst, int MaxLen, int *pLength, int *pEOF ) +{ + int c; + int idx; + int commentFlag,quoteFlag; + + /* Remove leading white space */ + do + { + c = ReadCharacter( ps ); + } while( c==' ' || c==0x9 || c==0xa ); + + /* + // Process line watching for comments and quotes + */ + idx=0; + commentFlag=0; + quoteFlag=0; + for(;;) + { + /* Process quotes and comments */ + if( c=='"' ) + quoteFlag^=1; + + if( quoteFlag ) + commentFlag=0; + + if( (commentFlag && c=='/') || (!quoteFlag && c==';') ) + { + if( c=='/' && idx>0 ) + idx--; + while( c!=0 && c!=-1 && c!=0xa ) + c = ReadCharacter( ps ); + break; + } + + if( c=='/' ) + commentFlag=1; + else + commentFlag=0; + + /* If this character terminated the line, break now */ + if( c==0 || c==-1 || c==0xa ) + break; + + /* We didn't consume this charater */ + if( idx<(MaxLen-1) ) + Dst[idx++]=c; + else + { Report(ps,REP_ERROR,"Line too long"); return(0); } + + c = ReadCharacter( ps ); + } + + /* Back off white space */ + while( idx>0 && (Dst[idx-1]==' ' || Dst[idx-1]==0x9) ) + idx--; + + /* Null terminate the output */ + Dst[idx] = 0; + + if( quoteFlag ) + Report(ps,REP_ERROR,"Open Quotes"); + + if( pLength ) + *pLength = idx; + + if( pEOF ) + { + if( idx || c!=-1 ) + *pEOF=0; + else + *pEOF=1; + } + + return(1); +} + + +/* +// ParseSource +// +// Parses the source string, expanding any equates +// +// Returns 1 on success, 0 on error +*/ +#define WF_READY 0 +#define WF_NONLABEL 1 +#define WF_QUOTED 2 +#define WF_LABEL 3 +static int ParseSource( SOURCEFILE *ps, char *Src, char *Dst, int *pIdx, int MaxLen ) +{ + char c,word[TOKEN_MAX_LEN]; + int i,srcIdx,dstIdx,wordIdx; + int wordFlag; + + srcIdx = 0; + dstIdx = *pIdx; + wordIdx = 0; + + wordFlag=WF_READY; + for(;;) + { + c = Src[srcIdx++]; + + /* See if we go into label or non-label mode */ + if( wordFlag==WF_READY ) + { + if( c=='"' ) + wordFlag=WF_QUOTED; + else if( LabelChar(c,1) ) + { + wordFlag=WF_LABEL; + wordIdx=0; + word[wordIdx++]=c; + continue; + } + else if( LabelChar(c,0) ) + wordFlag=WF_NONLABEL; + } + /* See if we fall out of non-label mode */ + else if( wordFlag==WF_NONLABEL ) + { + if( c=='"' ) + wordFlag=WF_QUOTED; + else if( !LabelChar(c,0) ) + wordFlag=WF_READY; + } + /* See if we fall out of label mode */ + else if( wordFlag==WF_LABEL ) + { + if( (wordIdx>=(TOKEN_MAX_LEN-1)) || !LabelChar(c,0) ) + { + /* Here we are teminating the word and checking it */ + EQUATE *peq; + if( c=='"' ) + wordFlag=WF_QUOTED; + else + wordFlag=WF_READY; + word[wordIdx]=0; + peq = EquateFind(word); + /* See if equate exists and is free */ + if( peq && !peq->Busy ) + { + /* Mark as busy, process, then mark as free */ + peq->Busy=1; + i = ParseSource( ps, peq->data, Dst, &dstIdx, MaxLen ); + peq->Busy=0; + + /* If there was an error, return now */ + if( !i ) + return(0); + } + else + { + /* The word is not a EQUATE */ + for(i=0;iSourceBaseDir ); + idx = strlen(NewFileName); + } + else if( c=='<' ) + { + term = '>'; + idx=0; + } + else + { Report(ps,REP_ERROR,"Expected \" or < after #include"); return(0); } + + /* Read in the filename to the terminating character */ + // Check for include paths that start with "/" or "\" + // (assume an absolute path) + if( Src[srcIdx]=='/' || Src[srcIdx]=='\\' ) + idx = 0; + oldidx = idx; + for(;;) + { + c = Src[srcIdx++]; + // Check for include paths that include a ":" + // (assume a driver letter preceeded) + if( c==':' && idx>0 ) + { + NewFileName[0]=NewFileName[idx-1]; + idx = 1; + oldidx = idx; + } + if( c==term ) + break; + if( !c ) + { Report(ps,REP_ERROR,"Bad filename in #include"); return(0); } + if( idx >= (SOURCE_BASE_DIR-1) ) + { Report(ps,REP_ERROR,"Filename too long in #include"); return(0); } + NewFileName[idx++]=c; + } + + /* The line should be done now */ + if( Src[srcIdx] ) + { Report(ps,REP_ERROR,"Expected EOL after '%s'",NewFileName); return(0); } + + /* Null terminate the filename and make sure something got copied */ + NewFileName[idx]=0; + if( idx == oldidx ) + { Report(ps,REP_ERROR,"Null filename in #include"); return(0); } + + /* Open the new file */ + if( !(psNew=InitSourceFile(ps, NewFileName)) ) + return(0); + + /* Process the new file */ + rc = ProcessSourceFile( psNew ); + + /* Free the file block */ + CloseSourceFile( psNew ); + + if( !rc && Pass==2 ) + return(0); + else + return(1); +} + +/* +// EquateProcess +// +// Processes a #define command +// +// Returns 1 on success, 0 on error +*/ +static int EquateProcess( SOURCEFILE *ps, char *Src ) +{ + EQUATE *pd,*pdTmp; + char c; + int idx,srcIdx; + + /* Allocate a new record */ + pd = malloc(sizeof(EQUATE)); + if( !pd ) + { Report(ps,REP_ERROR,"Memory allocation failed"); return(0); } + + srcIdx=0; + + /* Remove leading white space */ + do + { + c = Src[srcIdx++]; + } while( c==' ' || c==0x9 ); + + /* Character must be a legal label */ + if( !LabelChar(c,1) ) + { Report(ps,REP_ERROR,"Illegal label"); free(pd); return(0); } + + /* The name can only be delimited by a white space */ + /* Note: We now allow a NULL for a #define with no value */ + idx=0; + for(;;) + { + pd->name[idx++]=c; + c = Src[srcIdx++]; + if( !c || c==' ' || c==0x9 ) + break; + if( !LabelChar(c,0) ) + { Report(ps,REP_ERROR,"Illegal #define"); free(pd); return(0); } + if( idx >= (EQUATE_NAME_LEN-1) ) + { Report(ps,REP_ERROR,"Label too long"); free(pd); return(0); } + } + pd->name[idx]=0; + + /* Make sure this name is OK to use */ + if( !CheckName(ps,pd->name) ) + { + free(pd); + return(0); + } + + /* Remove leading white space (unless we already hit EOL) */ + if( c ) + do + { + c = Src[srcIdx++]; + } while( c==' ' || c==0x9 ); + + /* Load in the text part of the equate (defaul to "1" if no value) */ + if( !c ) + strcpy( pd->data, "1" ); + else + strcpy( pd->data, Src+srcIdx-1 ); + + /* Check for dedefinition, but ignore exact duplicates */ + if( (pdTmp = EquateFind(pd->name)) != 0 ) + { + idx = strcmp( pd->data, pdTmp->data ); + if( !idx ) + { + free(pd); + return(1); + } + EquateDestroy(pdTmp); + Report(ps,REP_WARN1,"Redefinition of equate '%s'",pd->name); + } + + /* Put this equate in the master list */ + pd->Busy = 0; + pd->pPrev = 0; + pd->pNext = pEqList; + if( pEqList ) + pEqList->pPrev = pd; + pEqList = pd; + + if( Pass==1 && (Options & OPTION_DEBUG) ) + printf("%s(%5d) : DEFINE : '%s' = '%s'\n", + ps->SourceName,ps->CurrentLine,pd->name,pd->data); + + return(1); +} + + +/* +// UndefProcess +// +// Processes a #undef command +// +// Returns 1 on success, 0 on error +*/ +static int UndefProcess( SOURCEFILE *ps, char *Src ) +{ + EQUATE *pdTmp; + char c,name[EQUATE_NAME_LEN]; + int idx,srcIdx; + + srcIdx=0; + + /* Remove leading white space */ + do + { + c = Src[srcIdx++]; + } while( c==' ' || c==0x9 ); + + /* Character must be a legal label */ + if( !LabelChar(c,1) ) + { Report(ps,REP_ERROR,"Illegal label"); return(0); } + + /* The name is delimited by EOL */ + idx=0; + for(;;) + { + name[idx++]=c; + c = Src[srcIdx++]; + if( !c ) + break; + if( c==' ' || c==0x9 ) + { Report(ps,REP_ERROR,"Unexpected additional characters on line"); return(0); } + if( !LabelChar(c,0) ) + { Report(ps,REP_ERROR,"Illegal name"); return(0); } + if( idx >= (EQUATE_NAME_LEN-1) ) + { Report(ps,REP_ERROR,"Label too long"); return(0); } + } + name[idx]=0; + + /* Check for dedefinition */ + if( !(pdTmp = EquateFind(name)) ) + { Report(ps,REP_WARN1,"Undef attempt on undfined '%s'",name); return(1); } + + EquateDestroy(pdTmp); + + if( Pass==1 && (Options & OPTION_DEBUG) ) + printf("%s(%5d) : UNDEF : '%s'\n", + ps->SourceName,ps->CurrentLine,name); + + return(1); +} + + +/* +// EquateFind +// +// Searches for an equate by name. If found, returns the record pointer. +// +// Returns EQUATE * on success, 0 on error +*/ +static EQUATE *EquateFind( char *name ) +{ + EQUATE *peq; + + peq = pEqList; + while( peq ) + { + if( !strcmp( name, peq->name ) ) + break; + peq = peq->pNext; + } + return(peq); +} + + +/* +// EquateDestroy +// +// Frees an equate record. +// +// void +*/ +static void EquateDestroy( EQUATE *peq ) +{ + if( !peq->pPrev ) + pEqList = peq->pNext; + else + peq->pPrev->pNext = peq->pNext; + + if( peq->pNext ) + peq->pNext->pPrev = peq->pPrev; + + free(peq); +} + + +/* +// IfDefProcess +// +// Processes a #ifdef command +// +// Returns 1 on success, 0 on error +*/ +static int IfDefProcess( SOURCEFILE *ps, char *Src, int fTrue ) +{ + char c,name[EQUATE_NAME_LEN]; + int idx,srcIdx; + + /* Check depth */ + if( ccDepth==CC_MAX_DEPTH ) + { Report(ps,REP_ERROR,"Conditional nesting limit exceeded"); return(0); } + + /* If we are already in a false if, just create another false here to track nesting */ + if( ccDepth && !(ccStateFlags[ccDepth-1]&CCSTATEFLG_TRUE) ) + { + ccStateFlags[ccDepth++] = 0; + + if( Pass==1 && (Options & OPTION_DEBUG) ) + printf("%s(%5d) : IFDEF : \n",ps->SourceName,ps->CurrentLine); + + return(1); + } + + srcIdx=0; + + /* Remove leading white space */ + do + { + c = Src[srcIdx++]; + } while( c==' ' || c==0x9 ); + + /* Character must be a legal label */ + if( !LabelChar(c,1) ) + { Report(ps,REP_ERROR,"Illegal label"); return(0); } + + /* The name is delimited by EOL */ + idx=0; + for(;;) + { + name[idx++]=c; + c = Src[srcIdx++]; + if( !c ) + break; + if( c==' ' || c==0x9 ) + { Report(ps,REP_ERROR,"Unexpected additional characters on line"); return(0); } + if( !LabelChar(c,0) ) + { Report(ps,REP_ERROR,"Illegal name"); return(0); } + if( idx >= (EQUATE_NAME_LEN-1) ) + { Report(ps,REP_ERROR,"Label too long"); return(0); } + } + name[idx]=0; + + ccStateFlags[ccDepth] = 0; + + /* Check for dedefinition */ + if( EquateFind(name) ) + ccStateFlags[ccDepth] = CCSTATEFLG_TRUE; + + /* Toggle the state for ifndef */ + if( !fTrue ) + ccStateFlags[ccDepth] ^= CCSTATEFLG_TRUE; + + ccDepth++; + + if( Pass==1 && (Options & OPTION_DEBUG) ) + { + if( fTrue ) + printf("%s(%5d) : IFDEF : '%s' (Result=%d)\n", + ps->SourceName,ps->CurrentLine,name,ccStateFlags[ccDepth-1]); + else + printf("%s(%5d) : IFNDEF : '%s' (Result=%d)\n", + ps->SourceName,ps->CurrentLine,name,ccStateFlags[ccDepth-1]); + } + + return(1); +} + + +/* +// ElseProcess +// +// Processes a #else command +// +// Returns 1 on success, 0 on error +*/ +static int ElseProcess( SOURCEFILE *ps, char *Src ) +{ + int i; + + if( *Src ) + { Report(ps,REP_ERROR,"Unexpected additional characters on line"); return(0); } + + /* Make sure #else is legal here */ + if( !ccDepth || (ccStateFlags[ccDepth-1]&CCSTATEFLG_ELSE) ) + { Report(ps,REP_ERROR,"Multiple #else or use without corresponding #if"); return(0); } + + /* Mark it as used */ + ccStateFlags[ccDepth-1] |= CCSTATEFLG_ELSE; + + /* Toggle the TRUE state */ + ccStateFlags[ccDepth-1] ^= CCSTATEFLG_TRUE; + + /* If we are already in a nested false if, keep expession false */ + for( i=0; i<(int)(ccDepth-1); i++ ) + if( !(ccStateFlags[i]&CCSTATEFLG_TRUE) ) + ccStateFlags[ccDepth-1] &= ~CCSTATEFLG_TRUE; + + if( Pass==1 && (Options & OPTION_DEBUG) ) + printf("%s(%5d) : ELSE : (Result=%d)\n", + ps->SourceName,ps->CurrentLine,ccStateFlags[ccDepth-1]&CCSTATEFLG_TRUE); + + return(1); +} + + +/* +// EndifProcess +// +// Processes a #endif command +// +// Returns 1 on success, 0 on error +*/ +static int EndifProcess( SOURCEFILE *ps, char *Src ) +{ + if( *Src ) + { Report(ps,REP_ERROR,"Unexpected additional characters on line"); return(0); } + + /* Make sure #else is legal here */ + if( !ccDepth ) + { Report(ps,REP_ERROR,"#endif without corresponding #if"); return(0); } + + ccDepth--; + + if( Pass==1 && (Options & OPTION_DEBUG) ) + printf("%s(%5d) : ENDIF :\n", + ps->SourceName,ps->CurrentLine); + + return(1); +} + diff --git a/am335x/pasm/pasmstruct.c b/am335x/pasm/pasmstruct.c new file mode 100644 index 00000000..6fc362e3 --- /dev/null +++ b/am335x/pasm/pasmstruct.c @@ -0,0 +1,1251 @@ +/* + * pasmstruct.c + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +/*=========================================================================== + * Copyright (c) Texas Instruments Inc 2010-12 + * + * Use of this software is controlled by the terms and conditions found in the + * license agreement under which this software has been supplied or provided. + * ============================================================================ + */ + +/*=========================================================================== +// PASM - PRU Assembler +//--------------------------------------------------------------------------- +// +// File : pasmstruct.c +// +// Description: +// Processes the scruct and scope commands +// +//--------------------------------------------------------------------------- +// Revision: +// 21-Jun-13: 0.84 - Open source version +============================================================================*/ + +#include +#include +#include +#if !defined(__APPLE__) +#include +#else +#include +#endif +#include +#include "pasm.h" + +/* Local Strcuture Types */ + +/* Struct Record */ +#define STRUCT_NAME_LEN TOKEN_MAX_LEN +#define STRUCT_MAX_ELEM 64 +typedef struct _STRUCT { + struct _STRUCT *pPrev; /* Previous in STRUCT list */ + struct _STRUCT *pNext; /* Next in STRUCT list */ + char Name[STRUCT_NAME_LEN]; + int Elements; /* Element Count */ + uint TotalSize; /* Total Size */ + uint Offset[STRUCT_MAX_ELEM]; /* Element Offset */ + uint Size[STRUCT_MAX_ELEM]; /* Element Size */ + char ElemName[STRUCT_MAX_ELEM][STRUCT_NAME_LEN]; +} STRUCT; + +/* Assignment Record */ +typedef struct _ASSIGN { + struct _ASSIGN *pPrev; /* Previous in ASSIGN list */ + struct _ASSIGN *pNext; /* Next in ASSIGN list */ + char Name[STRUCT_NAME_LEN]; + char BaseReg[STRUCT_NAME_LEN]; + int Elements; /* Element Count */ + uint TotalSize; /* Total Size */ + char ElemName[STRUCT_MAX_ELEM][STRUCT_NAME_LEN]; + char MappedReg[STRUCT_MAX_ELEM][STRUCT_NAME_LEN]; + uint Offset[STRUCT_MAX_ELEM]; /* Element Offset */ + uint Size[STRUCT_MAX_ELEM]; /* Element Size */ +} ASSIGN; + +/* Scope Record */ +#define SCOPE_NAME_LEN TOKEN_MAX_LEN +typedef struct _SCOPE { + struct _SCOPE *pPrev; /* Previous in SCOPE list */ + struct _SCOPE *pNext; /* Next in SCOPE list */ + uint Flags; +#define SCOPE_FLG_OPEN (1<<0) + char Name[SCOPE_NAME_LEN]; + struct _SCOPE *pParent; /* Current SCOPE when created */ + struct _ASSIGN *pAssignList; /* ASSIGN list */ +} SCOPE; + + +/* Local Support Funtions */ +static STRUCT *StructFind( char *Name ); +static STRUCT *StructCreate( SOURCEFILE *ps, char *Name ); +static void StructDestroy( STRUCT *pst ); +static int GetRegname( SOURCEFILE *ps, uint element, char *str, uint off, uint size ); +static ASSIGN *AssignFind( char *Name ); +static ASSIGN *AssignCreate( SOURCEFILE *ps, ASSIGN **pList, char *Name ); +static void AssignDestroy( ASSIGN **pList, ASSIGN *pas ); +static char *StructNameCheck( char *source ); +static int StructValueOperand( char *source, int CmdType, uint *pValue ); +#define SVO_SIZEOF 0 +#define SVO_OFFSET 1 +static int GetFinalSize( char *ext, uint Size, uint *pValue ); +static int GetFinalOffset( char *ext, uint Size, uint Offset, uint *pValue ); +static SCOPE *ScopeCreate( SOURCEFILE *ps, char *Name ); +static void ScopeDestroy( SCOPE *psc ); +static void ScopeClose( SCOPE *psc ); +static SCOPE *ScopeFind( char *Name ); + + +/* Local structure lists */ +STRUCT *pStructList=0; /* List of declared structs */ +STRUCT *pStructCurrent=0; + +SCOPE *pScopeList=0; /* List of desclared scopes */ +SCOPE *pScopeCurrent=0; + +/*=================================================================== +// +// Public Functions +// +====================================================================*/ + +/* +// ScopeEnter +// +// Returns: +// 0 - Success +// -1 - Error +*/ +int ScopeEnter( SOURCEFILE *ps, char *Name ) +{ + if( Core == CORE_V0 ) + { Report(ps,REP_ERROR,".enter illegal with specified core version"); return(-1); } + if( !ScopeCreate(ps, Name) ) + return(-1); + return(0); +} + + +/* +// ScopeLeave +// +// Returns: +// 0 - Success +// -1 - Error +*/ +int ScopeLeave( SOURCEFILE *ps, char *Name ) +{ + SCOPE *psc; + + psc = ScopeFind(Name); + if( !psc ) + { Report(ps,REP_ERROR,"Scope name undefined"); return(-1); } + if( !(psc->Flags&SCOPE_FLG_OPEN) ) + { Report(ps,REP_ERROR,"Scope is not open"); return(-1); } + ScopeClose(psc); + return(0); +} + + +/* +// ScopeUsing +// +// Returns: +// 0 - Success +// -1 - Error +*/ +int ScopeUsing( SOURCEFILE *ps, char *Name ) +{ + SCOPE *psc; + + psc = ScopeFind(Name); + if( !psc ) + { Report(ps,REP_ERROR,"Scope name undefined"); return(-1); } + if( psc->Flags&SCOPE_FLG_OPEN ) + { Report(ps,REP_ERROR,"Scope is already open"); return(-1); } + psc->Flags |= SCOPE_FLG_OPEN; + pScopeCurrent = psc; + return(0); +} + + +/* +// StructInit +// +// Returns: void +*/ +void StructInit() +{ + ScopeCreate(0,"_ROOT_"); +} + + +/* +// StructCleanup +// +// Returns: void +*/ +void StructCleanup() +{ + while( pScopeList ) + ScopeDestroy( pScopeList ); + while( pStructList ) + StructDestroy( pStructList ); +} + + +/* +// StructNew +// +// Returns: +// 0 - Success +// -1 - Error +*/ +int StructNew( SOURCEFILE *ps, char *Name ) +{ + if( pStructCurrent ) + { Report(ps,REP_ERROR,"Structure can not be nested"); return(-1); } + if( Core == CORE_V0 ) + { Report(ps,REP_ERROR,".struct illegal with specified core version"); return(-1); } + pStructCurrent=StructCreate(ps, Name); + if( !pStructCurrent ) + return(-1); + return(0); +} + + +/* +// StructEnd +// +// Returns: +// 0 - Success +// -1 - Error +*/ +int StructEnd(SOURCEFILE *ps) +{ + if( !pStructCurrent ) + { Report(ps,REP_ERROR,"Structure .struct/.ends mismatch"); return(-1); } + if( !pStructCurrent->Elements ) + { Report(ps,REP_ERROR,"Structure must have at least 1 element"); pStructCurrent=0; return(-1); } + pStructCurrent = 0; + return(0); +} + + +/* +// StructAddElement +// +// Create a new structure record +// +// Returns 0 on success, -1 on error +*/ +int StructAddElement( SOURCEFILE *ps, char *Name, uint size ) +{ + STRUCT *pst = pStructCurrent; + int i; + + if( !pst ) + { Report(ps,REP_ERROR,"Can not add element - missing .struct"); return(-1); } + + /* Make sure its not a too long */ + if( strlen(Name)>=STRUCT_NAME_LEN ) + { Report(ps,REP_ERROR,"Element name too long"); return(-1); } + + /* Make sure its not a reserved word */ + if( CheckTokenType(Name)!=TOKENTYPE_UNRESERVED ) + { Report(ps,REP_ERROR,"Illegal use of reserved word '%s'",Name); return(0); } + + /* Check for too many elements */ + if( pst->Elements==STRUCT_MAX_ELEM ) + { Report(ps,REP_ERROR,"Max element count (%d) exceeded",STRUCT_MAX_ELEM); return(-1); } + + /* Check for duplicate element name */ + for( i=0; iElements; i++ ) + if( !strcmp(Name,pst->ElemName[i]) ) + break; + if( i!= pst->Elements ) + { Report(ps,REP_ERROR,"Duplicate element name"); return(-1); } + + /* Add the element */ + strcpy( pst->ElemName[pst->Elements], Name ); + pst->Offset[pst->Elements] = pst->TotalSize; + pst->Size[pst->Elements] = size; + pst->TotalSize += size; + + if( Pass==1 && (Options & OPTION_DEBUG) ) + printf("%s(%5d) : DOTCMD : Element '%s' declared, offset=%d, size=%d\n", + ps->SourceName,ps->CurrentLine,pst->ElemName[pst->Elements], + pst->Offset[pst->Elements],pst->Size[pst->Elements]); + + pst->Elements++; + + return(0); +} + + +/* +// StructAssign +// +// Assign a structure to an instance +// +// Returns 0 on success, -1 on error +*/ +int StructAssign( SOURCEFILE *ps, char *structName, char *rsName, + char *reName, char *defName ) +{ + STRUCT *pst; + ASSIGN *pas; + PRU_ARG rs, re; + char tmpData[EQUATE_DATA_LEN]; + uint startOff,endOff,tmp,rangeCheck; + int i; + + if( pStructCurrent ) + { Report(ps,REP_ERROR,"Cannot assign while defining a structure"); return(-1); } + if( !pScopeCurrent ) + { Report(ps,REP_ERROR,"Cannot assign outside of a scope"); return(-1); } + + if( strcmp( reName, "*" ) ) + rangeCheck = 1; + else + rangeCheck = 0; + + /* Get the register parameters */ + if( !GetRegister( ps, 2, rsName, &rs, 0, 0 ) ) + return -1; + if( rangeCheck && !GetRegister( ps, 3, reName, &re, 0, 0 ) ) + return -1; + + /* Set the struct */ + pst = StructFind( structName ); + if( !pst ) + { Report(ps,REP_ERROR,"Structure '%s' not defined",structName); return(-1); } + + + if( !(Options & OPTION_BIGENDIAN) ) + { + /* + // ** Little Endian Version ** + */ + + /* See if the range is ok */ + startOff = rs.Value * 4; + switch( rs.Field ) + { + case FIELDTYPE_15_8: + case FIELDTYPE_23_8: + startOff += 1; + break; + case FIELDTYPE_23_16: + case FIELDTYPE_31_16: + startOff += 2; + break; + case FIELDTYPE_31_24: + startOff += 3; + break; + } + if( rangeCheck ) + { + endOff = re.Value * 4; + switch( re.Field ) + { + case FIELDTYPE_7_0: + endOff += 1; + break; + case FIELDTYPE_15_8: + case FIELDTYPE_15_0: + endOff += 2; + break; + case FIELDTYPE_23_16: + case FIELDTYPE_23_8: + endOff += 3; + break; + case FIELDTYPE_31_24: + case FIELDTYPE_31_16: + case FIELDTYPE_31_0: + endOff += 4; + break; + } + tmp = startOff + pst->TotalSize; + + if( tmp != endOff ) + { + if( !(tmp&3) ) + GetRegname( ps, 0, tmpData, tmp-4, 4 ); + else if( !(tmp&1) ) + GetRegname( ps, 0, tmpData, tmp-2, 2 ); + else + GetRegname( ps, 0, tmpData, tmp-1, 1 ); + Report(ps,REP_ERROR,"Range error, parameter 3 should be '%s'",tmpData); + return -1; + } + } + } + else + { + /* + // ** Big Endian Version ** + */ + + /* See if the range is ok */ + startOff = rs.Value * 4; + switch( rs.Field ) + { + case FIELDTYPE_23_8: + case FIELDTYPE_23_16: + startOff += 1; + break; + case FIELDTYPE_15_8: + case FIELDTYPE_15_0: + startOff += 2; + break; + case FIELDTYPE_7_0: + startOff += 3; + break; + } + if( rangeCheck ) + { + endOff = re.Value * 4; + switch( re.Field ) + { + case FIELDTYPE_31_24: + endOff += 1; + break; + case FIELDTYPE_23_16: + case FIELDTYPE_31_16: + endOff += 2; + break; + case FIELDTYPE_15_8: + case FIELDTYPE_23_8: + endOff += 3; + break; + case FIELDTYPE_7_0: + case FIELDTYPE_15_0: + case FIELDTYPE_31_0: + endOff += 4; + break; + } + tmp = startOff + pst->TotalSize; + + if( tmp != endOff ) + { + if( !(tmp&3) ) + GetRegname( ps, 0, tmpData, tmp-4, 4 ); + else if( !(tmp&1) ) + GetRegname( ps, 0, tmpData, tmp-2, 2 ); + else + GetRegname( ps, 0, tmpData, tmp-1, 1 ); + Report(ps,REP_ERROR,"Range error, parameter 3 should be '%s'",tmpData); + return -1; + } + } + } + + /* Alignment check pass */ + tmp = startOff; + for(i=0; iElements; i++) + { + if( GetRegname( ps, i+1, tmpData, tmp, pst->Size[i] )<0 ) + return(-1); + tmp += pst->Size[i]; + } + + if( !(pas = AssignCreate( ps, &pScopeCurrent->pAssignList, defName )) ) + return(-1); + + pas->Elements = pst->Elements; + pas->TotalSize = pst->TotalSize; + + /* Equate create pass */ + for(i=0; iElements; i++) + { + GetRegname( ps, i+1, tmpData, startOff, pst->Size[i] ); + if( !i ) + { + strcpy(pas->Name,defName); + strcpy(pas->BaseReg,tmpData); + } + pas->Offset[i] = pst->Offset[i]; + pas->Size[i] = pst->Size[i]; + strcpy(pas->ElemName[i],pst->ElemName[i]); + strcpy(pas->MappedReg[i],tmpData); + startOff += pst->Size[i]; + } + + return(0); +} + + +/* +// Struct Param Process +// +// Processes the supplied argument for stucture references or SIZE/OFFSET +// operations. When found, the structure definition is used to substitute +// in the proper register or numeric value. +// +// The string 'source' is assumed to be be able to hold a length of +// at least 'TOKEN_MAX_LEN' bytes. +// +// Returns 0 for OK, or -1 for Fatal Error +// +*/ +int StructParamProcess( SOURCEFILE *ps, int ParamIdx, char *source ) +{ + char substr[TOKEN_MAX_LEN*2]; + int subidx,srcidx; + char tmpname[STRUCT_NAME_LEN],*pNewName; + int i,j,onedot; + + srcidx=0; + subidx=0; + while(source[srcidx]) + { + /* Scan past any number constants */ + if( source[srcidx]>='0' && source[srcidx]<='9' ) + { + do + { + substr[subidx++] = source[srcidx++]; + } while( LabelChar(source[srcidx],0) ); + } + /* Scan past any non-label charaters */ + else if( !LabelChar(source[srcidx],1) ) + substr[subidx++] = source[srcidx++]; + else + { + /* Scan in the candidate name */ + onedot = 0; + tmpname[0] = source[srcidx]; + for(i=1; i= TOKEN_MAX_LEN ) + return -1; + strcpy( source, substr ); + + return(0); +} + + +/* +// CheckStruct +// +// Searches for struct template or struct by name. +// +// Returns 1 on success, 0 on error +*/ +int CheckStruct( char *name ) +{ + if( StructFind(name) || AssignFind(name) || ScopeFind(name) ) + return(1); + return(0); +} + + +/*=================================================================== +// +// Private Functions +// +====================================================================*/ + +/* +// StructFind +// +// Searches for a struct record by name. If found, returns the record pointer. +// +// Returns STRUCT * on success, 0 on error +*/ +static STRUCT *StructFind( char *Name ) +{ + STRUCT *pst; + + pst = pStructList; + while( pst ) + { + if( !strcmp( Name, pst->Name ) ) + break; + pst = pst->pNext; + } + return(pst); +} + + +/* +// StructCreate +// +// Create a new structure record +// +// Returns STRUCT * on success, 0 on error +*/ +static STRUCT *StructCreate( SOURCEFILE *ps, char *Name ) +{ + STRUCT *pst; + + /* Make sure this name is OK to use */ + if( !CheckName(ps,Name) ) + return(0); + + /* Make sure its not too long */ + if( strlen(Name)>=STRUCT_NAME_LEN ) + { Report(ps,REP_ERROR,"Structure name too long"); return(0); } + + /* Allocate a new record */ + pst = malloc(sizeof(STRUCT)); + if( !pst ) + { Report(ps,REP_ERROR,"Memory allocation failed"); return(0); } + + strcpy( pst->Name, Name ); + pst->Elements = 0; + pst->TotalSize = 0; + + /* Put this equate in the master list */ + pst->pPrev = 0; + pst->pNext = pStructList; + pStructList = pst; + + if( Pass==1 && (Options & OPTION_DEBUG) ) + printf("%s(%5d) : DOTCMD : Structure '%s' declared\n", + ps->SourceName,ps->CurrentLine,pst->Name); + + return(pst); +} + + +/* +// StructDestroy +// +// Frees a structure record. +// +// void +*/ +static void StructDestroy( STRUCT *pst ) +{ + if( !pst->pPrev ) + pStructList = pst->pNext; + else + pst->pPrev->pNext = pst->pNext; + + if( pst->pNext ) + pst->pNext->pPrev = pst->pPrev; + + free(pst); +} + + + +/* +// GetRegname +// +// Checks alignment and returns a string of the proper register +// +// Returns 0 on success, -1 on error +*/ +static int GetRegname( SOURCEFILE *ps, uint element, char *str, uint off, uint size ) +{ + if( ((off%4)+size) > 4 ) + { Report(ps,REP_ERROR,"Register alignment error on element %d",element); return(-1); } + + if( !(Options & OPTION_BIGENDIAN) ) + { + /* + // ** Little Endian Version ** + */ + if( size==4 ) + sprintf( str, "R%d", off/4 ); + else if( size==2 ) + sprintf( str, "R%d.w%d", off/4, off%4 ); + else + sprintf( str, "R%d.b%d", off/4, off%4 ); + } + else + { + /* + // ** Big Endian Version ** + */ + if( size==4 ) + sprintf( str, "R%d", off/4 ); + else if( size==2 ) + sprintf( str, "R%d.w%d", off/4, 2-off%4 ); + else + sprintf( str, "R%d.b%d", off/4, 3-off%4 ); + } + + return(0); +} + +/* +// AssignFind +// +// Searches for an assignment record by name. If found, returns the record pointer. +// +// Returns STRUCT * on success, 0 on error +*/ +static ASSIGN *AssignFind( char *Name ) +{ + SCOPE *psc; + ASSIGN *pas; + + psc = pScopeList; + while( psc ) + { + if( psc->Flags&SCOPE_FLG_OPEN ) + { + pas = psc->pAssignList; + while( pas ) + { + if( !strcmp( Name, pas->Name ) ) + return(pas); + pas = pas->pNext; + } + } + psc = psc->pNext; + } + return(0); +} + + +/* +// AssignCreate +// +// Create a new assignment record +// +// Returns STRUCT * on success, 0 on error +*/ +static ASSIGN *AssignCreate( SOURCEFILE *ps, ASSIGN **pList, char *Name ) +{ + ASSIGN *pas; + + /* Make sure this name is OK to use */ + if( !CheckName(ps,Name) ) + return(0); + + /* Make sure the name is not too long */ + if( strlen(Name)>=STRUCT_NAME_LEN ) + { Report(ps,REP_ERROR,"Structure name too long"); return(0); } + + /* Allocate a new record */ + pas = malloc(sizeof(ASSIGN)); + if( !pas ) + { Report(ps,REP_ERROR,"Memory allocation failed"); return(0); } + + strcpy( pas->Name, Name ); + + /* Put this equate in the master list */ + pas->pPrev = 0; + pas->pNext = *pList; + *pList = pas; + + if( Pass==1 && (Options & OPTION_DEBUG) ) + printf("%s(%5d) : DOTCMD : Assignment '%s' declared\n", + ps->SourceName,ps->CurrentLine,pas->Name); + + return(pas); +} + + +/* +// AssignDestroy +// +// Frees an assignment record. +// +// void +*/ +static void AssignDestroy( ASSIGN **pList, ASSIGN *pas ) +{ + if( !pas->pPrev ) + *pList = pas->pNext; + else + pas->pPrev->pNext = pas->pNext; + + if( pas->pNext ) + pas->pNext->pPrev = pas->pPrev; + + free(pas); +} + + +/* +// Struct Name Check +// +// Returns NULL for not match, or replacement string ptr +// +*/ +static char *StructNameCheck( char *source ) +{ + ASSIGN *pas; + char name[STRUCT_NAME_LEN]; + int i,off,more=0; + + for(i=0; iBaseReg); + + off = i+1; + for(i=0; (i+off)Elements; i++ ) + { + if( !strcmp(name,pas->ElemName[i]) ) + return(pas->MappedReg[i]); + } + return(0); +} + + + +/* +// Struct Value Operand +// +// Returns 0 for OK, or -1 for Fatal Error +*/ +static int StructValueOperand( char *source, int CmdType, uint *pValue ) +{ + ASSIGN *pas; + STRUCT *pst; + char name[STRUCT_NAME_LEN]; + char name2[STRUCT_NAME_LEN]; + char *ext = 0; + int i; + + for(i=0; iTotalSize; + else + *pValue = 0; + return(0); + } + + for( i=0; iElements; i++ ) + { + if( !strcmp(name2,pas->ElemName[i]) ) + break; + } + + if( i==pas->Elements ) + return(-1); + + if( CmdType==SVO_SIZEOF ) + { + if(ext) + return( GetFinalSize( ext, pas->Size[i], pValue ) ); + *pValue = pas->Size[i]; + } + else + { + if(ext) + return( GetFinalOffset( ext, pas->Size[i], pas->Offset[i], pValue ) ); + *pValue = pas->Offset[i]; + } + return(0); + } + + pst = StructFind(name); + if( pst ) + { + if( !strlen(name2) ) + { + if( CmdType==SVO_SIZEOF ) + *pValue = pst->TotalSize; + else + *pValue = 0; + return(0); + } + + for( i=0; iElements; i++ ) + { + if( !strcmp(name2,pst->ElemName[i]) ) + break; + } + + if( i==pst->Elements ) + return(-1); + + if( CmdType==SVO_SIZEOF ) + { + if(ext) + return( GetFinalSize( ext, pst->Size[i], pValue ) ); + *pValue = pst->Size[i]; + } + else + { + if(ext) + return( GetFinalOffset( ext, pst->Size[i], pst->Offset[i], pValue ) ); + *pValue = pst->Offset[i]; + } + return(0); + } + + return -1; +} + + +/* +// GetFinalSize - For subfield on struct operand +// +// Returns 0 for OK, or -1 for Fatal Error +*/ +static int GetFinalSize( char *ext, uint Size, uint *pValue ) +{ + char c; + uint val; + + if( strlen(ext) > 2 ) + return -1; + c = toupper(ext[0]); + val = ext[1] - '0'; + switch(c) + { + case 'B': + if( (val+1)>Size ) + return -1; + *pValue = 1; + return(0); + case 'W': + if( (val+2)>Size ) + return -1; + *pValue = 2; + return(0); + } + return(-1); +} + +/* +// GetFinalOffset - For subfield on struct operand +// +// Returns 0 for OK, or -1 for Fatal Error +*/ +static int GetFinalOffset( char *ext, uint Size, uint Offset, uint *pValue ) +{ + char c; + uint val; + + if( strlen(ext) > 2 ) + return -1; + c = toupper(ext[0]); + val = ext[1] - '0'; + switch(c) + { + case 'B': + if( (val+1)>Size ) + return -1; + if( Options & OPTION_BIGENDIAN ) + val = Size-val-1; + *pValue = Offset+val; + return(0); + case 'W': + if( (val+2)>Size ) + return -1; + if( Options & OPTION_BIGENDIAN ) + val = Size-val-2; + *pValue = Offset+val; + return(0); + } + return(-1); +} + + +/* +// ScopeCreate +// +// Create a new scope record +// +// Returns STRUCT * on success, 0 on error +*/ +static SCOPE *ScopeCreate( SOURCEFILE *ps, char *Name ) +{ + SCOPE *psc; + + /* Make sure this name is OK to use */ + if( !CheckName(ps,Name) ) + return(0); + + /* Make sure its not too long */ + if( strlen(Name)>=SCOPE_NAME_LEN ) + { Report(ps,REP_ERROR,"Scope name too long"); return(0); } + + /* Allocate a new record */ + psc = malloc(sizeof(SCOPE)); + if( !psc ) + { Report(ps,REP_ERROR,"Memory allocation failed"); return(0); } + + strcpy( psc->Name, Name ); + psc->Flags = SCOPE_FLG_OPEN; + psc->pParent = pScopeCurrent; + psc->pAssignList = 0; + + /* Put this equate in the master list */ + psc->pPrev = 0; + psc->pNext = pScopeList; + pScopeList = psc; + pScopeCurrent = psc; + + if( Pass==1 && (Options & OPTION_DEBUG) ) + { + if(ps) + printf("%s(%5d) : ",ps->SourceName,ps->CurrentLine); + printf("DOTCMD : Scope '%s' declared\n",psc->Name); + } + + return(psc); +} + + +/* +// ScopeDestroy +// +// Frees a scope record. +// +// void +*/ +static void ScopeDestroy( SCOPE *psc ) +{ + if( psc->Flags & SCOPE_FLG_OPEN ) + ScopeClose( psc ); + + while( psc->pAssignList ) + AssignDestroy( &psc->pAssignList, psc->pAssignList ); + + if( !psc->pPrev ) + pScopeList = psc->pNext; + else + psc->pPrev->pNext = psc->pNext; + + if( psc->pNext ) + psc->pNext->pPrev = psc->pPrev; + + free(psc); +} + + +/* +// ScopeClose +// +// Closes a scope record. +// +// void +*/ +static void ScopeClose( SCOPE *psc ) +{ + psc->Flags &= ~SCOPE_FLG_OPEN; + + while( pScopeCurrent && !(pScopeCurrent->Flags&SCOPE_FLG_OPEN) ) + pScopeCurrent = pScopeCurrent->pParent; +} + + +/* +// ScopeFind +// +// Finds a scope record. +// +// void +*/ +static SCOPE *ScopeFind( char *Name ) +{ + SCOPE *psc; + + psc = pScopeList; + while( psc ) + { + if( !strcmp( Name, psc->Name ) ) + break; + psc = psc->pNext; + } + return(psc); +} + + diff --git a/am335x/pasm/pru_ins.h b/am335x/pasm/pru_ins.h new file mode 100644 index 00000000..f367b792 --- /dev/null +++ b/am335x/pasm/pru_ins.h @@ -0,0 +1,176 @@ +/* + * pru_ins.h + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +/*=========================================================================== + * Copyright (c) Texas Instruments Inc 2010-12 + * + * Use of this software is controlled by the terms and conditions found in the + * license agreement under which this software has been supplied or provided. + * ============================================================================ + */ + +/*=========================================================================== +// PASM - PRU Assembler +//--------------------------------------------------------------------------- +// +// File : pru_ins.h +// +// Description: +// Defines a data structre PRU_INST that can completely describe a +// PRU opcode. +// +//--------------------------------------------------------------------------- +// Revision: +// 21-Jun-13: 0.84 - Open source version +============================================================================*/ + +typedef struct _PRU_ARG { + uint Type; + uint Flags; /* Flags for RegisterBit type */ +#define PA_FLG_REGPOINTER 0x0001 +#define PA_FLG_POSTINC 0x0002 +#define PA_FLG_PREDEC 0x0004 + uint Value; /* Reg #, Imm Val, Count Val */ + uint Field; /* Field for Registers */ + uint Bit; /* Bit # for RegisterBit type */ +} PRU_ARG; + +#define ARGTYPE_REGISTER 1 /* Standard register and field */ +#define ARGTYPE_IMMEDIATE 2 /* Immediate value */ +#define ARGTYPE_COUNT 3 /* Count for burst */ +#define ARGTYPE_R0BYTE 4 /* Byte from R0 */ +#define ARGTYPE_CONSTANT 5 /* Constant Table Index */ +#define ARGTYPE_OFFSET 6 /* 10 bit offset for jumps */ +#define ARGTYPE_REGISTERBIT 7 /* Register in Rxx.Txx format Field=bitno */ + +#define FIELDTYPE_7_0 0 /* Bits 7:0 */ +#define FIELDTYPE_15_8 1 /* Bits 15:8 */ +#define FIELDTYPE_23_16 2 /* Bits 23:16 */ +#define FIELDTYPE_31_24 3 /* Bits 31:24 */ +#define FIELDTYPE_15_0 4 /* Bits 15:0 */ +#define FIELDTYPE_23_8 5 /* Bits 23:8 */ +#define FIELDTYPE_31_16 6 /* Bits 31:16 */ +#define FIELDTYPE_31_0 7 /* Bits 31:0 */ + +#define FIELDTYPE_OFF_0 0 /* Offset bit 0 */ +#define FIELDTYPE_OFF_8 1 /* Offset bit 8 */ +#define FIELDTYPE_OFF_16 2 /* Offset bit 16 */ +#define FIELDTYPE_OFF_24 3 /* Offset bit 24 */ + +extern char *FieldText[]; + +typedef struct _PRU_INST { + uint Op; /* Operation */ + uint ArgCnt; /* Argument Count */ + PRU_ARG Arg[4]; /* Arguments */ +} PRU_INST; + +#define OP_ADD 1 +#define OP_ADC 2 +#define OP_SUB 3 +#define OP_SUC 4 +#define OP_LSL 5 +#define OP_LSR 6 +#define OP_RSB 7 +#define OP_RSC 8 +#define OP_AND 9 +#define OP_OR 10 +#define OP_XOR 11 +#define OP_NOT 12 +#define OP_MIN 13 +#define OP_MAX 14 +#define OP_CLR 15 +#define OP_SET 16 +#define OP_LDI 17 +#define OP_LBBO 18 +#define OP_LBCO 19 +#define OP_SBBO 20 +#define OP_SBCO 21 +#define OP_LFC 22 +#define OP_STC 23 +#define OP_JAL 24 +#define OP_JMP 25 +#define OP_QBGT 26 +#define OP_QBLT 27 +#define OP_QBEQ 28 +#define OP_QBGE 29 +#define OP_QBLE 30 +#define OP_QBNE 31 +#define OP_QBA 32 +#define OP_QBBS 33 +#define OP_QBBC 34 +#define OP_LMBD 35 +#define OP_CALL 36 +#define OP_WBC 37 +#define OP_WBS 38 +#define OP_MOV 39 +#define OP_MVIB 40 +#define OP_MVIW 41 +#define OP_MVID 42 +#define OP_SCAN 43 +#define OP_HALT 44 +#define OP_SLP 45 +#define OP_RET 46 +#define OP_ZERO 47 +#define OP_FILL 48 +#define OP_XIN 49 +#define OP_XOUT 50 +#define OP_XCHG 51 +#define OP_SXIN 52 +#define OP_SXOUT 53 +#define OP_SXCHG 54 +#define OP_LOOP 55 +#define OP_ILOOP 56 +#define OP_NOP0 57 +#define OP_NOP1 58 +#define OP_NOP2 59 +#define OP_NOP3 60 +#define OP_NOP4 61 +#define OP_NOP5 62 +#define OP_NOP6 63 +#define OP_NOP7 64 +#define OP_NOP8 65 +#define OP_NOP9 66 +#define OP_NOPA 67 +#define OP_NOPB 68 +#define OP_NOPC 69 +#define OP_NOPD 70 +#define OP_NOPE 71 +#define OP_NOPF 72 +#define OP_MAXIDX 72 + +extern char *OpText[]; + From 67e98c42f8991005aa4980b0c6c905acb918201d Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 31 Jul 2013 20:57:28 -0400 Subject: [PATCH 019/332] Reworked makefiles to work for cross compiling pasm and pru lib --- Makefile | 14 ++++++++++---- am335x/app_loader/interface/Makefile | 2 +- am335x/pasm/Makefile | 27 +++++++++++++++++++++++++++ am335x/pasm/dosbuild.bat | 3 --- am335x/pasm/linuxbuild | 4 ---- am335x/pasm/macbuild | 4 ---- 6 files changed, 38 insertions(+), 16 deletions(-) create mode 100755 am335x/pasm/Makefile delete mode 100644 am335x/pasm/dosbuild.bat delete mode 100755 am335x/pasm/linuxbuild delete mode 100644 am335x/pasm/macbuild diff --git a/Makefile b/Makefile index 223cdf3b..d1b3c4dc 100755 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -#CROSS_COMPILE?=arm-arago-linux-gnueabi- +CROSS_COMPILE?=arm-linux-gnueabi- -LIBDIR_APP_LOADER?=../../app_loader/lib -INCDIR_APP_LOADER?=../../app_loader/include +LIBDIR_APP_LOADER?=./am335x/app_loader/lib +INCDIR_APP_LOADER?=./am335x/app_loader/include CFLAGS += \ -std=c99 \ @@ -17,7 +17,7 @@ LDFLAGS += \ -lprussdrv \ -lpthread \ -PASM := ../../utils/pasm_2 +PASM := ./am335x/pasm/pasm TARGET := rgb-test _DEPS = @@ -51,3 +51,9 @@ dts: LEDscape.dts fi dtc -O dtb -o /lib/firmware/BB-LEDSCAPE-00A0.dtbo -b 0 -@ LEDscape.dts echo BB-LEDSCAPE > $(SLOT_FILE) + + +# Libraries and compiler +depend: + $(MAKE) -C am335x/app_loader/interface + cd ./am335x/pasm ; ./linuxbuild diff --git a/am335x/app_loader/interface/Makefile b/am335x/app_loader/interface/Makefile index 0cb0893f..4b9324c7 100644 --- a/am335x/app_loader/interface/Makefile +++ b/am335x/app_loader/interface/Makefile @@ -1,6 +1,6 @@ ROOTDIR = .. TARGET = libprussdrv -CROSS_COMPILE?=arm-arago-linux-gnueabi- +CROSS_COMPILE?=arm-linux-gnueabi- CC = $(CROSS_COMPILE)gcc AR = $(CROSS_COMPILE)ar diff --git a/am335x/pasm/Makefile b/am335x/pasm/Makefile new file mode 100755 index 00000000..6482c98d --- /dev/null +++ b/am335x/pasm/Makefile @@ -0,0 +1,27 @@ +# Builds with whatever the host format is +CC := gcc + +CFLAGS += \ + -O3 \ + -W \ + -Wall \ + -D_UNIX_ \ + +OBJS := \ + pasm.o \ + pasmpp.o \ + pasmexp.o \ + pasmop.o \ + pasmdot.o \ + pasmstruct.o \ + pasmmacro.o \ + +all: pasm + +pasm: $(OBJS) + $(CC) -o $@ $^ + +clean: + $(RM) -f *.o + + diff --git a/am335x/pasm/dosbuild.bat b/am335x/pasm/dosbuild.bat deleted file mode 100644 index 3db51046..00000000 --- a/am335x/pasm/dosbuild.bat +++ /dev/null @@ -1,3 +0,0 @@ -cl -W3 -D_CRT_SECURE_NO_WARNINGS pasm.c pasmpp.c pasmexp.c pasmop.c pasmdot.c pasmstruct.c pasmmacro.c /Fe..\pasm.exe -del *.obj - diff --git a/am335x/pasm/linuxbuild b/am335x/pasm/linuxbuild deleted file mode 100755 index 550101e9..00000000 --- a/am335x/pasm/linuxbuild +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -gcc -Wall -D_UNIX_ pasm.c pasmpp.c pasmexp.c pasmop.c pasmdot.c pasmstruct.c pasmmacro.c -o ../pasm - - diff --git a/am335x/pasm/macbuild b/am335x/pasm/macbuild deleted file mode 100644 index 37f9a3e8..00000000 --- a/am335x/pasm/macbuild +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -gcc -Wall -D_UNIX_ pasm.c pasmpp.c pasmexp.c pasmop.c pasmdot.c pasmstruct.c pasmmacro.c -o ../pasm.mac - - From d03a8f7c3c7ab4912bf3e5259114f2ece3a85819 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 31 Jul 2013 20:57:42 -0400 Subject: [PATCH 020/332] ignore more binaries --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index e31c2a9e..306e1d47 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ *.bin pcb/*.b[^r][^d] pcb/*.p[^c][^b] +rgb-test +am335x/pasm/pasm From dfd841767ed747657c569a8c1c199238b2d93861 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 31 Jul 2013 21:04:28 -0400 Subject: [PATCH 021/332] Try to guess if we are cross compiling --- Makefile | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index d1b3c4dc..68c316d1 100755 --- a/Makefile +++ b/Makefile @@ -1,4 +1,17 @@ -CROSS_COMPILE?=arm-linux-gnueabi- +ifeq ($(shell uname -m),armv7l) +# We are on the BeagleBone Black itself; +# do not cross compile. +export CROSS_COMPILE:= +else +# We are not on the BeagleBone and might be cross compiling. +# If the environment does not set CROSS_COMPILE, set our +# own. Install a cross compiler with something like: +# +# sudo apt-get install gcc-arm-linux-gnueabi +# +export CROSS_COMPILE?=arm-linux-gnueabi- +#export CROSS_COMPILE +endif LIBDIR_APP_LOADER?=./am335x/app_loader/lib INCDIR_APP_LOADER?=./am335x/app_loader/include @@ -56,4 +69,4 @@ dts: LEDscape.dts # Libraries and compiler depend: $(MAKE) -C am335x/app_loader/interface - cd ./am335x/pasm ; ./linuxbuild + $(MAKE) -C am335x/pasm From 17e8e15686c6ea519b0e6e6614a1c9004f870fd4 Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Thu, 1 Aug 2013 15:38:00 +0800 Subject: [PATCH 022/332] Fully routed, 8mil clearances, 10mil minimum traces --- pcb/LEDscape.brd | 1239 +++++++++++++++++++++++++++++++--------------- 1 file changed, 834 insertions(+), 405 deletions(-) diff --git a/pcb/LEDscape.brd b/pcb/LEDscape.brd index 494e12c0..b5fcc89f 100644 --- a/pcb/LEDscape.brd +++ b/pcb/LEDscape.brd @@ -6,7 +6,7 @@ - + @@ -1091,12 +1091,12 @@ Please make sure your boards conform to these design rules. - - - - - - + + + + + + @@ -1105,7 +1105,7 @@ Please make sure your boards conform to these design rules. - + @@ -1251,23 +1251,23 @@ Please make sure your boards conform to these design rules. - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + @@ -1293,11 +1293,11 @@ Please make sure your boards conform to these design rules. - - - - - + + + + + @@ -1308,14 +1308,14 @@ Please make sure your boards conform to these design rules. - - - - + + + + - + @@ -1353,7 +1353,7 @@ Please make sure your boards conform to these design rules. - + @@ -1417,20 +1417,20 @@ Please make sure your boards conform to these design rules. - - - + + + - - - - - - + + + + + + @@ -1439,18 +1439,30 @@ Please make sure your boards conform to these design rules. - - - + + + - - - - - - + + + + + + + + + + + + + + + + + + @@ -1468,248 +1480,409 @@ Please make sure your boards conform to these design rules. - + + + + + + + + + + + + + - + + + + + + + + + + + + - + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + - + + + + + - + + + + + - + + + + - + + + + + + + + + - - - - - + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + - + + + + + + + - + + + + + + - + + + + + + + + - + + + + + + + - + + + + + - + + + + + - + + + + - + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - + + + + + - - - - - - - + + + + + - + + + + + + + + + + - + + + + + + + + - - - + + + - - - + + + + + @@ -1722,16 +1895,16 @@ Please make sure your boards conform to these design rules. - - - - - - + + + + + + - - + + @@ -1739,54 +1912,79 @@ Please make sure your boards conform to these design rules. - - - - + + + + + + + + + + + + - - - + + + + + + + + + + + + + + - - - + + + + + - - - - - + + + + + + + - - - + + + + - - - - - - + + + + + + + @@ -1795,9 +1993,9 @@ Please make sure your boards conform to these design rules. - - - + + + @@ -1807,42 +2005,40 @@ Please make sure your boards conform to these design rules. - - - + + + - - - - - + + + - - + + - - - + + + - + - - + + @@ -1855,9 +2051,9 @@ Please make sure your boards conform to these design rules. - - - + + + @@ -1867,112 +2063,189 @@ Please make sure your boards conform to these design rules. - + + + + + + + + + + + + + - + + + + + + + + + + + + - - - + + + - + + + + + + + - + + + + + + - + + + + + - + + + + + - - - + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + @@ -1986,8 +2259,18 @@ Please make sure your boards conform to these design rules. - - + + + + + + + + + + + + @@ -2022,28 +2305,31 @@ Please make sure your boards conform to these design rules. - - - - - - + + + + + + + + + - - - + + + @@ -2060,26 +2346,28 @@ Please make sure your boards conform to these design rules. - - - + + + - - - - + + + + + - + + @@ -2119,22 +2407,29 @@ Please make sure your boards conform to these design rules. - - - - - - - - - - + + + + + + + + + + + + + - + + + + + @@ -2144,49 +2439,92 @@ Please make sure your boards conform to these design rules. - - - - - - - - + + + + + + + + - - - - - + + + + + + + + - - - + + + - + + + + + + + + + + + - + + + + + + + + + + - + + + + + + + + + + + + + + - + + + + + + + + + @@ -2194,102 +2532,155 @@ Please make sure your boards conform to these design rules. - - - - + + + + - - + + - - - - - - - + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + - - - - - - - + + + + - + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - + + + + - - - - - + + + + + + - + + + + + + + + + + - + + + + + + + + + - - - + + + @@ -2300,38 +2691,63 @@ Please make sure your boards conform to these design rules. - - - + + + - - - - - + + + + + - + + + + + + + + - + + + + + + + + + - + + + + - + + + + + + + + @@ -2385,25 +2801,38 @@ Please make sure your boards conform to these design rules. - - - - - - - - + + + + + + - - - - - + + + + + - - + + + + + + + + + + + + + + + + + From 642200ef464f0ee1d050dd87b6e75658362b71ce Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Thu, 1 Aug 2013 18:19:39 +0800 Subject: [PATCH 023/332] Add some expansion IO (conflicts with HDMI, beware), and fix 8x2 header --- pcb/LEDscape.brd | 735 +++++++++++++++----------- pcb/LEDscape.lbr | 4 +- pcb/LEDscape.sch | 1323 ++++++++++++++++++++++++++++++---------------- pcb/TODO | 13 +- 4 files changed, 1305 insertions(+), 770 deletions(-) diff --git a/pcb/LEDscape.brd b/pcb/LEDscape.brd index b5fcc89f..463c2812 100644 --- a/pcb/LEDscape.brd +++ b/pcb/LEDscape.brd @@ -152,12 +152,16 @@ -+ -- -- -- -- -- ++ +- +- +- +- +- +LEDscape LED Controller +By Matt Mets and Trammel Hudson +Rev A 2013-08-01 + @@ -227,8 +231,8 @@ http://www.maxim-ic.com .. MAX3223-MAX3243.pdf - - + + @@ -830,215 +834,6 @@ chip - -<b>Molex Connectors</b><p> -<author>Created by librarian@cadsoft.de</author> - - -<b>STACKED MODULAR JACK CATEGORY 5</b><p> -Source: http://www.molex.com/pdm_docs/sd/445200006_sd.pdf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - <h3>SparkFun Electronics' preferred foot prints</h3> In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> @@ -1066,6 +861,172 @@ We've spent an enormous amount of time creating and checking these footprints an >NAME >VALUE + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + +Library of parts that we use for our Blinkiverse designs. Some parts copied (and modified) from the excellent Sparkfun libraries. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1316,15 +1277,12 @@ Please make sure your boards conform to these design rules. - - - - - - - - - + + + + + + @@ -1463,6 +1421,9 @@ Please make sure your boards conform to these design rules. + + + @@ -1590,47 +1551,47 @@ Please make sure your boards conform to these design rules. - + - - - - - + + + + + - + - + - - - - - - + + + + + + - + - - - - - - + + + + + + @@ -1638,7 +1599,7 @@ Please make sure your boards conform to these design rules. - + @@ -1646,13 +1607,13 @@ Please make sure your boards conform to these design rules. - - - - - + + + + + - + @@ -1662,13 +1623,13 @@ Please make sure your boards conform to these design rules. - - - - - - - + + + + + + + @@ -1678,13 +1639,13 @@ Please make sure your boards conform to these design rules. - - - - - - - + + + + + + + @@ -2146,13 +2107,13 @@ Please make sure your boards conform to these design rules. - - - - - - - + + + + + + + @@ -2168,13 +2129,13 @@ Please make sure your boards conform to these design rules. - - - - - - - + + + + + + + @@ -2185,14 +2146,14 @@ Please make sure your boards conform to these design rules. - - - - - - + + + + + + - + @@ -2202,26 +2163,26 @@ Please make sure your boards conform to these design rules. - - - - - - + + + + + + - + - - - - - - - + + + + + + + @@ -2236,13 +2197,13 @@ Please make sure your boards conform to these design rules. - - - - - - - + + + + + + + @@ -2263,12 +2224,12 @@ Please make sure your boards conform to these design rules. - - - - - - + + + + + + @@ -2833,6 +2794,148 @@ Please make sure your boards conform to these design rules. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcb/LEDscape.lbr b/pcb/LEDscape.lbr index 5164c18e..eb5a79f2 100644 --- a/pcb/LEDscape.lbr +++ b/pcb/LEDscape.lbr @@ -143,8 +143,8 @@ - - + + diff --git a/pcb/LEDscape.sch b/pcb/LEDscape.sch index d8b25ec2..c7ffbf49 100644 --- a/pcb/LEDscape.sch +++ b/pcb/LEDscape.sch @@ -626,8 +626,8 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - + + @@ -3757,419 +3757,6 @@ Metric Code Size 5664 - -<b>Molex Connectors</b><p> -<author>Created by librarian@cadsoft.de</author> - - -<b>STACKED MODULAR JACK CATEGORY 5</b><p> -Source: http://www.molex.com/pdm_docs/sd/445200006_sd.pdf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - -<b>STACKED MODULAR JACK CATEGORY 5</b><p> -Source: http://www.molex.com/pdm_docs/sd/445200006_sd.pdf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <h3>SparkFun Electronics' preferred foot prints</h3> In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> @@ -4535,6 +4122,408 @@ will be further integrated into the Sparkfun Library for other footprints. It c + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + +This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place. +You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line). +This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace" +to hold the component in place. 0.005 has proven to be the perfect amount of "off-center" position when using our standard breakaway headers. +Although looks a little odd when you look at the bare footprint, once you have a header in there, the alteration is very hard to notice. Also, +if you push a header all the way into place, it is covered up entirely on the bottom side. This idea of altering the position of holes to aid alignment +will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins. + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + +>NAME +>VALUE + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + +>Name +>Value ++ +- +S + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + +>Name +>Value + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + +>Value +>Name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + @@ -4549,6 +4538,60 @@ will be further integrated into the Sparkfun Library for other footprints. It c + + + + + + + + +>VALUE +>NAME + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + + + + + + + + + + + + @@ -4751,6 +4794,221 @@ Standard 2-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + +<b>Header 3</b> +Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08232 with associated crimp pins and housings. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +.1" headers, two rows of 8 each + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4827,13 +5085,18 @@ Standard 2-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - + + + + + + @@ -4904,28 +5167,18 @@ Standard 2-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + @@ -5100,9 +5353,22 @@ Standard 2-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - + + + + + + + + + + + + + + @@ -5328,23 +5594,36 @@ Standard 2-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - + - + - + - - - - - + + + + + + + + + + + + + + + + + + @@ -6289,6 +6568,156 @@ Standard 2-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcb/TODO b/pcb/TODO index 31557f46..139ead2b 100644 --- a/pcb/TODO +++ b/pcb/TODO @@ -3,9 +3,12 @@ x-Add shield holes to back of 8x2 RJ45 header x-Flip board so the BBB is upside down (rather than the rest of the board) x-Verify RJ45 pinout x-Add ground connections --Fix case positions on RJ45 shield --Finish routing RJ45 section --Finish routing digital section +x-Fix case positions on RJ45 shield +x-Finish routing RJ45 section +x-Finish routing digital section +x-gpio on p8 pin ETHRPWM2B +x-Add extra pads for GPIO like the HDMI on p8 + +Future: -Add HRC logo --gpio on p8 pin 42(?) --Add extra pads for GPIO like the HDMI on p9 +-EEPROM for shield detection From 9faa9e69afb52f91fc5175eeb981a79d45353a86 Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Thu, 1 Aug 2013 18:38:19 +0800 Subject: [PATCH 024/332] Small cleanups; take part identifiers off silk, change outline of ethernet to tDocu --- pcb/LEDscape.brd | 119 ++++++++++++++++++++++++++++------------------- pcb/LEDscape.lbr | 46 +++++++++--------- pcb/LEDscape.sch | 46 +++++++++--------- 3 files changed, 117 insertions(+), 94 deletions(-) diff --git a/pcb/LEDscape.brd b/pcb/LEDscape.brd index 463c2812..fccbfbc3 100644 --- a/pcb/LEDscape.brd +++ b/pcb/LEDscape.brd @@ -34,8 +34,8 @@ - - + + @@ -58,8 +58,8 @@ - - + + @@ -158,10 +158,9 @@ - - - -LEDscape LED Controller -By Matt Mets and Trammel Hudson -Rev A 2013-08-01 - +LEDscape LED Controller +By Matt Mets and Trammel Hudson +Rev A 2013-08-01 @@ -223,35 +222,35 @@ http://www.maxim-ic.com .. MAX3223-MAX3243.pdf - - - - - + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + @@ -1212,53 +1211,61 @@ Please make sure your boards conform to these design rules. - + + - + + - + + - + + - + + - + + - + + - + + @@ -1269,18 +1276,34 @@ Please make sure your boards conform to these design rules. - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/pcb/LEDscape.lbr b/pcb/LEDscape.lbr index eb5a79f2..10c741e1 100644 --- a/pcb/LEDscape.lbr +++ b/pcb/LEDscape.lbr @@ -135,35 +135,35 @@ - - - - - + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/pcb/LEDscape.sch b/pcb/LEDscape.sch index c7ffbf49..52c8de1a 100644 --- a/pcb/LEDscape.sch +++ b/pcb/LEDscape.sch @@ -618,35 +618,35 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - - - - + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + From a061fffdba10281cd6f08d3710a3ed2456ac60bb Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Thu, 1 Aug 2013 23:49:44 +0800 Subject: [PATCH 025/332] Fix some ERC errors, a sad DRC one, and add an extra GPIO. --- pcb/LEDscape.brd | 215 ++++++------- pcb/LEDscape.lbr | 4 +- pcb/LEDscape.sch | 794 +++++++++++++++++++++++++---------------------- 3 files changed, 508 insertions(+), 505 deletions(-) diff --git a/pcb/LEDscape.brd b/pcb/LEDscape.brd index fccbfbc3..b85c090d 100644 --- a/pcb/LEDscape.brd +++ b/pcb/LEDscape.brd @@ -34,8 +34,8 @@ - - + + @@ -152,14 +152,14 @@ -+ -- -- -- -- -- ++ +- +- +- +- +- LEDscape LED Controller -By Matt Mets and Trammel Hudson +By Matt Mets and Trammel Hudson Rev A 2013-08-01 @@ -860,36 +860,6 @@ We've spent an enormous amount of time creating and checking these footprints an >NAME >VALUE - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - @@ -983,6 +953,18 @@ We've spent an enormous amount of time creating and checking these footprints an + + + + + +>NAME +>VALUE + + + + + @@ -1216,56 +1198,48 @@ Please make sure your boards conform to these design rules. - - - - - - - - @@ -1276,36 +1250,24 @@ Please make sure your boards conform to these design rules. - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - + + + - - + + + + @@ -1351,12 +1313,6 @@ Please make sure your boards conform to these design rules. - - - - - - @@ -1444,9 +1400,15 @@ Please make sure your boards conform to these design rules. - + + + + + + + @@ -1827,8 +1789,10 @@ Please make sure your boards conform to these design rules. - - + + + + @@ -1840,11 +1804,11 @@ Please make sure your boards conform to these design rules. - - - - - + + + + + @@ -2510,8 +2474,20 @@ Please make sure your boards conform to these design rules. - + + + + + + + + + + + + + @@ -2637,27 +2613,23 @@ Please make sure your boards conform to these design rules. - - - - - - - - + + + + + + - - - - - - - - - + + + + + + + @@ -2800,11 +2772,11 @@ Please make sure your boards conform to these design rules. - - - - - + + + + + @@ -2817,28 +2789,21 @@ Please make sure your boards conform to these design rules. - + - - - - - - - - - - - - - - + + + + + + + diff --git a/pcb/LEDscape.lbr b/pcb/LEDscape.lbr index 10c741e1..f0529cee 100644 --- a/pcb/LEDscape.lbr +++ b/pcb/LEDscape.lbr @@ -6,7 +6,7 @@ - + @@ -811,7 +811,7 @@ - + diff --git a/pcb/LEDscape.sch b/pcb/LEDscape.sch index 52c8de1a..06446839 100644 --- a/pcb/LEDscape.sch +++ b/pcb/LEDscape.sch @@ -1294,7 +1294,7 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - + @@ -4122,13 +4122,112 @@ will be further integrated into the Sparkfun Library for other footprints. It c - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + @@ -4142,57 +4241,105 @@ will be further integrated into the Sparkfun Library for other footprints. It c - - + + + >NAME >VALUE + - + - - - - + + + + - - + + + - - - - - + + + + + - + - - - - - - + + + + + + + + + + + >NAME >VALUE - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + @@ -4206,17 +4353,19 @@ will be further integrated into the Sparkfun Library for other footprints. It c - - + + + >NAME >VALUE + - + This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place. You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line). This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace" @@ -4226,303 +4375,178 @@ if you push a header all the way into place, it is covered up entirely on the bo will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins. + - - - - - + + + + + + >NAME >VALUE + - + - - - - + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE + - - - - ->NAME ->VALUE - - - + + + + + + + + + + + + + + + + + + + - + - + + >NAME >VALUE + - - - - - - - - - - - ->Name ->Value -+ -- -S - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - + + + + + >NAME >VALUE + - - - - - - - - - - - - - - - ->Name ->Value + + + + + + + + + + + + + + +>Name +>Value ++ +- +S +S - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + >NAME >VALUE - - - - - - - - - - - ->Value ->Name - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE @@ -4538,20 +4562,6 @@ will be further integrated into the Sparkfun Library for other footprints. It c - - - - - - - - ->VALUE ->NAME - - - - @@ -4592,6 +4602,22 @@ will be further integrated into the Sparkfun Library for other footprints. It c + + + + + + + + + +>VALUE +>NAME + + + + + @@ -4794,214 +4820,193 @@ Standard 2-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - -<b>Header 3</b> -Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08232 with associated crimp pins and housings. + +.1" headers, two rows of 8 each - + - - - - - - - - - - - + + + + + + + + + + + + + + - + + + +<b>Header 4</b> +Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08231 with associated crimp pins and housings. 1MM SMD Version SKU: PRT-10208 + + + + + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + - - - - - - - - - - - - - - - - - - - - - - - -.1" headers, two rows of 8 each - - - - - - - - - - - - - - - - - - - - - @@ -5091,12 +5096,12 @@ Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - + @@ -5173,12 +5178,12 @@ Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - + + @@ -5357,9 +5362,9 @@ Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - + @@ -5612,9 +5617,9 @@ Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - + + @@ -6399,12 +6404,17 @@ Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - + + + + + @@ -6575,9 +6585,9 @@ Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - @@ -6601,6 +6611,7 @@ Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + @@ -6612,6 +6623,7 @@ Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + @@ -6623,6 +6635,7 @@ Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + @@ -6634,6 +6647,7 @@ Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + @@ -6705,6 +6719,7 @@ Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + @@ -6716,11 +6731,34 @@ Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + + + + + + + + + + + + + + + + + + + + + From 35468c31ce3df3dd84dae3ae62a023a9b7334c24 Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Fri, 2 Aug 2013 00:03:58 +0800 Subject: [PATCH 026/332] Fix Trammells name... --- pcb/LEDscape.brd | 2 +- pcb/LEDscape.sch | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pcb/LEDscape.brd b/pcb/LEDscape.brd index b85c090d..173007e5 100644 --- a/pcb/LEDscape.brd +++ b/pcb/LEDscape.brd @@ -159,7 +159,7 @@ - - LEDscape LED Controller -By Matt Mets and Trammel Hudson +By Matt Mets and Trammell Hudson Rev A 2013-08-01 diff --git a/pcb/LEDscape.sch b/pcb/LEDscape.sch index 06446839..e884a988 100644 --- a/pcb/LEDscape.sch +++ b/pcb/LEDscape.sch @@ -6753,11 +6753,10 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - + From cffc8aec4a833787d6748480d8f5e13c852d3483 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 2 Aug 2013 02:33:39 +0000 Subject: [PATCH 027/332] UDP receiver; not tested against the actual transmitter --- Makefile | 9 ++++-- udp-rx.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 udp-rx.c diff --git a/Makefile b/Makefile index 68c316d1..0af6107b 100755 --- a/Makefile +++ b/Makefile @@ -36,13 +36,16 @@ TARGET := rgb-test _DEPS = DEPS = $(patsubst %,$(INCDIR_APP_LOADER)/%,$(_DEPS)) -OBJS = ledscape.o pru.o rgb-test.o +OBJS = ledscape.o pru.o %.o: %.c $(DEPS) $(CROSS_COMPILE)gcc $(CFLAGS) -c -o $@ $< -all: $(TARGET) ws281x.bin -$(TARGET): $(OBJS) +all: rgb-test udp-rx ws281x.bin +rgb-test: rgb-test.o $(OBJS) + $(CROSS_COMPILE)gcc $(CFLAGS) -o $@ $^ $(LDFLAGS) + +udp-rx: udp-rx.o $(OBJS) $(CROSS_COMPILE)gcc $(CFLAGS) -o $@ $^ $(LDFLAGS) ws281x.bin: ws281x.p ws281x.hp diff --git a/udp-rx.c b/udp-rx.c new file mode 100644 index 00000000..9b1dda1f --- /dev/null +++ b/udp-rx.c @@ -0,0 +1,84 @@ +/** \file + * UDP image packet receiver. + * + * Based on the HackRockCity LED Display code: + * https://github.com/agwn/pyramidTransmitter/blob/master/LEDDisplay.pde + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "ledscape.h" +#include "pru.h" + +int +main( + int argc, + char ** argv +) +{ + int port = 9999; + int num_pixels = 256; + int num_strips = 32; // not necessarily LEDSCAPE_NUM_STRIPS + + const int sock = socket(AF_INET, SOCK_DGRAM, 0); + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_addr.s_addr = INADDR_ANY, + .sin_port = htons(port), + }; + + if (sock < 0) + die("socket failed: %s\n", strerror(errno)); + if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr)) < 0) + die("bind port %d failed: %s\n", port, strerror(errno)); + + ledscape_t * const leds = ledscape_init(num_pixels); + + unsigned frame_num = 0; + + uint8_t buf[65536]; + + while (1) + { + const ssize_t rc = recv(sock, buf, sizeof(buf), 0); + if (rc < 0) + die("recv failed: %s\n", strerror(errno)); + + if (buf[0] == '2') + { + // image type + printf("image type: %.*s\n", + (int) rc - 1, + &buf[1] + ); + continue; + } + + ledscape_frame_t * const frame + = ledscape_frame(leds, frame_num); + + for(unsigned x=0 ; x < num_pixels ; x++) + { + for(unsigned strip = 0 ; strip < 32 ; strip++) + { + const uint8_t r = buf[x*num_strips+1]; + const uint8_t g = buf[x*num_strips+2]; + const uint8_t b = buf[x*num_strips+3]; + ledscape_set_color(frame, strip, x, r, g, b); + } + } + + ledscape_wait(leds); + ledscape_draw(leds, frame_num); + + frame_num = (frame_num+1) % 2; + } + + ledscape_close(leds); + return 0; +} From c9c8ae307268b0d802659d41a1e70f8ec8c9f03c Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 2 Aug 2013 02:34:17 +0000 Subject: [PATCH 028/332] random tweaks to output --- rgb-test.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/rgb-test.c b/rgb-test.c index 79219a80..de2419de 100644 --- a/rgb-test.c +++ b/rgb-test.c @@ -28,7 +28,7 @@ ledscape_fill_color( int main (void) { - const int num_pixels = 256; + const int num_pixels = 128; ledscape_t * const leds = ledscape_init(num_pixels); time_t last_time = time(NULL); unsigned last_i = 0; @@ -42,13 +42,32 @@ int main (void) = ledscape_frame(leds, frame_num); uint8_t val = i >> 1; - //ledscape_fill_color(frame, num_pixels, val, 0, val); + uint16_t r = ((i >> 0) & 0xFF); + uint16_t g = ((i >> 8) & 0xFF); + uint16_t b = ((i >> 16) & 0xFF); + ledscape_fill_color(frame, num_pixels, val, val, val); - for (int strip = 0 ; strip < 32 ; strip++) + for (unsigned strip = 0 ; strip < 32 ; strip++) { - ledscape_set_color(frame, strip, 0, val, 0, 0); - ledscape_set_color(frame, strip, 1, 0, val + 80, 0); - ledscape_set_color(frame, strip, 2, 0, 0, val + 160); + for (unsigned p = 0 ; p < 64 ; p++) + { + ledscape_set_color( + frame, + strip, + p, +#if 1 + ((strip % 3) == 0) ? (i) : 0, + ((strip % 3) == 1) ? (i) : 0, + ((strip % 3) == 2) ? (i) : 0 +#else + ((strip % 3) == 0) ? 100 : 0, + ((strip % 3) == 1) ? 100 : 0, + ((strip % 3) == 2) ? 100 : 0 +#endif + ); + //ledscape_set_color(frame, strip, 3*p+1, 0, p+val + 80, 0); + //ledscape_set_color(frame, strip, 3*p+2, 0, 0, p+val + 160); + } } // wait for the previous frame to finish; From e5a48c7fa3be42bce5b850533508d27023021529 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 2 Aug 2013 20:27:56 -0400 Subject: [PATCH 029/332] Locate the serial ports on the BBB --- find-serial | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100755 find-serial diff --git a/find-serial b/find-serial new file mode 100755 index 00000000..b3eb78fe --- /dev/null +++ b/find-serial @@ -0,0 +1,10 @@ +#!/bin/sh +# Locate the serial ports and their serial numbers. +# This can then be used to map devices to positions in the matrix. + +for dev in `find /sys/devices/ -name '*ACM*' `;do + DIR=`dirname $dev` + TTY=`basename $dev` + SERIAL=`cat $DIR/../../serial` + echo "/dev/$TTY: $SERIAL" +done From 62c09f9cb31fef608567092ff9fe4c6f906a4a11 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 3 Aug 2013 19:51:05 -0400 Subject: [PATCH 030/332] Receive UDP frames and slice them for the teensy --- pru.h | 8 +--- teensy-udp-rx.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++ util.h | 21 ++++++++ 3 files changed, 147 insertions(+), 7 deletions(-) create mode 100644 teensy-udp-rx.c create mode 100644 util.h diff --git a/pru.h b/pru.h index ff851d94..0a471614 100644 --- a/pru.h +++ b/pru.h @@ -7,6 +7,7 @@ #include #include +#include "util.h" /** Mapping of the PRU memory spaces. @@ -45,13 +46,6 @@ pru_close( ); -#define die(fmt, ...) \ - do { \ - fprintf(stderr, "%s:%d: " fmt, \ - __func__, __LINE__, ## __VA_ARGS__); \ - exit(EXIT_FAILURE); \ - } while (0) - /** Configure a GPIO pin. * diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c new file mode 100644 index 00000000..35f8eda3 --- /dev/null +++ b/teensy-udp-rx.c @@ -0,0 +1,125 @@ +/** \file + * UDP image packet receiver. + * + * Based on the HackRockCity LED Display code: + * https://github.com/agwn/pyramidTransmitter/blob/master/LEDDisplay.pde + * + * Designed to clock data out to USB teensy3 serial devices, which require + * bitslicing into the raw form for the OctoWS2811 firmware. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" + + +/** Prepare one Teensy3 worth of image data. + * Each Teensy handles 8 rows of data and needs the bits sliced into + * each 8 rows. + */ +void +bitslice( + uint8_t * const out, + const uint8_t * in, + const unsigned width, + const unsigned y_offset +) +{ + // Reorder from RGB in the input to GRB in the output + static const uint8_t channel_map[] = { 1, 0, 2 }; + + // Skip to the starting row that we're processing + in += y_offset * width; + + for(unsigned x=0 ; x < width ; x++) + { + for (unsigned channel = 0 ; channel < 3 ; channel++) + { + const uint8_t mapped_channel + = channel_map[channel]; + + for (unsigned bit_num = 0 ; bit_num < 8 ; bit_num++) + { + uint8_t b = 0; + const uint8_t mask = 1 << (7 - bit_num); + + for(unsigned y = 0 ; y < 8 ; y++) + { + const uint8_t v + = in[x + y*width + channel]; + if (v & mask) + b |= 1 << y; + } + + out[x + 3*mapped_channel + bit_num] = b; + } + } + } +} + + +int +main( + int argc, + char ** argv +) +{ + int port = 9999; + unsigned width = 10; + unsigned height = 8; + + const int sock = socket(AF_INET, SOCK_DGRAM, 0); + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_port = htons(port), + .sin_addr.s_addr = INADDR_ANY, + }; + + if (sock < 0) + die("socket failed: %s\n", strerror(errno)); + if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr)) < 0) + die("bind port %d failed: %s\n", port, strerror(errno)); + + const size_t slice_size = width * height * 3 + 3; + uint8_t * const slice = calloc(1, slice_size); + + uint8_t buf[65536]; + + while (1) + { + const ssize_t rc = recv(sock, buf, sizeof(buf), 0); + if (rc < 0) + die("recv failed: %s\n", strerror(errno)); + + if (buf[0] == '2') + { + // image type + printf("image type: %.*s\n", + (int) rc - 1, + &buf[1] + ); + continue; + } + + // Header for the frame to the teensy indicating that it + // is to be drawn immediately. + slice[0] = '%'; + slice[1] = 0; + slice[2] = 0; + + // Translate the image from packed RGB into sliced 24-bit + // for each teensy. + for (unsigned y_offset = 0 ; y_offset < height ; y_offset += 8) + { + bitslice(slice+3, buf+1, width, y_offset); + write(1, slice, slice_size); + } + } + + return 0; +} diff --git a/util.h b/util.h new file mode 100644 index 00000000..5e6666bb --- /dev/null +++ b/util.h @@ -0,0 +1,21 @@ +/** \file + * Utility functions. + */ +#ifndef _util_h_ +#define _util_h_ + +#include +#include +#include +#include +#include + +#define die(fmt, ...) \ + do { \ + fprintf(stderr, "%s:%d: " fmt, \ + __func__, __LINE__, ## __VA_ARGS__); \ + exit(EXIT_FAILURE); \ + } while (0) + + +#endif From 505e43efe430a25f33dcbae131a238ba4afc95b2 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 3 Aug 2013 20:07:53 -0400 Subject: [PATCH 031/332] maybe bitslicing works now --- teensy-udp-rx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 35f8eda3..b37c83d7 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -34,7 +34,7 @@ bitslice( static const uint8_t channel_map[] = { 1, 0, 2 }; // Skip to the starting row that we're processing - in += y_offset * width; + in += y_offset * width * 3; for(unsigned x=0 ; x < width ; x++) { @@ -51,12 +51,12 @@ bitslice( for(unsigned y = 0 ; y < 8 ; y++) { const uint8_t v - = in[x + y*width + channel]; + = in[3*(x + y*width) + channel]; if (v & mask) b |= 1 << y; } - out[x + 3*mapped_channel + bit_num] = b; + out[24*x + 8*mapped_channel + bit_num] = b; } } } @@ -108,7 +108,7 @@ main( // Header for the frame to the teensy indicating that it // is to be drawn immediately. - slice[0] = '%'; + slice[0] = '$'; slice[1] = 0; slice[2] = 0; From 199f96bf0893e85302420557813816138d9989e5 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 3 Aug 2013 20:12:06 -0400 Subject: [PATCH 032/332] Rainbow test works --- rainbow | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100755 rainbow diff --git a/rainbow b/rainbow new file mode 100755 index 00000000..03f59648 --- /dev/null +++ b/rainbow @@ -0,0 +1,27 @@ +#!/usr/bin/perl +use warnings; +use strict; + +# Make a smooth gradient pattern + +my $width = 10; +my $height = 8; + +my $s = '1'; + +for(my $y = 0 ; $y < $height ; $y++) +{ + for(my $x =0 ; $x < $width ; $x++) + { + my $r = $x * 0xFF / $width; + #my $g = ($width - $x - 1) * 0xFF / $width; + my $g = 0; + my $b = ($height - $y - 1) * 0xFF / $height; + + $s .= chr($r); + $s .= chr($g); + $s .= chr($b); + } +} + +print $s; From 7dc938002b5a48f31d18840b12168de26223b054 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 3 Aug 2013 20:15:58 -0400 Subject: [PATCH 033/332] Better checks for message types and sizes --- rainbow | 3 ++- teensy-udp-rx.c | 27 +++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/rainbow b/rainbow index 03f59648..69db63f3 100755 --- a/rainbow +++ b/rainbow @@ -13,7 +13,8 @@ for(my $y = 0 ; $y < $height ; $y++) { for(my $x =0 ; $x < $width ; $x++) { - my $r = $x * 0xFF / $width; + #my $r = $x * 0xFF / $width; + my $r = ($width - $x - 1) * 0xFF / $width; #my $g = ($width - $x - 1) * 0xFF / $width; my $g = 0; my $b = ($height - $y - 1) * 0xFF / $height; diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index b37c83d7..f843d354 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -85,27 +85,46 @@ main( if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr)) < 0) die("bind port %d failed: %s\n", port, strerror(errno)); - const size_t slice_size = width * height * 3 + 3; + const size_t image_size = width * height * 3; + const size_t slice_size = width * 8 * 3 + 3; uint8_t * const slice = calloc(1, slice_size); uint8_t buf[65536]; while (1) { - const ssize_t rc = recv(sock, buf, sizeof(buf), 0); - if (rc < 0) + const ssize_t rlen = recv(sock, buf, sizeof(buf), 0); + if (rlen < 0) die("recv failed: %s\n", strerror(errno)); if (buf[0] == '2') { // image type printf("image type: %.*s\n", - (int) rc - 1, + (int) rlen - 1, &buf[1] ); continue; } + if (buf[0] != '1') + { + // What is it? + fprintf(stderr, "Unknown image type '%c' (%02x)\n", + buf[0], + buf[0] + ); + continue; + } + + if ((size_t) rlen != width * height * 3 + 1) + { + fprintf(stderr, "WARNING: Received packet %zu bytes, expected %zu\n", + rlen, + image_size + ); + } + // Header for the frame to the teensy indicating that it // is to be drawn immediately. slice[0] = '$'; From 3a25652c52f9fda5e1bbd2db878edb03e2e2f809 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 3 Aug 2013 20:39:32 -0400 Subject: [PATCH 034/332] Use termios to open per-teensy serial ports --- rainbow | 10 ++--- teensy-udp-rx.c | 102 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 95 insertions(+), 17 deletions(-) diff --git a/rainbow b/rainbow index 69db63f3..67241e4d 100755 --- a/rainbow +++ b/rainbow @@ -13,11 +13,11 @@ for(my $y = 0 ; $y < $height ; $y++) { for(my $x =0 ; $x < $width ; $x++) { - #my $r = $x * 0xFF / $width; - my $r = ($width - $x - 1) * 0xFF / $width; - #my $g = ($width - $x - 1) * 0xFF / $width; - my $g = 0; - my $b = ($height - $y - 1) * 0xFF / $height; + my $r = $x * 0x30 / $width; + #my $r = ($width - $x - 1) * 0x30 / $width; + my $g = ($width - $x - 1) * 0x30 / $width; + #my $g = 0; + my $b = ($height - $y - 1) * 0x30 / $height; $s .= chr($r); $s .= chr($g); diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index f843d354..6d121fc1 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -9,8 +9,11 @@ */ #include #include +#include +#include +#include #include -#include +#include #include #include #include @@ -63,6 +66,47 @@ bitslice( } +static int +udp_socket( + const int port +) +{ + const int sock = socket(AF_INET, SOCK_DGRAM, 0); + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_port = htons(port), + .sin_addr.s_addr = INADDR_ANY, + }; + + if (sock < 0) + return -1; + if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr)) < 0) + return -1; + + return sock; +} + + +static int +serial_open( + const char * const dev +) +{ + const int fd = open(dev, O_RDWR | O_NONBLOCK | O_NOCTTY, 0666); + if (fd < 0) + return -1; + + // Disable modem control signals + struct termios attr; + tcgetattr(fd, &attr); + attr.c_cflag |= CLOCAL | CREAD; + tcsetattr(fd, TCSANOW, &attr); + + return fd; +} + + + int main( int argc, @@ -73,17 +117,37 @@ main( unsigned width = 10; unsigned height = 8; - const int sock = socket(AF_INET, SOCK_DGRAM, 0); - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_port = htons(port), - .sin_addr.s_addr = INADDR_ANY, - }; + const unsigned num_fds = argc - 1; + if (argc <= 1) + die("At least one serial port must be specified\n"); + + int fds[num_fds]; + const char * dev_names[num_fds]; + for (int i = 1 ; i < argc ; i++) + { + const char * const dev = argv[i]; + const int fd = serial_open(dev); + if (fd < 0) + die("%s: Unable to open serial port: %s\n", + dev, + strerror(errno) + ); + fds[i-1] = fd; + dev_names[i-1] = dev; + } + + printf("%d serial ports\n", num_fds); + if (num_fds * 8 != height) + fprintf(stderr, "WARNING: %d ports == %d rows != image height %d\n", + num_fds, + num_fds * 8, + height + ); + + const int sock = udp_socket(port); if (sock < 0) - die("socket failed: %s\n", strerror(errno)); - if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr)) < 0) - die("bind port %d failed: %s\n", port, strerror(errno)); + die("socket port %d failed: %s\n", port, strerror(errno)); const size_t image_size = width * height * 3; const size_t slice_size = width * 8 * 3 + 3; @@ -133,10 +197,24 @@ main( // Translate the image from packed RGB into sliced 24-bit // for each teensy. - for (unsigned y_offset = 0 ; y_offset < height ; y_offset += 8) + for (unsigned i = 0 ; i < num_fds ; i++) { + const unsigned y_offset = i * 8; bitslice(slice+3, buf+1, width, y_offset); - write(1, slice, slice_size); + + ssize_t rc = write(fds[i], slice, slice_size); + if (rc < 0) + die("%s: write failed: %s\n", + dev_names[i], + strerror(errno) + ); + if ((size_t) rc != slice_size) + die("%s: short write %zu != %zu: %s\n", + dev_names[i], + rc, + slice_size, + strerror(errno) + ); } } From 6632eb6c1f724b1eb0816ef0a9753db4576e469b Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 3 Aug 2013 20:59:34 -0400 Subject: [PATCH 035/332] 32 strip works --- identify | 32 ++++++++++++++++++++++++++++++++ rainbow | 6 +++--- teensy-udp-rx.c | 2 +- 3 files changed, 36 insertions(+), 4 deletions(-) create mode 100755 identify diff --git a/identify b/identify new file mode 100755 index 00000000..dd28a9bf --- /dev/null +++ b/identify @@ -0,0 +1,32 @@ +#!/usr/bin/perl +use warnings; +use strict; + +# Make a bargraph to help identify which port is which +# R Y G C B W + +my $width = 10; +my $height = 32; + +my $s = '1'; + +for(my $y = 0 ; $y < $height ; $y++) +{ + for(my $x = 0 ; $x < $width ; $x++) + { + my $v = ($y % 8) >= $x ? 0x10 : 0; + my $r = 0; + my $g = 0; + my $b = 0; + $r = $v if int($y / 8) == 0; + $g = $v if int($y / 8) == 1; + $b = $v if int($y / 8) == 2; + $g = $r = $v if int($y / 8) == 3; + + $s .= chr($r); + $s .= chr($g); + $s .= chr($b); + } +} + +print $s; diff --git a/rainbow b/rainbow index 67241e4d..517be81c 100755 --- a/rainbow +++ b/rainbow @@ -5,7 +5,7 @@ use strict; # Make a smooth gradient pattern my $width = 10; -my $height = 8; +my $height = 32; my $s = '1'; @@ -15,8 +15,8 @@ for(my $y = 0 ; $y < $height ; $y++) { my $r = $x * 0x30 / $width; #my $r = ($width - $x - 1) * 0x30 / $width; - my $g = ($width - $x - 1) * 0x30 / $width; - #my $g = 0; + #my $g = ($width - $x - 1) * 0x30 / $width; + my $g = 0; my $b = ($height - $y - 1) * 0x30 / $height; $s .= chr($r); diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 6d121fc1..7f7df586 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -115,7 +115,7 @@ main( { int port = 9999; unsigned width = 10; - unsigned height = 8; + unsigned height = 32; const unsigned num_fds = argc - 1; if (argc <= 1) From 9ad55d22795080cb9ae238d4a26e57a817d79e8b Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 4 Aug 2013 13:37:05 -0400 Subject: [PATCH 036/332] Import of Teensy3 VideoDisplay.ino --- VideoDisplay.ino | 246 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 VideoDisplay.ino diff --git a/VideoDisplay.ino b/VideoDisplay.ino new file mode 100644 index 00000000..a348c419 --- /dev/null +++ b/VideoDisplay.ino @@ -0,0 +1,246 @@ +/* OctoWS2811 VideoDisplay.ino - Video on LEDs, from a PC, Mac, Raspberry Pi + http://www.pjrc.com/teensy/td_libs_OctoWS2811.html + Copyright (c) 2013 Paul Stoffregen, 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. + + + Required Connections + -------------------- + pin 2: LED Strip #1 OctoWS2811 drives 8 LED Strips. + pin 14: LED strip #2 All 8 are the same length. + pin 7: LED strip #3 + pin 8: LED strip #4 A 100 to 220 ohm resistor should used + pin 6: LED strip #5 between each Teensy pin and the + pin 20: LED strip #6 wire to the LED strip, to minimize + pin 21: LED strip #7 high frequency ringining & noise. + pin 5: LED strip #8 + pin 15 & 16 - Connect together, but do not use + pin 4: Do not use + pin 3: Do not use as PWM. Normal use is ok. + pin 12: Frame Sync + + When using more than 1 Teensy to display a video image, connect + the Frame Sync signal between every board. All boards will + synchronize their WS2811 update using this signal. + + Beware of image distortion from long LED strip lengths. During + the WS2811 update, the LEDs update in sequence, not all at the + same instant! The first pixel updates after 30 microseconds, + the second pixel after 60 us, and so on. A strip of 120 LEDs + updates in 3.6 ms, which is 10.8% of a 30 Hz video frame time. + Doubling the strip length to 240 LEDs increases the lag to 21.6% + of a video frame. For best results, use shorter length strips. + Multiple boards linked by the frame sync signal provides superior + video timing accuracy. + + A Multi-TT USB hub should be used if 2 or more Teensy boards + are connected. The Multi-TT feature allows proper USB bandwidth + allocation. Single-TT hubs, or direct connection to multiple + ports on the same motherboard, may give poor performance. +*/ + +#include + +// The actual arrangement of the LEDs connected to this Teensy 3.0 board. +// LED_HEIGHT *must* be a multiple of 8. When 16, 24, 32 are used, each +// strip spans 2, 3, 4 rows. LED_LAYOUT indicates the direction the strips +// are arranged. If 0, each strip begins on the left for its first row, +// then goes right to left for its second row, then left to right, +// zig-zagging for each successive row. +#define LED_WIDTH 60 // number of LEDs horizontally +#define LED_HEIGHT 16 // number of LEDs vertically (must be multiple of 8) +#define LED_LAYOUT 0 // 0 = even rows left->right, 1 = even rows right->left + +// The portion of the video image to show on this set of LEDs. All 4 numbers +// are percentages, from 0 to 100. For a large LED installation with many +// Teensy 3.0 boards driving groups of LEDs, these parameters allow you to +// program each Teensy to tell the video application which portion of the +// video it displays. By reading these numbers, the video application can +// automatically configure itself, regardless of which serial port COM number +// or device names are assigned to each Teensy 3.0 by your operating system. +#define VIDEO_XOFFSET 0 +#define VIDEO_YOFFSET 0 // display entire image +#define VIDEO_WIDTH 100 +#define VIDEO_HEIGHT 100 + +//#define VIDEO_XOFFSET 0 +//#define VIDEO_YOFFSET 0 // display upper half +//#define VIDEO_WIDTH 100 +//#define VIDEO_HEIGHT 50 + +//#define VIDEO_XOFFSET 0 +//#define VIDEO_YOFFSET 50 // display lower half +//#define VIDEO_WIDTH 100 +//#define VIDEO_HEIGHT 50 + + +const int ledsPerStrip = LED_WIDTH * LED_HEIGHT / 8; + +DMAMEM int displayMemory[ledsPerStrip*6]; +int drawingMemory[ledsPerStrip*6]; +elapsedMicros elapsedUsecSinceLastFrameSync = 0; + +const int config = WS2811_800kHz; // color config is on the PC side + +OctoWS2811 leds(ledsPerStrip, displayMemory, drawingMemory, config); + +void setup() { + pinMode(12, INPUT_PULLUP); // Frame Sync + Serial.setTimeout(50); + leds.begin(); + leds.show(); +} + +void loop() { +// +// wait for a Start-Of-Message character: +// +// '*' = Frame of image data, with frame sync pulse to be sent +// a specified number of microseconds after reception of +// the first byte (typically at 75% of the frame time, to +// allow other boards to fully receive their data). +// Normally '*' is used when the sender controls the pace +// of playback by transmitting each frame as it should +// appear. +// +// '$' = Frame of image data, with frame sync pulse to be sent +// a specified number of microseconds after the previous +// frame sync. Normally this is used when the sender +// transmits each frame as quickly as possible, and we +// control the pacing of video playback by updating the +// LEDs based on time elapsed from the previous frame. +// +// '%' = Frame of image data, to be displayed with a frame sync +// pulse is received from another board. In a multi-board +// system, the sender would normally transmit one '*' or '$' +// message and '%' messages to all other boards, so every +// Teensy 3.0 updates at the exact same moment. +// +// '@' = Reset the elapsed time, used for '$' messages. This +// should be sent before the first '$' message, so many +// frames are not played quickly if time as elapsed since +// startup or prior video playing. +// +// '?' = Query LED and Video parameters. Teensy 3.0 responds +// with a comma delimited list of information. +// + int startChar = Serial.read(); + + if (startChar == '*') { + // receive a "master" frame - we send the frame sync to other boards + // the sender is controlling the video pace. The 16 bit number is + // how far into this frame to send the sync to other boards. + unsigned int startAt = micros(); + unsigned int usecUntilFrameSync = 0; + int count = Serial.readBytes((char *)&usecUntilFrameSync, 2); + if (count != 2) return; + count = Serial.readBytes((char *)drawingMemory, sizeof(drawingMemory)); + if (count == sizeof(drawingMemory)) { + unsigned int endAt = micros(); + unsigned int usToWaitBeforeSyncOutput = 100; + if (endAt - startAt < usecUntilFrameSync) { + usToWaitBeforeSyncOutput = usecUntilFrameSync - (endAt - startAt); + } + digitalWrite(12, HIGH); + pinMode(12, OUTPUT); + delayMicroseconds(usToWaitBeforeSyncOutput); + digitalWrite(12, LOW); + // WS2811 update begins immediately after falling edge of frame sync + digitalWrite(13, HIGH); + leds.show(); + digitalWrite(13, LOW); + } + + } else if (startChar == '$') { + // receive a "master" frame - we send the frame sync to other boards + // we are controlling the video pace. The 16 bit number is how long + // after the prior frame sync to wait until showing this frame + unsigned int usecUntilFrameSync = 0; + int count = Serial.readBytes((char *)&usecUntilFrameSync, 2); + if (count != 2) return; + count = Serial.readBytes((char *)drawingMemory, sizeof(drawingMemory)); + if (count == sizeof(drawingMemory)) { + digitalWrite(12, HIGH); + pinMode(12, OUTPUT); + while (elapsedUsecSinceLastFrameSync < usecUntilFrameSync) /* wait */ ; + elapsedUsecSinceLastFrameSync -= usecUntilFrameSync; + digitalWrite(12, LOW); + // WS2811 update begins immediately after falling edge of frame sync + digitalWrite(13, HIGH); + leds.show(); + digitalWrite(13, LOW); + } + + } else if (startChar == '%') { + // receive a "slave" frame - wait to show it until the frame sync arrives + pinMode(12, INPUT_PULLUP); + unsigned int unusedField = 0; + int count = Serial.readBytes((char *)&unusedField, 2); + if (count != 2) return; + count = Serial.readBytes((char *)drawingMemory, sizeof(drawingMemory)); + if (count == sizeof(drawingMemory)) { + elapsedMillis wait = 0; + while (digitalRead(12) != HIGH && wait < 30) ; // wait for sync high + while (digitalRead(12) != LOW && wait < 30) ; // wait for sync high->low + // WS2811 update begins immediately after falling edge of frame sync + if (wait < 30) { + digitalWrite(13, HIGH); + leds.show(); + digitalWrite(13, LOW); + } + } + + } else if (startChar == '@') { + // reset the elapsed frame time, for startup of '$' message playing + elapsedUsecSinceLastFrameSync = 0; + + } else if (startChar == '?') { + // when the video application asks, give it all our info + // for easy and automatic configuration + Serial.print(LED_WIDTH); + Serial.write(','); + Serial.print(LED_HEIGHT); + Serial.write(','); + Serial.print(LED_LAYOUT); + Serial.write(','); + Serial.print(0); + Serial.write(','); + Serial.print(0); + Serial.write(','); + Serial.print(VIDEO_XOFFSET); + Serial.write(','); + Serial.print(VIDEO_YOFFSET); + Serial.write(','); + Serial.print(VIDEO_WIDTH); + Serial.write(','); + Serial.print(VIDEO_HEIGHT); + Serial.write(','); + Serial.print(0); + Serial.write(','); + Serial.print(0); + Serial.write(','); + Serial.print(0); + Serial.println(); + + } else if (startChar >= 0) { + // discard unknown characters + } +} + From 6019b4b2486663d6b91f59735462dc1b01eefd4d Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 4 Aug 2013 13:51:40 -0400 Subject: [PATCH 037/332] Add serial number to ? output --- .../VideoDisplay.ino | 17 ++++++++-- VideoDisplay/mac.cpp | 32 +++++++++++++++++++ VideoDisplay/mac.h | 7 ++++ 3 files changed, 54 insertions(+), 2 deletions(-) rename VideoDisplay.ino => VideoDisplay/VideoDisplay.ino (95%) create mode 100644 VideoDisplay/mac.cpp create mode 100644 VideoDisplay/mac.h diff --git a/VideoDisplay.ino b/VideoDisplay/VideoDisplay.ino similarity index 95% rename from VideoDisplay.ino rename to VideoDisplay/VideoDisplay.ino index a348c419..2b320e9a 100644 --- a/VideoDisplay.ino +++ b/VideoDisplay/VideoDisplay.ino @@ -2,6 +2,10 @@ http://www.pjrc.com/teensy/td_libs_OctoWS2811.html Copyright (c) 2013 Paul Stoffregen, PJRC.COM, LLC + Updated by Trammell Hudson + - Teport unique Teensy serial number in response to ? command. + - Receive a data frame and wait for a ! command to display it. + 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 @@ -57,6 +61,7 @@ */ #include +#include "mac.h" // The actual arrangement of the LEDs connected to this Teensy 3.0 board. // LED_HEIGHT *must* be a multiple of 8. When 16, 24, 32 are used, each @@ -64,8 +69,12 @@ // are arranged. If 0, each strip begins on the left for its first row, // then goes right to left for its second row, then left to right, // zig-zagging for each successive row. +// +// Since the receiving program on the host is slicing the image, +// only the width matters. The height is always 8. +// #define LED_WIDTH 60 // number of LEDs horizontally -#define LED_HEIGHT 16 // number of LEDs vertically (must be multiple of 8) +#define LED_HEIGHT 8 // number of LEDs vertically (must be 8) #define LED_LAYOUT 0 // 0 = even rows left->right, 1 = even rows right->left // The portion of the video image to show on this set of LEDs. All 4 numbers @@ -140,6 +149,8 @@ void loop() { // // '?' = Query LED and Video parameters. Teensy 3.0 responds // with a comma delimited list of information. +// +// '!' = Display the frame now. // int startChar = Serial.read(); @@ -220,7 +231,9 @@ void loop() { Serial.write(','); Serial.print(LED_LAYOUT); Serial.write(','); - Serial.print(0); + read_mac(); + const uint16_t id = mac[4] << 8 | mac[5]; + Serial.print(id); Serial.write(','); Serial.print(0); Serial.write(','); diff --git a/VideoDisplay/mac.cpp b/VideoDisplay/mac.cpp new file mode 100644 index 00000000..552d612f --- /dev/null +++ b/VideoDisplay/mac.cpp @@ -0,0 +1,32 @@ +#include "mac.h" + +uint8_t mac[6]; + +// http://forum.pjrc.com/threads/91-teensy-3-MAC-address +void read(uint8_t word, uint8_t *mac, uint8_t offset) { + FTFL_FCCOB0 = 0x41; // Selects the READONCE command + FTFL_FCCOB1 = word; // read the given word of read once area + + // launch command and wait until complete + FTFL_FSTAT = FTFL_FSTAT_CCIF; + while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF)); + + *(mac+offset) = FTFL_FCCOB5; // collect only the top three bytes, + *(mac+offset+1) = FTFL_FCCOB6; // in the right orientation (big endian). + *(mac+offset+2) = FTFL_FCCOB7; // Skip FTFL_FCCOB4 as it's always 0. +} + +void read_mac() { + read(0xe,mac,0); + read(0xf,mac,3); +} + +void print_mac() { + size_t count = 0; + for(uint8_t i = 0; i < 6; ++i) { + if (i!=0) count += Serial.print(":"); + count += Serial.print((*(mac+i) & 0xF0) >> 4, 16); + count += Serial.print(*(mac+i) & 0x0F, 16); + } +} + diff --git a/VideoDisplay/mac.h b/VideoDisplay/mac.h new file mode 100644 index 00000000..904b841e --- /dev/null +++ b/VideoDisplay/mac.h @@ -0,0 +1,7 @@ +#include ; + +extern uint8_t mac[6]; + +void read_mac(); +void print_mac(); + From 009a1ce41a1a64a18e7485dfff8ad9fb7d605ff5 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 4 Aug 2013 13:58:56 -0400 Subject: [PATCH 038/332] Work with ten pixels right now --- VideoDisplay/VideoDisplay.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VideoDisplay/VideoDisplay.ino b/VideoDisplay/VideoDisplay.ino index 2b320e9a..ea2757b3 100644 --- a/VideoDisplay/VideoDisplay.ino +++ b/VideoDisplay/VideoDisplay.ino @@ -73,7 +73,7 @@ // Since the receiving program on the host is slicing the image, // only the width matters. The height is always 8. // -#define LED_WIDTH 60 // number of LEDs horizontally +#define LED_WIDTH 10 // number of LEDs horizontally #define LED_HEIGHT 8 // number of LEDs vertically (must be 8) #define LED_LAYOUT 0 // 0 = even rows left->right, 1 = even rows right->left From 3bc40b8f62d94e67085f47891ee36fa15a20d6a8 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 4 Aug 2013 14:18:07 -0400 Subject: [PATCH 039/332] Lookup serial number and use this to map position of LED strip in image --- teensy-udp-rx.c | 137 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 121 insertions(+), 16 deletions(-) diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 7f7df586..4ab1cf24 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -9,6 +9,7 @@ */ #include #include +#include #include #include #include @@ -106,6 +107,84 @@ serial_open( } +typedef struct +{ + unsigned id; + unsigned fd; + const char * dev; + uint8_t bad[256]; // which pixels are to be masked out +} teensy_strip_t; + +// \todo read this from a file at run time +static teensy_strip_t strips[] = { + { .id = 14401, .bad = { [2] = 1, } }, + { .id = 14389, .bad = { [3] = 1, [4] = 1, } }, + { .id = 8987, .bad = { } }, + { .id = 8998, .bad = { } }, +}; + +static const unsigned num_strips = sizeof(strips) / sizeof(*strips); + + +static teensy_strip_t * strip_find( + const char * const dev, + const int fd, + const unsigned id +) +{ + // Look through our table to find where this one goes + for (unsigned j = 0 ; j < num_strips ; j++) + { + teensy_strip_t * const leds = &strips[j]; + if (leds->id != id) + continue; + + if (leds->dev != NULL) + { + fprintf(stderr, "FATAL: %s: Duplicate ID %u (%s)\n", + dev, id, leds->dev); + return NULL; + } + + leds->dev = dev; + leds->fd = fd; + return leds; + } + + fprintf(stderr, "FATAL: %s: Unknown ID %u\n", dev, id); + return NULL; +} + + +static ssize_t +write_all( + const int fd, + const void * const buf_ptr, + const size_t len +) +{ + const uint8_t * const buf = buf_ptr; + size_t offset = 0; + + while (offset < len) + { + const ssize_t rc = write(fd, buf + offset, len - offset); + if (rc < 0) + { + if (errno == EAGAIN) + continue; + return -1; + } + + if (rc == 0) + return -1; + + offset += rc; + } + + return len; +} + int main( @@ -117,13 +196,11 @@ main( unsigned width = 10; unsigned height = 32; - const unsigned num_fds = argc - 1; - if (argc <= 1) - die("At least one serial port must be specified\n"); - - int fds[num_fds]; - const char * dev_names[num_fds]; + const unsigned num_devs = argc - 1; + if (num_devs != num_strips) + die("Must specify %u serial devices\n", num_strips); + int failed = 0; for (int i = 1 ; i < argc ; i++) { const char * const dev = argv[i]; @@ -133,15 +210,42 @@ main( dev, strerror(errno) ); - fds[i-1] = fd; - dev_names[i-1] = dev; + // Find out the serial number of this teensy + ssize_t rc; + rc = write(fd, "?", 1); + if (rc < 0) + die("%s: write failed: %s\n", dev, strerror(errno)); + + usleep(100000); + char response[128]; + rc = read(fd, response, sizeof(response)-1); + if (rc < 0) + die("%s: read failed: %s\n", dev, strerror(errno)); + + response[rc] = '\0'; + if (0) printf("read: '%s'\n", response); + + unsigned this_width; + unsigned this_id; + if (sscanf(response, "%d,%*d,%*d,%d", &this_width, &this_id) != 2) + die("%s: Unable to parse response: '%s'\n", dev, response); + printf("%s: ID %d width %d\n", dev, this_id, this_width); + if (this_width != width) + die("%s: width %d != expected %d\n", dev, this_width, width); + + teensy_strip_t * const leds = strip_find(dev, fd, this_id); + if (!leds) + failed++; } - printf("%d serial ports\n", num_fds); - if (num_fds * 8 != height) + if (failed) + die("FATAL configuration error\n"); + + printf("%d serial ports\n", num_devs); + if (num_devs * 8 != height) fprintf(stderr, "WARNING: %d ports == %d rows != image height %d\n", - num_fds, - num_fds * 8, + num_devs, + num_devs * 8, height ); @@ -197,20 +301,21 @@ main( // Translate the image from packed RGB into sliced 24-bit // for each teensy. - for (unsigned i = 0 ; i < num_fds ; i++) + for (unsigned i = 0 ; i < num_strips ; i++) { + teensy_strip_t * const strip = &strips[i]; const unsigned y_offset = i * 8; bitslice(slice+3, buf+1, width, y_offset); - ssize_t rc = write(fds[i], slice, slice_size); + ssize_t rc = write_all(strip->fd, slice, slice_size); if (rc < 0) die("%s: write failed: %s\n", - dev_names[i], + strip->dev, strerror(errno) ); if ((size_t) rc != slice_size) die("%s: short write %zu != %zu: %s\n", - dev_names[i], + strip->dev, rc, slice_size, strerror(errno) From ded4dd6f8d1a7c829dabe9cd5bebb2a1b94a883d Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 4 Aug 2013 14:22:34 -0400 Subject: [PATCH 040/332] Add bad pixel support --- teensy-udp-rx.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 4ab1cf24..227c7234 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -25,13 +25,17 @@ /** Prepare one Teensy3 worth of image data. * Each Teensy handles 8 rows of data and needs the bits sliced into * each 8 rows. + * + * Since some of the pixels might have bad single channels, + * allow them to be masked out entirely. */ void bitslice( uint8_t * const out, const uint8_t * in, const unsigned width, - const unsigned y_offset + const unsigned y_offset, + const uint8_t * const bad_pixels ) { // Reorder from RGB in the input to GRB in the output @@ -54,10 +58,13 @@ bitslice( for(unsigned y = 0 ; y < 8 ; y++) { + const uint8_t bit_pos = 1 << y; + if (bad_pixels[x] & bit_pos) + continue; const uint8_t v = in[3*(x + y*width) + channel]; if (v & mask) - b |= 1 << y; + b |= bit_pos; } out[24*x + 8*mapped_channel + bit_num] = b; @@ -119,8 +126,8 @@ typedef struct static teensy_strip_t strips[] = { { .id = 14401, .bad = { [2] = 1, } }, { .id = 14389, .bad = { [3] = 1, [4] = 1, } }, - { .id = 8987, .bad = { } }, - { .id = 8998, .bad = { } }, + { .id = 8987, .bad = { [0] = 0xFF, } }, + { .id = 8998, .bad = { [1] = 0x80, } }, }; static const unsigned num_strips = sizeof(strips) / sizeof(*strips); @@ -305,7 +312,7 @@ main( { teensy_strip_t * const strip = &strips[i]; const unsigned y_offset = i * 8; - bitslice(slice+3, buf+1, width, y_offset); + bitslice(slice+3, buf+1, width, y_offset, strip->bad); ssize_t rc = write_all(strip->fd, slice, slice_size); if (rc < 0) From 44e8d573b5b8f848e42fcce2a43d60f7852a6ddc Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 4 Aug 2013 14:33:01 -0400 Subject: [PATCH 041/332] Add warn() and warn_once() --- util.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/util.h b/util.h index 5e6666bb..9ea616b2 100644 --- a/util.h +++ b/util.h @@ -10,12 +10,25 @@ #include #include -#define die(fmt, ...) \ +#define warn(fmt, ...) \ do { \ fprintf(stderr, "%s:%d: " fmt, \ __func__, __LINE__, ## __VA_ARGS__); \ - exit(EXIT_FAILURE); \ } while (0) +#define warn_once(fmt, ...) \ + do { \ + static unsigned __warned__; \ + if (__warned__) \ + break; \ + __warned__ = 1; \ + warn(fmt, ## __VA_ARGS__ ); \ + } while (0) + +#define die(fmt, ...) \ + do { \ + warn(fmt, ## __VA_ARGS__ ); \ + exit(EXIT_FAILURE); \ + } while(0) #endif From 9c8eb19d500efc9a0001efdf89b38d5edd1d526d Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 4 Aug 2013 14:33:18 -0400 Subject: [PATCH 042/332] Store the y_offset in the strip config since we might not have the full image on this BBB --- teensy-udp-rx.c | 76 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 25 deletions(-) diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 227c7234..c178d3c9 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -118,16 +118,17 @@ typedef struct { unsigned id; unsigned fd; + unsigned y_offset; const char * dev; uint8_t bad[256]; // which pixels are to be masked out } teensy_strip_t; // \todo read this from a file at run time static teensy_strip_t strips[] = { - { .id = 14401, .bad = { [2] = 1, } }, - { .id = 14389, .bad = { [3] = 1, [4] = 1, } }, - { .id = 8987, .bad = { [0] = 0xFF, } }, - { .id = 8998, .bad = { [1] = 0x80, } }, + { .id = 14401, .y_offset = 0, .bad = { [2] = 1, } }, + { .id = 14389, .y_offset = 8, .bad = { [3] = 1, [4] = 1, } }, + { .id = 8987, .y_offset = 16, .bad = { [0] = 0xFF, } }, + { .id = 8998, .y_offset = 24, .bad = { [1] = 0x80, } }, }; static const unsigned num_strips = sizeof(strips) / sizeof(*strips); @@ -201,7 +202,7 @@ main( { int port = 9999; unsigned width = 10; - unsigned height = 32; + unsigned height = 128; const unsigned num_devs = argc - 1; if (num_devs != num_strips) @@ -213,21 +214,34 @@ main( const char * const dev = argv[i]; const int fd = serial_open(dev); if (fd < 0) - die("%s: Unable to open serial port: %s\n", + { + warn("%s: Unable to open serial port: %s\n", dev, strerror(errno) ); + failed++; + continue; + } + // Find out the serial number of this teensy ssize_t rc; rc = write(fd, "?", 1); if (rc < 0) - die("%s: write failed: %s\n", dev, strerror(errno)); + { + warn("%s: write failed: %s\n", dev, strerror(errno)); + failed++; + continue; + } usleep(100000); char response[128]; rc = read(fd, response, sizeof(response)-1); if (rc < 0) - die("%s: read failed: %s\n", dev, strerror(errno)); + { + warn("%s: read failed: %s\n", dev, strerror(errno)); + failed++; + continue; + } response[rc] = '\0'; if (0) printf("read: '%s'\n", response); @@ -235,10 +249,19 @@ main( unsigned this_width; unsigned this_id; if (sscanf(response, "%d,%*d,%*d,%d", &this_width, &this_id) != 2) - die("%s: Unable to parse response: '%s'\n", dev, response); + { + warn("%s: Unable to parse response: '%s'\n", dev, response); + failed++; + continue; + } + printf("%s: ID %d width %d\n", dev, this_id, this_width); if (this_width != width) - die("%s: width %d != expected %d\n", dev, this_width, width); + { + warn("%s: width %d != expected %d\n", dev, this_width, width); + failed++; + continue; + } teensy_strip_t * const leds = strip_find(dev, fd, this_id); if (!leds) @@ -246,15 +269,9 @@ main( } if (failed) - die("FATAL configuration error\n"); + die("FATAL CONFIGURATION ERROR\n"); printf("%d serial ports\n", num_devs); - if (num_devs * 8 != height) - fprintf(stderr, "WARNING: %d ports == %d rows != image height %d\n", - num_devs, - num_devs * 8, - height - ); const int sock = udp_socket(port); if (sock < 0) @@ -285,18 +302,18 @@ main( if (buf[0] != '1') { // What is it? - fprintf(stderr, "Unknown image type '%c' (%02x)\n", + warn_once("Unknown image type '%c' (%02x)\n", buf[0], buf[0] ); continue; } - if ((size_t) rlen != width * height * 3 + 1) + if ((size_t) rlen != image_size + 1) { - fprintf(stderr, "WARNING: Received packet %zu bytes, expected %zu\n", + warn_once("WARNING: Received packet %zu bytes, expected %zu\n", rlen, - image_size + image_size + 1 ); } @@ -310,16 +327,25 @@ main( // for each teensy. for (unsigned i = 0 ; i < num_strips ; i++) { - teensy_strip_t * const strip = &strips[i]; - const unsigned y_offset = i * 8; - bitslice(slice+3, buf+1, width, y_offset, strip->bad); + const teensy_strip_t * const strip = &strips[i]; + + bitslice( + slice + 3, + buf + 1, + width, + strip->y_offset, + strip->bad + ); + + const ssize_t rc + = write_all(strip->fd, slice, slice_size); - ssize_t rc = write_all(strip->fd, slice, slice_size); if (rc < 0) die("%s: write failed: %s\n", strip->dev, strerror(errno) ); + if ((size_t) rc != slice_size) die("%s: short write %zu != %zu: %s\n", strip->dev, From 5b983a193ff2bc0f1f03300056f11d2de27dcc8f Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 4 Aug 2013 16:25:51 -0400 Subject: [PATCH 043/332] Change intensity --- rainbow | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/rainbow b/rainbow index 517be81c..61466d73 100755 --- a/rainbow +++ b/rainbow @@ -8,16 +8,17 @@ my $width = 10; my $height = 32; my $s = '1'; +my $bright = 0x10; for(my $y = 0 ; $y < $height ; $y++) { for(my $x =0 ; $x < $width ; $x++) { - my $r = $x * 0x30 / $width; - #my $r = ($width - $x - 1) * 0x30 / $width; - #my $g = ($width - $x - 1) * 0x30 / $width; + my $r = $x * $bright / $width; + #my $r = ($width - $x - 1) * $bright / $width; + #my $g = ($width - $x - 1) * $bright / $width; my $g = 0; - my $b = ($height - $y - 1) * 0x30 / $height; + my $b = ($height - $y - 1) * $bright / $height; $s .= chr($r); $s .= chr($g); From 0f4e6587905e8fcd6af8893ab59ec17d635cef8b Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 7 Aug 2013 08:23:44 -0400 Subject: [PATCH 044/332] rework makefile to track dependencies, etc --- Makefile | 105 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 29 deletions(-) diff --git a/Makefile b/Makefile index 0af6107b..fa84f8aa 100755 --- a/Makefile +++ b/Makefile @@ -1,3 +1,14 @@ +######### +# +# The top level targets link in the two .o files for now. +# +TARGETS := rgb-test udp-rx +LEDSCAPE_OBJS = ledscape.o pru.o +LEDSCAPE_LIB := libledscape.a + +all: $(TARGETS) ws281x.bin + + ifeq ($(shell uname -m),armv7l) # We are on the BeagleBone Black itself; # do not cross compile. @@ -10,54 +21,82 @@ else # sudo apt-get install gcc-arm-linux-gnueabi # export CROSS_COMPILE?=arm-linux-gnueabi- -#export CROSS_COMPILE endif -LIBDIR_APP_LOADER?=./am335x/app_loader/lib -INCDIR_APP_LOADER?=./am335x/app_loader/include - CFLAGS += \ -std=c99 \ + -W \ -Wall \ - -I$(INCDIR_APP_LOADER) \ - -D__DEBUG \ + -Wp,-MMD,$(dir $@).$(notdir $@).d \ + -Wp,-MT,$@ \ + -I. \ -O2 \ -mtune=cortex-a8 \ -march=armv7-a \ LDFLAGS += \ - -L$(LIBDIR_APP_LOADER) \ - -lprussdrv \ + +LDLIBS += \ -lpthread \ -PASM := ./am335x/pasm/pasm -TARGET := rgb-test +COMPILE.o = $(CROSS_COMPILE)gcc $(CFLAGS) -c -o $@ $< +COMPILE.a = $(CROSS_COMPILE)gcc -c -o $@ $< +COMPILE.link = $(CROSS_COMPILE)gcc $(LDFLAGS) -o $@ $^ $(LDLIBS) + -_DEPS = -DEPS = $(patsubst %,$(INCDIR_APP_LOADER)/%,$(_DEPS)) +##### +# +# The TI "app_loader" is the userspace library for talking to +# the PRU and mapping memory between it and the ARM. +# +APP_LOADER_DIR ?= ./am335x/app_loader +APP_LOADER_LIB := $(APP_LOADER_DIR)/lib/libprussdrv.a +CFLAGS += -I$(APP_LOADER_DIR)/include +LDLIBS += $(APP_LOADER_LIB) -OBJS = ledscape.o pru.o +##### +# +# The TI PRU assembler looks like it has macros and includes, +# but it really doesn't. So instead we use cpp to pre-process the +# file and then strip out all of the directives that it adds. +# PASM also doesn't handle multiple statements per line, so we +# insert hard newline characters for every ; in the file. +# +PASM_DIR ?= ./am335x/pasm +PASM := $(PASM_DIR)/pasm -%.o: %.c $(DEPS) - $(CROSS_COMPILE)gcc $(CFLAGS) -c -o $@ $< +%.bin: %.p $(PASM) + $(CPP) - < $< | perl -p -e 's/^#.*//; s/;/\n/g' > $<.i + $(PASM) -V3 -b $<.i $(basename $@) + $(RM) $<.i -all: rgb-test udp-rx ws281x.bin -rgb-test: rgb-test.o $(OBJS) - $(CROSS_COMPILE)gcc $(CFLAGS) -o $@ $^ $(LDFLAGS) +%.o: %.c + $(COMPILE.o) -udp-rx: udp-rx.o $(OBJS) - $(CROSS_COMPILE)gcc $(CFLAGS) -o $@ $^ $(LDFLAGS) +$(foreach O,$(TARGETS),$(eval $O: $O.o $(LEDSCAPE_OBJS) $(APP_LOADER_LIB))) -ws281x.bin: ws281x.p ws281x.hp - $(CPP) - < $< | grep -v '^#' | sed 's/;/\n/g' > $<.i - $(PASM) -V3 -b $<.i +$(TARGETS): + $(COMPILE.link) .PHONY: clean clean: - rm -rf *.o *.i *~ $(INCDIR_APP_LOADER)/*~ $(TARGET) ../bin/ws281x.bin ws281x.bin - + rm -rf \ + *.o \ + *.i \ + .*.o.d \ + *~ \ + $(INCDIR_APP_LOADER)/*~ \ + $(TARGET) \ + ws281x.bin \ + + +########### +# +# The correct way to reserve the GPIO pins on the BBB is with the +# capemgr and a Device Tree file. But it doesn't work. +# SLOT_FILE=/sys/devices/bone_capemgr.8/slots dts: LEDscape.dts @SLOT="`grep LEDSCAPE $(SLOT_FILE) | cut -d: -f1`"; \ @@ -69,7 +108,15 @@ dts: LEDscape.dts echo BB-LEDSCAPE > $(SLOT_FILE) -# Libraries and compiler -depend: - $(MAKE) -C am335x/app_loader/interface - $(MAKE) -C am335x/pasm +########### +# +# PRU Libraries and PRU assembler are build from their own trees. +# +$(APP_LOADER_LIB): + $(MAKE) -C $(APP_LOADER_DIR)/interface + +$(PASM): + $(MAKE) -C $(PASM_DIR) + +# Include all of the generated dependency files +-include .*.o.d From 15947df5934a951d8fb670b2a65337171f4414d5 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 7 Aug 2013 19:08:17 -0400 Subject: [PATCH 045/332] one per line --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fa84f8aa..bb8e550c 100755 --- a/Makefile +++ b/Makefile @@ -2,7 +2,10 @@ # # The top level targets link in the two .o files for now. # -TARGETS := rgb-test udp-rx +TARGETS += teensy-udp-rx +TARGETS += rgb-test +TARGETS += udp-rx + LEDSCAPE_OBJS = ledscape.o pru.o LEDSCAPE_LIB := libledscape.a From 127a9af87a818eb93e6ba58bab8fc4e01d4245fa Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Thu, 8 Aug 2013 00:18:33 +0000 Subject: [PATCH 046/332] Reliability in the face of flaky hardware. Spin off a separate thread to reopen the teensy devices when they go away. Use a hard coded (soon to be config file) list of teensys. --- teensy-udp-rx.c | 290 +++++++++++++++++++++++++++++++----------------- 1 file changed, 189 insertions(+), 101 deletions(-) diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index c178d3c9..da882291 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -6,6 +6,10 @@ * * Designed to clock data out to USB teensy3 serial devices, which require * bitslicing into the raw form for the OctoWS2811 firmware. + * + * Since the teensy devices might come and go, this allows them to go into + * a disconnected state and will attempt to reconnect when the device port + * re-appears. */ #include #include @@ -19,8 +23,13 @@ #include #include #include +#include #include "util.h" +static int port = 9999; +static unsigned width = 10; +static unsigned height = 128; + /** Prepare one Teensy3 worth of image data. * Each Teensy handles 8 rows of data and needs the bits sliced into @@ -95,6 +104,39 @@ udp_socket( } +/** Write all the bytes to a fd, even if there is a brief interruption. + * \return number of bytes written or -1 on any fatal error. + */ +static ssize_t +write_all( + const int fd, + const void * const buf_ptr, + const size_t len +) +{ + const uint8_t * const buf = buf_ptr; + size_t offset = 0; + + while (offset < len) + { + const ssize_t rc = write(fd, buf + offset, len - offset); + if (rc < 0) + { + if (errno == EAGAIN) + continue; + return -1; + } + + if (rc == 0) + return -1; + + offset += rc; + } + + return len; +} + + static int serial_open( const char * const dev @@ -114,12 +156,19 @@ serial_open( } +typedef struct +{ + const char * dev; + unsigned id; + int fd; +} teensy_dev_t; + + typedef struct { unsigned id; - unsigned fd; unsigned y_offset; - const char * dev; + teensy_dev_t * dev; uint8_t bad[256]; // which pixels are to be masked out } teensy_strip_t; @@ -131,152 +180,182 @@ static teensy_strip_t strips[] = { { .id = 8998, .y_offset = 24, .bad = { [1] = 0x80, } }, }; + +static teensy_dev_t teensy_devs[] = { + { "/dev/ttyACM0", 0, -1 }, + { "/dev/ttyACM1", 0, -1 }, + { "/dev/ttyACM2", 0, -1 }, + { "/dev/ttyACM3", 0, -1 }, +}; + + static const unsigned num_strips = sizeof(strips) / sizeof(*strips); +static const unsigned num_devs = sizeof(teensy_devs) / sizeof(*teensy_devs); -static teensy_strip_t * strip_find( - const char * const dev, - const int fd, - const unsigned id +static teensy_strip_t * +strip_find( + teensy_dev_t * const dev ) { // Look through our table to find where this one goes for (unsigned j = 0 ; j < num_strips ; j++) { teensy_strip_t * const leds = &strips[j]; - if (leds->id != id) + if (leds->id != dev->id) continue; if (leds->dev != NULL) { fprintf(stderr, "FATAL: %s: Duplicate ID %u (%s)\n", - dev, id, leds->dev); + dev->dev, dev->id, leds->dev->dev); return NULL; } leds->dev = dev; - leds->fd = fd; return leds; } - fprintf(stderr, "FATAL: %s: Unknown ID %u\n", dev, id); + fprintf(stderr, "FATAL: %s: Unknown ID %u\n", dev->dev, dev->id); return NULL; } -static ssize_t -write_all( - const int fd, - const void * const buf_ptr, - const size_t len +static void +strip_close( + teensy_strip_t * const strip ) { - const uint8_t * const buf = buf_ptr; - size_t offset = 0; + teensy_dev_t * const dev = strip->dev; + if (!dev) + return; - while (offset < len) + if (dev->fd >= 0) + close(dev->fd); + + dev->fd = -1; + dev->id = 0; + strip->dev = NULL; +} + + +static int +teensy_open( + teensy_dev_t * const dev +) +{ + dev->fd = serial_open(dev->dev); + if (dev->fd < 0) { - const ssize_t rc = write(fd, buf + offset, len - offset); - if (rc < 0) - { - if (errno == EAGAIN) - continue; - return -1; - } + if (errno == ENOENT) + return 0; - if (rc == 0) - return -1; + warn("%s: Unable to open serial port: %s\n", + dev->dev, + strerror(errno) + ); - offset += rc; + // Something else went wrong + goto fail; } - return len; -} - + // Find out the serial number of this teensy + ssize_t rc; + rc = write_all(dev->fd, "?", 1); + if (rc < 0) + { + warn("%s: write failed: %s\n", dev->dev, strerror(errno)); + goto fail; + } -int -main( - int argc, - char ** argv -) -{ - int port = 9999; - unsigned width = 10; - unsigned height = 128; + // \todo: Read until a newline or a timeout + usleep(100000); + char response[128]; + rc = read(dev->fd, response, sizeof(response)-1); + if (rc < 0) + { + warn("%s: read failed: %s\n", dev->dev, strerror(errno)); + goto fail; + } - const unsigned num_devs = argc - 1; - if (num_devs != num_strips) - die("Must specify %u serial devices\n", num_strips); + response[rc] = '\0'; + if (0) printf("read: '%s'\n", response); - int failed = 0; - for (int i = 1 ; i < argc ; i++) + unsigned this_width; + if (sscanf(response, "%d,%*d,%*d,%d", &this_width, &dev->id) != 2) { - const char * const dev = argv[i]; - const int fd = serial_open(dev); - if (fd < 0) - { - warn("%s: Unable to open serial port: %s\n", - dev, - strerror(errno) - ); - failed++; - continue; - } + warn("%s: Unable to parse response: '%s'\n", dev->dev, response); + goto fail; + } - // Find out the serial number of this teensy - ssize_t rc; - rc = write(fd, "?", 1); - if (rc < 0) - { - warn("%s: write failed: %s\n", dev, strerror(errno)); - failed++; - continue; - } + printf("%s: ID %d width %d\n", dev->dev, dev->id, this_width); - usleep(100000); - char response[128]; - rc = read(fd, response, sizeof(response)-1); - if (rc < 0) - { - warn("%s: read failed: %s\n", dev, strerror(errno)); - failed++; - continue; - } + if (dev->id == 0) + { + warn("%s: dev id == 0. NOT GOOD\n", dev->dev); + goto fail; + } - response[rc] = '\0'; - if (0) printf("read: '%s'\n", response); + if (this_width != width) + { + warn("%s: width %d != expected %d\n", dev->dev, this_width, width); + goto fail; + } + + teensy_strip_t * const leds = strip_find(dev); + if (!leds) + goto fail; + + return 1; + +fail: + dev->id = 0; + if (dev->fd >= 0) + close(dev->fd); + return -1; +} - unsigned this_width; - unsigned this_id; - if (sscanf(response, "%d,%*d,%*d,%d", &this_width, &this_id) != 2) - { - warn("%s: Unable to parse response: '%s'\n", dev, response); - failed++; - continue; - } - printf("%s: ID %d width %d\n", dev, this_id, this_width); - if (this_width != width) +static void * +reopen_thread( + void * const arg +) +{ + (void) arg; + + while (1) + { + for (unsigned i = 0 ; i < num_devs ; i++) { - warn("%s: width %d != expected %d\n", dev, this_width, width); - failed++; - continue; + teensy_dev_t * const dev = &teensy_devs[i]; + if (dev->id != 0) + continue; + teensy_open(dev); } - teensy_strip_t * const leds = strip_find(dev, fd, this_id); - if (!leds) - failed++; + sleep(1); } - if (failed) - die("FATAL CONFIGURATION ERROR\n"); + return NULL; +} + - printf("%d serial ports\n", num_devs); + +int +main( + int argc, + char ** argv +) +{ const int sock = udp_socket(port); if (sock < 0) die("socket port %d failed: %s\n", port, strerror(errno)); + pthread_t reopen_tid; + if (pthread_create(&reopen_tid, NULL, reopen_thread, NULL) < 0) + die("pthread create failed: %s\n", strerror(errno)); + const size_t image_size = width * height * 3; const size_t slice_size = width * 8 * 3 + 3; uint8_t * const slice = calloc(1, slice_size); @@ -327,7 +406,12 @@ main( // for each teensy. for (unsigned i = 0 ; i < num_strips ; i++) { - const teensy_strip_t * const strip = &strips[i]; + teensy_strip_t * const strip = &strips[i]; + teensy_dev_t * const dev = strip->dev; + + // If it hasn't been opened yet, go onto the next one + if (!dev) + continue; bitslice( slice + 3, @@ -338,21 +422,25 @@ main( ); const ssize_t rc - = write_all(strip->fd, slice, slice_size); + = write_all(dev->fd, slice, slice_size); + + if ((size_t) rc == slice_size) + continue; if (rc < 0) - die("%s: write failed: %s\n", + warn("%s: write failed: %s\n", strip->dev, strerror(errno) ); - - if ((size_t) rc != slice_size) - die("%s: short write %zu != %zu: %s\n", + else + warn("%s: short write %zu != %zu: %s\n", strip->dev, rc, slice_size, strerror(errno) ); + + strip_close(strip); } } From 3db9a37f69dad96f85708f5563bb936d01727d5f Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Thu, 8 Aug 2013 00:56:56 +0000 Subject: [PATCH 047/332] Config file parser mostly works; pretty hacky --- config.txt | 5 ++++ teensy-udp-rx.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 config.txt diff --git a/config.txt b/config.txt new file mode 100644 index 00000000..24398a25 --- /dev/null +++ b/config.txt @@ -0,0 +1,5 @@ +10,9999 +14401,0, +14389,8,1:1,2:3,3:3,4:4 +8987,16,1:4,2:3,3:2 +8998,24,4:4 diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index da882291..bad63398 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -163,22 +163,27 @@ typedef struct int fd; } teensy_dev_t; +#define MAX_STRIPS 32 +#define MAX_PIXELS 256 typedef struct { unsigned id; unsigned y_offset; teensy_dev_t * dev; - uint8_t bad[256]; // which pixels are to be masked out + uint8_t bad[MAX_PIXELS]; // which pixels are to be masked out } teensy_strip_t; // \todo read this from a file at run time -static teensy_strip_t strips[] = { +static teensy_strip_t strips[MAX_STRIPS] = { +#if 0 { .id = 14401, .y_offset = 0, .bad = { [2] = 1, } }, { .id = 14389, .y_offset = 8, .bad = { [3] = 1, [4] = 1, } }, { .id = 8987, .y_offset = 16, .bad = { [0] = 0xFF, } }, { .id = 8998, .y_offset = 24, .bad = { [1] = 0x80, } }, +#endif }; +static unsigned num_strips; static teensy_dev_t teensy_devs[] = { @@ -189,7 +194,6 @@ static teensy_dev_t teensy_devs[] = { }; -static const unsigned num_strips = sizeof(strips) / sizeof(*strips); static const unsigned num_devs = sizeof(teensy_devs) / sizeof(*teensy_devs); @@ -340,6 +344,67 @@ reopen_thread( } +/** Config file format; + * + * $(WIDTH),$(PORT) + * $(DEVID),$(YOFFSET),$(BAD_STRIP):$(BAD_PIXEL),.... + */ +static void +read_config( + const char * const config_file +) +{ + FILE * const f = fopen(config_file, "r"); + if (!f) + die("%s: Unable to open: %s\n", config_file, strerror(errno)); + + if (fscanf(f, "%u,%u\n", &width, &port) != 2) + die("%s: Parse error on image width or port\n", config_file); + + unsigned line = 2; + + for (num_strips = 0 ; num_strips < MAX_STRIPS ; num_strips++, line++) + { + teensy_strip_t * const strip = &strips[num_strips]; + char buf[1024]; + int rc = fscanf(f,"%u,%u,%1024[^\n]\n", + &strip->id, + &strip->y_offset, + buf + ); + if (rc != 2 && rc != 3) + { + if (feof(f)) + break; + die("%s:%d: unable to parse rc=%d\n", config_file, line, rc); + } + + char * s = buf; + do { + char * eol = strchr(s, ','); + if (eol) + *eol++ = '\0'; + if (*s == '\0' || *s == '\n') + break; + + unsigned bad_strip; + unsigned bad_pixel; + + if (sscanf(s, "%u:%u", &bad_strip, &bad_pixel) != 2) + die("%s:%d: unable to parse bad pixels '%s'\n", config_file, line, s); + + if (bad_strip >= MAX_STRIPS) + die("%s:%d: bad bad strip %u line %d\n", config_file, line, bad_strip); + if (bad_pixel >= MAX_PIXELS) + die("%s:%d: bad bad pixel %u\n", config_file, line, bad_pixel); + strip->bad[bad_pixel] |= 1 << bad_strip; + s = eol; + printf("%u: bad %u:%u\n", strip->id, bad_strip, bad_pixel); + } while (s); + } + +} + int @@ -348,6 +413,10 @@ main( char ** argv ) { + if (argc != 2) + die("Require config file path\n"); + read_config(argv[1]); + const int sock = udp_socket(port); if (sock < 0) die("socket port %d failed: %s\n", port, strerror(errno)); From fda25d601776c26e1854dafb5e81557b10224fc7 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 7 Aug 2013 21:10:10 -0400 Subject: [PATCH 048/332] Clean all targets --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index bb8e550c..fed9e726 100755 --- a/Makefile +++ b/Makefile @@ -91,7 +91,7 @@ clean: .*.o.d \ *~ \ $(INCDIR_APP_LOADER)/*~ \ - $(TARGET) \ + $(TARGETS) \ ws281x.bin \ From 963f9a04ecd32e531e54cf0a06e695cf141cb5fc Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 7 Aug 2013 21:10:21 -0400 Subject: [PATCH 049/332] Send the rainbow --- rainbow | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/rainbow b/rainbow index 61466d73..718621c3 100755 --- a/rainbow +++ b/rainbow @@ -1,29 +1,42 @@ #!/usr/bin/perl use warnings; use strict; +use IO::Socket; +use Time::HiRes 'usleep'; # Make a smooth gradient pattern +my $host = '192.168.7.2:9999'; + +my $sock = IO::Socket::INET->new( + PeerAddr => $host, + Proto => 'udp', +) or die "Socket failed: $!\n"; + my $width = 10; my $height = 32; +my $offset = 0; -my $s = '1'; -my $bright = 0x10; - -for(my $y = 0 ; $y < $height ; $y++) +while (1) { - for(my $x =0 ; $x < $width ; $x++) + $offset++; + my $s = '1'; + my $bright = 0x10; + + for(my $y = 0 ; $y < $height ; $y++) { - my $r = $x * $bright / $width; - #my $r = ($width - $x - 1) * $bright / $width; - #my $g = ($width - $x - 1) * $bright / $width; - my $g = 0; - my $b = ($height - $y - 1) * $bright / $height; - - $s .= chr($r); - $s .= chr($g); - $s .= chr($b); + for(my $x =0 ; $x < $width ; $x++) + { + my $r = (($x + $offset) % $width) * $bright / $width; + my $g = 0; + my $b = (($height - $y - 1 + $offset) % $height) * $bright / $height; + + $s .= chr($r); + $s .= chr($g); + $s .= chr($b); + } } -} -print $s; + $sock->send($s); + usleep(20000); +} From 5fe28db133a58e3c38dd3149b150eba10dd25685 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Thu, 8 Aug 2013 01:11:18 +0000 Subject: [PATCH 050/332] Ignore more things --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 306e1d47..b3efb876 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ pcb/*.b[^r][^d] pcb/*.p[^c][^b] rgb-test am335x/pasm/pasm +.*.d +*~ +*~ From f527b104be8b69b787b83ec640a621acce76ce87 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Thu, 8 Aug 2013 01:23:25 +0000 Subject: [PATCH 051/332] Output the correct name for the port that went away --- teensy-udp-rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index bad63398..503b1701 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -498,7 +498,7 @@ main( if (rc < 0) warn("%s: write failed: %s\n", - strip->dev, + dev->dev, strerror(errno) ); else From 48c9979d92aa1f74fde9ef01dcd257e772f9fbe2 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Thu, 8 Aug 2013 01:25:34 +0000 Subject: [PATCH 052/332] format string fixups --- teensy-udp-rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 503b1701..b9c0c758 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -394,7 +394,7 @@ read_config( die("%s:%d: unable to parse bad pixels '%s'\n", config_file, line, s); if (bad_strip >= MAX_STRIPS) - die("%s:%d: bad bad strip %u line %d\n", config_file, line, bad_strip); + die("%s:%d: bad bad strip %u\n", config_file, line, bad_strip); if (bad_pixel >= MAX_PIXELS) die("%s:%d: bad bad pixel %u\n", config_file, line, bad_pixel); strip->bad[bad_pixel] |= 1 << bad_strip; @@ -503,7 +503,7 @@ main( ); else warn("%s: short write %zu != %zu: %s\n", - strip->dev, + dev->dev, rc, slice_size, strerror(errno) From 155d0b04259ad59121dfe6bbd0c9acd8523c94fc Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Thu, 8 Aug 2013 01:29:37 +0000 Subject: [PATCH 053/332] Only warn once --- teensy-udp-rx.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index b9c0c758..57caa18a 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -159,8 +159,9 @@ serial_open( typedef struct { const char * dev; - unsigned id; int fd; + unsigned id; + int warned; } teensy_dev_t; #define MAX_STRIPS 32 @@ -187,10 +188,10 @@ static unsigned num_strips; static teensy_dev_t teensy_devs[] = { - { "/dev/ttyACM0", 0, -1 }, - { "/dev/ttyACM1", 0, -1 }, - { "/dev/ttyACM2", 0, -1 }, - { "/dev/ttyACM3", 0, -1 }, + { .dev = "/dev/ttyACM0", .fd = -1 }, + { .dev = "/dev/ttyACM1", .fd = -1 }, + { .dev = "/dev/ttyACM2", .fd = -1 }, + { .dev = "/dev/ttyACM3", .fd = -1 }, }; @@ -268,10 +269,14 @@ teensy_open( rc = write_all(dev->fd, "?", 1); if (rc < 0) { - warn("%s: write failed: %s\n", dev->dev, strerror(errno)); + if (!dev->warned) + warn("%s: write failed: %s\n", dev->dev, strerror(errno)); + dev->warned = 1; goto fail; } + dev->warned = 0; + // \todo: Read until a newline or a timeout usleep(100000); char response[128]; From e3fb20473dc69ef41ca5271078cfd9cf2e43fbda Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 7 Aug 2013 21:29:49 -0400 Subject: [PATCH 054/332] Setup notes --- BeagleBone-setup.md | 82 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 BeagleBone-setup.md diff --git a/BeagleBone-setup.md b/BeagleBone-setup.md new file mode 100644 index 00000000..950a39b0 --- /dev/null +++ b/BeagleBone-setup.md @@ -0,0 +1,82 @@ +Building +-------- + +SSL install is broken; [http://derekmolloy.ie/fixing-git-and-curl-certificates-problem-on-beaglebone-blac/](disable certs): + + git config --global http.sslVerify false + +Checkout LEDscape and build both PRU and teensy LEDscape code. + + git clone https://osresearch@github.com/osresearch/LEDscape + cd LEDscape + make + + +Teensy config +------------- + +* Code is in `LEDscape/VideoDisplay/` +* Update `LED_WIDTH` to have the maximum length of the strips +* Rebuild and flash to all teensys (do this on the laptop) + +* Find the teensy serial IDs with the `find-serial` tool in LEDscape: + + root@beaglebone:~/LEDscape# ./find-serial + /dev/ttyACM0: 8998 + /dev/ttyACM1: 14401 + /dev/ttyACM2: 14389 + /dev/ttyACM3: 8987 + +* Update `config.txt`. At the minimum it needs the first line with the +maximum strip length and the UDP port number, and four lines for the +teensy serial IDs and their Y-offset in the image buffer. It is ok +to have teensys that are not in use with this BBB so that the same +config file can be used with all of them. + + 10,9999 + 14401,0, + 14389,8, + 8987,16,1:9,0:8 + 8998,24, + +* If there are any bad pixels, they go on the line with that ID. In the +above example, there are two bad pixels, both on the same teensy. +Pixel #9 on strip #1 and pixel #8 on strip #0 are marked as "bad" and +will not be set to anything other than black. + +* Run `teensy-rx-udp` on the BeagleBone. It should report opening all +four serial ports and querying them to find out their configured pixel +lengths (which *must match the config file*): + + root@beaglebone:~/LEDscape# ./teensy-udp-rx config.txt + 8987: bad 1:9 + 8987: bad 0:8 + /dev/ttyACM0: ID 8998 width 10 + /dev/ttyACM1: ID 14401 width 10 + /dev/ttyACM2: ID 14389 width 10 + /dev/ttyACM3: ID 8987 width 10 + +* If a device is cleanly unplugged and replugged, it should report: + + teensy_open:286: /dev/ttyACM1: read failed: Resource temporarily unavailable + main:508: /dev/ttyACM1: write failed: No such device + /dev/ttyACM1: ID 14401 width 10 + +USB problems +------------ + +* USB devices don't show up when the teensy is not plugged in during startup. +* Clean disconnect from HUB is OK. +* Power kill to the teensys and reconnect is not: + + [ 243.372796] musb_stage0_irq 496: bogus host RESUME (b_peripheral) + +* power management seems to just hose the port. +* but.... `lsusb -v` seems to bring them back? +* Solution: + + while true; do + lsusb -v > /dev/null + sleep 5 + done + From d55931c413436d9d44db8379eca3238a48d01090 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 7 Aug 2013 21:32:51 -0400 Subject: [PATCH 055/332] md fixes --- BeagleBone-setup.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BeagleBone-setup.md b/BeagleBone-setup.md index 950a39b0..0477f53d 100644 --- a/BeagleBone-setup.md +++ b/BeagleBone-setup.md @@ -1,11 +1,11 @@ Building -------- -SSL install is broken; [http://derekmolloy.ie/fixing-git-and-curl-certificates-problem-on-beaglebone-blac/](disable certs): +* SSL install is broken; [disable certs](http://derekmolloy.ie/fixing-git-and-curl-certificates-problem-on-beaglebone-blac/): git config --global http.sslVerify false -Checkout LEDscape and build both PRU and teensy LEDscape code. +* Checkout LEDscape and build both PRU and teensy LEDscape code. git clone https://osresearch@github.com/osresearch/LEDscape cd LEDscape @@ -15,7 +15,7 @@ Checkout LEDscape and build both PRU and teensy LEDscape code. Teensy config ------------- -* Code is in `LEDscape/VideoDisplay/` +* Code is in [LEDscape/VideoDisplay](https://github.com/osresearch/LEDscape/VideoDisplay/) * Update `LED_WIDTH` to have the maximum length of the strips * Rebuild and flash to all teensys (do this on the laptop) From 4a5043af42b9589794609a3eb3ef18b2c9419639 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 7 Aug 2013 21:35:00 -0400 Subject: [PATCH 056/332] md fixes --- BeagleBone-setup.md | 50 ++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/BeagleBone-setup.md b/BeagleBone-setup.md index 0477f53d..926ce976 100644 --- a/BeagleBone-setup.md +++ b/BeagleBone-setup.md @@ -3,13 +3,13 @@ Building * SSL install is broken; [disable certs](http://derekmolloy.ie/fixing-git-and-curl-certificates-problem-on-beaglebone-blac/): - git config --global http.sslVerify false + git config --global http.sslVerify false * Checkout LEDscape and build both PRU and teensy LEDscape code. - git clone https://osresearch@github.com/osresearch/LEDscape - cd LEDscape - make + git clone https://osresearch@github.com/osresearch/LEDscape + cd LEDscape + make Teensy config @@ -21,11 +21,11 @@ Teensy config * Find the teensy serial IDs with the `find-serial` tool in LEDscape: - root@beaglebone:~/LEDscape# ./find-serial - /dev/ttyACM0: 8998 - /dev/ttyACM1: 14401 - /dev/ttyACM2: 14389 - /dev/ttyACM3: 8987 + root@beaglebone:~/LEDscape# ./find-serial + /dev/ttyACM0: 8998 + /dev/ttyACM1: 14401 + /dev/ttyACM2: 14389 + /dev/ttyACM3: 8987 * Update `config.txt`. At the minimum it needs the first line with the maximum strip length and the UDP port number, and four lines for the @@ -33,11 +33,11 @@ teensy serial IDs and their Y-offset in the image buffer. It is ok to have teensys that are not in use with this BBB so that the same config file can be used with all of them. - 10,9999 - 14401,0, - 14389,8, - 8987,16,1:9,0:8 - 8998,24, + 10,9999 + 14401,0, + 14389,8, + 8987,16,1:9,0:8 + 8998,24, * If there are any bad pixels, they go on the line with that ID. In the above example, there are two bad pixels, both on the same teensy. @@ -48,19 +48,19 @@ will not be set to anything other than black. four serial ports and querying them to find out their configured pixel lengths (which *must match the config file*): - root@beaglebone:~/LEDscape# ./teensy-udp-rx config.txt - 8987: bad 1:9 - 8987: bad 0:8 - /dev/ttyACM0: ID 8998 width 10 - /dev/ttyACM1: ID 14401 width 10 - /dev/ttyACM2: ID 14389 width 10 - /dev/ttyACM3: ID 8987 width 10 + root@beaglebone:~/LEDscape# ./teensy-udp-rx config.txt + 8987: bad 1:9 + 8987: bad 0:8 + /dev/ttyACM0: ID 8998 width 10 + /dev/ttyACM1: ID 14401 width 10 + /dev/ttyACM2: ID 14389 width 10 + /dev/ttyACM3: ID 8987 width 10 * If a device is cleanly unplugged and replugged, it should report: - teensy_open:286: /dev/ttyACM1: read failed: Resource temporarily unavailable - main:508: /dev/ttyACM1: write failed: No such device - /dev/ttyACM1: ID 14401 width 10 + teensy_open:286: /dev/ttyACM1: read failed: Resource temporarily unavailable + main:508: /dev/ttyACM1: write failed: No such device + /dev/ttyACM1: ID 14401 width 10 USB problems ------------ @@ -69,7 +69,7 @@ USB problems * Clean disconnect from HUB is OK. * Power kill to the teensys and reconnect is not: - [ 243.372796] musb_stage0_irq 496: bogus host RESUME (b_peripheral) + [ 243.372796] musb_stage0_irq 496: bogus host RESUME (b_peripheral) * power management seems to just hose the port. * but.... `lsusb -v` seems to bring them back? From 79efd623ba04dae31a37152ce8b449534c434547 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 7 Aug 2013 21:35:29 -0400 Subject: [PATCH 057/332] md fixes --- BeagleBone-setup.md | 58 ++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/BeagleBone-setup.md b/BeagleBone-setup.md index 926ce976..a8a2c057 100644 --- a/BeagleBone-setup.md +++ b/BeagleBone-setup.md @@ -3,13 +3,13 @@ Building * SSL install is broken; [disable certs](http://derekmolloy.ie/fixing-git-and-curl-certificates-problem-on-beaglebone-blac/): - git config --global http.sslVerify false + git config --global http.sslVerify false * Checkout LEDscape and build both PRU and teensy LEDscape code. - git clone https://osresearch@github.com/osresearch/LEDscape - cd LEDscape - make + git clone https://osresearch@github.com/osresearch/LEDscape + cd LEDscape + make Teensy config @@ -21,11 +21,11 @@ Teensy config * Find the teensy serial IDs with the `find-serial` tool in LEDscape: - root@beaglebone:~/LEDscape# ./find-serial - /dev/ttyACM0: 8998 - /dev/ttyACM1: 14401 - /dev/ttyACM2: 14389 - /dev/ttyACM3: 8987 + root@beaglebone:~/LEDscape# ./find-serial + /dev/ttyACM0: 8998 + /dev/ttyACM1: 14401 + /dev/ttyACM2: 14389 + /dev/ttyACM3: 8987 * Update `config.txt`. At the minimum it needs the first line with the maximum strip length and the UDP port number, and four lines for the @@ -33,11 +33,11 @@ teensy serial IDs and their Y-offset in the image buffer. It is ok to have teensys that are not in use with this BBB so that the same config file can be used with all of them. - 10,9999 - 14401,0, - 14389,8, - 8987,16,1:9,0:8 - 8998,24, + 10,9999 + 14401,0, + 14389,8, + 8987,16,1:9,0:8 + 8998,24, * If there are any bad pixels, they go on the line with that ID. In the above example, there are two bad pixels, both on the same teensy. @@ -48,19 +48,19 @@ will not be set to anything other than black. four serial ports and querying them to find out their configured pixel lengths (which *must match the config file*): - root@beaglebone:~/LEDscape# ./teensy-udp-rx config.txt - 8987: bad 1:9 - 8987: bad 0:8 - /dev/ttyACM0: ID 8998 width 10 - /dev/ttyACM1: ID 14401 width 10 - /dev/ttyACM2: ID 14389 width 10 - /dev/ttyACM3: ID 8987 width 10 + root@beaglebone:~/LEDscape# ./teensy-udp-rx config.txt + 8987: bad 1:9 + 8987: bad 0:8 + /dev/ttyACM0: ID 8998 width 10 + /dev/ttyACM1: ID 14401 width 10 + /dev/ttyACM2: ID 14389 width 10 + /dev/ttyACM3: ID 8987 width 10 * If a device is cleanly unplugged and replugged, it should report: - teensy_open:286: /dev/ttyACM1: read failed: Resource temporarily unavailable - main:508: /dev/ttyACM1: write failed: No such device - /dev/ttyACM1: ID 14401 width 10 + teensy_open:286: /dev/ttyACM1: read failed: Resource temporarily unavailable + main:508: /dev/ttyACM1: write failed: No such device + /dev/ttyACM1: ID 14401 width 10 USB problems ------------ @@ -69,14 +69,14 @@ USB problems * Clean disconnect from HUB is OK. * Power kill to the teensys and reconnect is not: - [ 243.372796] musb_stage0_irq 496: bogus host RESUME (b_peripheral) + [ 243.372796] musb_stage0_irq 496: bogus host RESUME (b_peripheral) * power management seems to just hose the port. * but.... `lsusb -v` seems to bring them back? * Solution: - while true; do - lsusb -v > /dev/null - sleep 5 - done + while true; do + lsusb -v > /dev/null + sleep 5 + done From 268a792572c9cf4e0f8bc6dda23fcac764f4b374 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 10 Aug 2013 12:52:28 -0400 Subject: [PATCH 058/332] add image width to config file, allow comments on first two lines --- config.txt | 5 +++-- teensy-udp-rx.c | 48 +++++++++++++++++++++++++++++++----------------- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/config.txt b/config.txt index 24398a25..3eed3aab 100644 --- a/config.txt +++ b/config.txt @@ -1,5 +1,6 @@ -10,9999 -14401,0, +9999 # UDP port number +10,128 # width,height in pixels (only 32 of the width are on this machine) +14401,0 14389,8,1:1,2:3,3:3,4:4 8987,16,1:4,2:3,3:2 8998,24,4:4 diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 57caa18a..df2376e9 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -278,7 +279,7 @@ teensy_open( dev->warned = 0; // \todo: Read until a newline or a timeout - usleep(100000); + nanosleep(10000000); char response[128]; rc = read(dev->fd, response, sizeof(response)-1); if (rc < 0) @@ -363,28 +364,41 @@ read_config( if (!f) die("%s: Unable to open: %s\n", config_file, strerror(errno)); - if (fscanf(f, "%u,%u\n", &width, &port) != 2) + char line[1024]; + + if (fgets(line, sizeof(line), f) == NULL) + die("%s: Unable to read port num\n", config_file); + + port = atoi(line); + + if (fgets(line, sizeof(line), f) == NULL) + die("%s: Unable to read dimenstions\n", config_file); + + if (sscanf(line, "%u,%u\n", &width, &height) != 2) die("%s: Parse error on image width or port\n", config_file); - unsigned line = 2; + unsigned line_num = 2; - for (num_strips = 0 ; num_strips < MAX_STRIPS ; num_strips++, line++) + for (num_strips = 0 ; num_strips < MAX_STRIPS ; num_strips++, line_num++) { + if (fgets(line, sizeof(line), f) == NULL) + break; + teensy_strip_t * const strip = &strips[num_strips]; - char buf[1024]; - int rc = fscanf(f,"%u,%u,%1024[^\n]\n", + int offset = 0; + int rc = sscanf(line, "%u,%u%n", &strip->id, &strip->y_offset, - buf + &offset ); - if (rc != 2 && rc != 3) - { - if (feof(f)) - break; - die("%s:%d: unable to parse rc=%d\n", config_file, line, rc); - } - char * s = buf; + if (rc != 2) + die("%s:%d: unable to parse rc=%d\n", config_file, line_num, rc); + + char * s = line + offset; + if (*s == ',') + s++; + do { char * eol = strchr(s, ','); if (eol) @@ -396,12 +410,12 @@ read_config( unsigned bad_pixel; if (sscanf(s, "%u:%u", &bad_strip, &bad_pixel) != 2) - die("%s:%d: unable to parse bad pixels '%s'\n", config_file, line, s); + die("%s:%d: unable to parse bad pixels '%s'\n", config_file, line_num, s); if (bad_strip >= MAX_STRIPS) - die("%s:%d: bad bad strip %u\n", config_file, line, bad_strip); + die("%s:%d: bad bad strip %u\n", config_file, line_num, bad_strip); if (bad_pixel >= MAX_PIXELS) - die("%s:%d: bad bad pixel %u\n", config_file, line, bad_pixel); + die("%s:%d: bad bad pixel %u\n", config_file, line_num, bad_pixel); strip->bad[bad_pixel] |= 1 << bad_strip; s = eol; printf("%u: bad %u:%u\n", strip->id, bad_strip, bad_pixel); From 3a01e24ba9317c29e388fc8a18f48f3126a6c470 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 10 Aug 2013 13:03:48 -0400 Subject: [PATCH 059/332] Updated sample config file --- BeagleBone-setup.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/BeagleBone-setup.md b/BeagleBone-setup.md index a8a2c057..bdd393a2 100644 --- a/BeagleBone-setup.md +++ b/BeagleBone-setup.md @@ -33,11 +33,12 @@ teensy serial IDs and their Y-offset in the image buffer. It is ok to have teensys that are not in use with this BBB so that the same config file can be used with all of them. - 10,9999 - 14401,0, - 14389,8, + 9999 # UDP port + 64,256 # Image width x height + 14401,0 + 14389,8 8987,16,1:9,0:8 - 8998,24, + 8998,24 * If there are any bad pixels, they go on the line with that ID. In the above example, there are two bad pixels, both on the same teensy. From b63fe872af19aa69638c9cfc6c50584570098b98 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 10 Aug 2013 17:32:54 +0000 Subject: [PATCH 060/332] Work with actual transmitter code --- config.txt | 2 +- find-serial | 2 ++ teensy-udp-rx.c | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/config.txt b/config.txt index 3eed3aab..0d1c259b 100644 --- a/config.txt +++ b/config.txt @@ -1,5 +1,5 @@ 9999 # UDP port number -10,128 # width,height in pixels (only 32 of the width are on this machine) +210,64 # width,height in pixels (only 32 of the width are on this machine) 14401,0 14389,8,1:1,2:3,3:3,4:4 8987,16,1:4,2:3,3:2 diff --git a/find-serial b/find-serial index b3eb78fe..8259ad11 100755 --- a/find-serial +++ b/find-serial @@ -2,6 +2,8 @@ # Locate the serial ports and their serial numbers. # This can then be used to map devices to positions in the matrix. +lsusb -v > /dev/null + for dev in `find /sys/devices/ -name '*ACM*' `;do DIR=`dirname $dev` TTY=`basename $dev` diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index df2376e9..537ebcbe 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -456,7 +456,7 @@ main( if (rlen < 0) die("recv failed: %s\n", strerror(errno)); - if (buf[0] == '2') + if (buf[0] == 2) { // image type printf("image type: %.*s\n", @@ -466,7 +466,7 @@ main( continue; } - if (buf[0] != '1') + if (buf[0] != 1) { // What is it? warn_once("Unknown image type '%c' (%02x)\n", From e59875ed81a9579e0748967696f5652635af8396 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 1 Jan 2000 01:41:10 +0000 Subject: [PATCH 061/332] trying to slice the other way. not working quite right --- config.txt | 2 +- teensy-udp-rx.c | 67 ++++++++++++++++++++++++++----------------------- 2 files changed, 36 insertions(+), 33 deletions(-) diff --git a/config.txt b/config.txt index 0d1c259b..91b90bc0 100644 --- a/config.txt +++ b/config.txt @@ -1,5 +1,5 @@ 9999 # UDP port number -210,64 # width,height in pixels (only 32 of the width are on this machine) +64,210 # width,height in pixels (only 32 of the width are on this machine) 14401,0 14389,8,1:1,2:3,3:3,4:4 8987,16,1:4,2:3,3:2 diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 537ebcbe..0f7cb72a 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -28,11 +28,23 @@ #include "util.h" static int port = 9999; -static unsigned width = 10; -static unsigned height = 128; +static unsigned width = 64; +static unsigned height = 210; + + +static const uint8_t * +bitmap_pixel( + const uint8_t * const bitmap, + const unsigned x, + const unsigned y +) +{ + return bitmap + (y * width + x) * 3; +} /** Prepare one Teensy3 worth of image data. + * * Each Teensy handles 8 rows of data and needs the bits sliced into * each 8 rows. * @@ -43,18 +55,14 @@ void bitslice( uint8_t * const out, const uint8_t * in, - const unsigned width, - const unsigned y_offset, + const unsigned x_offset, const uint8_t * const bad_pixels ) { // Reorder from RGB in the input to GRB in the output static const uint8_t channel_map[] = { 1, 0, 2 }; - // Skip to the starting row that we're processing - in += y_offset * width * 3; - - for(unsigned x=0 ; x < width ; x++) + for(unsigned y=0 ; y < height ; y++) { for (unsigned channel = 0 ; channel < 3 ; channel++) { @@ -66,18 +74,19 @@ bitslice( uint8_t b = 0; const uint8_t mask = 1 << (7 - bit_num); - for(unsigned y = 0 ; y < 8 ; y++) + for(unsigned x = 0 ; x < 8 ; x++) { - const uint8_t bit_pos = 1 << y; - if (bad_pixels[x] & bit_pos) + const uint8_t bit_pos = 1 << x; + if (bad_pixels[y] & bit_pos) continue; - const uint8_t v - = in[3*(x + y*width) + channel]; + const uint8_t * const p + = bitmap_pixel(in, x + x_offset, y); + const uint8_t v = p[channel]; if (v & mask) b |= bit_pos; } - out[24*x + 8*mapped_channel + bit_num] = b; + out[24*y + 8*mapped_channel + bit_num] = b; } } } @@ -177,14 +186,7 @@ typedef struct } teensy_strip_t; // \todo read this from a file at run time -static teensy_strip_t strips[MAX_STRIPS] = { -#if 0 - { .id = 14401, .y_offset = 0, .bad = { [2] = 1, } }, - { .id = 14389, .y_offset = 8, .bad = { [3] = 1, [4] = 1, } }, - { .id = 8987, .y_offset = 16, .bad = { [0] = 0xFF, } }, - { .id = 8998, .y_offset = 24, .bad = { [1] = 0x80, } }, -#endif -}; +static teensy_strip_t strips[MAX_STRIPS]; static unsigned num_strips; @@ -193,6 +195,10 @@ static teensy_dev_t teensy_devs[] = { { .dev = "/dev/ttyACM1", .fd = -1 }, { .dev = "/dev/ttyACM2", .fd = -1 }, { .dev = "/dev/ttyACM3", .fd = -1 }, + { .dev = "/dev/ttyACM4", .fd = -1 }, + { .dev = "/dev/ttyACM5", .fd = -1 }, + { .dev = "/dev/ttyACM6", .fd = -1 }, + { .dev = "/dev/ttyACM7", .fd = -1 }, }; @@ -279,7 +285,7 @@ teensy_open( dev->warned = 0; // \todo: Read until a newline or a timeout - nanosleep(10000000); + usleep(10000); char response[128]; rc = read(dev->fd, response, sizeof(response)-1); if (rc < 0) @@ -291,14 +297,14 @@ teensy_open( response[rc] = '\0'; if (0) printf("read: '%s'\n", response); - unsigned this_width; - if (sscanf(response, "%d,%*d,%*d,%d", &this_width, &dev->id) != 2) + unsigned this_height; + if (sscanf(response, "%d,%*d,%*d,%d", &this_height, &dev->id) != 2) { warn("%s: Unable to parse response: '%s'\n", dev->dev, response); goto fail; } - printf("%s: ID %d width %d\n", dev->dev, dev->id, this_width); + printf("%s: ID %d height %d\n", dev->dev, dev->id, this_height); if (dev->id == 0) { @@ -306,9 +312,9 @@ teensy_open( goto fail; } - if (this_width != width) + if (this_height != height) { - warn("%s: width %d != expected %d\n", dev->dev, this_width, width); + warn("%s: height %d != expected %d\n", dev->dev, this_height, height); goto fail; } @@ -352,8 +358,6 @@ reopen_thread( /** Config file format; * - * $(WIDTH),$(PORT) - * $(DEVID),$(YOFFSET),$(BAD_STRIP):$(BAD_PIXEL),.... */ static void read_config( @@ -445,7 +449,7 @@ main( die("pthread create failed: %s\n", strerror(errno)); const size_t image_size = width * height * 3; - const size_t slice_size = width * 8 * 3 + 3; + const size_t slice_size = height * 8 * 3 + 3; uint8_t * const slice = calloc(1, slice_size); uint8_t buf[65536]; @@ -504,7 +508,6 @@ main( bitslice( slice + 3, buf + 1, - width, strip->y_offset, strip->bad ); From 8a3baaf4ce8f80172e713dab46e43ccfe325b0a5 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 10 Aug 2013 16:24:55 -0400 Subject: [PATCH 062/332] Hexdump bit sliced versions. Looks ok? --- teensy-udp-rx.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 0f7cb72a..7dbf9c02 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -82,6 +82,10 @@ bitslice( const uint8_t * const p = bitmap_pixel(in, x + x_offset, y); const uint8_t v = p[channel]; + + // If the bit_num'th bit in v is + // set, then mark that the x'th bit + // in this output byte should be set. if (v & mask) b |= bit_pos; } @@ -429,6 +433,24 @@ read_config( } +static void +hexdump( + const void * const buf, + const size_t len +) +{ + const uint8_t * const p = buf; + + for(size_t i = 0 ; i < len ; i++) + { + if (i % 16 == 0) + printf("%s%04zu:", i == 0 ? "": "\n", i); + printf(" %02x", p[i]); + } + + printf("\n"); +} + int main( @@ -452,13 +474,19 @@ main( const size_t slice_size = height * 8 * 3 + 3; uint8_t * const slice = calloc(1, slice_size); + // largest possible UDP packet uint8_t buf[65536]; + if (sizeof(buf) < image_size + 1) + die("%u x %u too large for UDP\n", width, height); + + fprintf(stderr, "%u x %u, UDP port %u\n", width, height, port); while (1) { const ssize_t rlen = recv(sock, buf, sizeof(buf), 0); if (rlen < 0) die("recv failed: %s\n", strerror(errno)); + warn_once("received %zu bytes\n", rlen); if (buf[0] == 2) { @@ -494,6 +522,18 @@ main( slice[1] = 0; slice[2] = 0; +#if 0 + bitslice( + slice + 3, + buf + 1, + 8, + strips[0].bad + ); + + hexdump(buf+1, rlen-1); + hexdump(slice+3, slice_size-3); + +#else // Translate the image from packed RGB into sliced 24-bit // for each teensy. for (unsigned i = 0 ; i < num_strips ; i++) @@ -533,6 +573,7 @@ main( strip_close(strip); } +#endif } return 0; From 41833f353e7744bcc623f23cb90be344a78cd9cf Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 10 Aug 2013 16:39:21 -0400 Subject: [PATCH 063/332] rename y_offset to x_offset --- BeagleBone-setup.md | 9 +++++---- teensy-udp-rx.c | 13 +++++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/BeagleBone-setup.md b/BeagleBone-setup.md index bdd393a2..5abe3fd5 100644 --- a/BeagleBone-setup.md +++ b/BeagleBone-setup.md @@ -29,12 +29,12 @@ Teensy config * Update `config.txt`. At the minimum it needs the first line with the maximum strip length and the UDP port number, and four lines for the -teensy serial IDs and their Y-offset in the image buffer. It is ok +teensy serial IDs and their X-offset in the image buffer. It is ok to have teensys that are not in use with this BBB so that the same config file can be used with all of them. 9999 # UDP port - 64,256 # Image width x height + 64,210 # Image width x height 14401,0 14389,8 8987,16,1:9,0:8 @@ -43,13 +43,14 @@ config file can be used with all of them. * If there are any bad pixels, they go on the line with that ID. In the above example, there are two bad pixels, both on the same teensy. Pixel #9 on strip #1 and pixel #8 on strip #0 are marked as "bad" and -will not be set to anything other than black. +will not be set to anything other than black. Bad pixels are +measured from the start of the strip, not the image. * Run `teensy-rx-udp` on the BeagleBone. It should report opening all four serial ports and querying them to find out their configured pixel lengths (which *must match the config file*): - root@beaglebone:~/LEDscape# ./teensy-udp-rx config.txt + root@beaglebone:~/LEDscape# ./teensy-udp-rx config.txt 8987: bad 1:9 8987: bad 0:8 /dev/ttyACM0: ID 8998 width 10 diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 7dbf9c02..03c166e7 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -32,6 +32,11 @@ static unsigned width = 64; static unsigned height = 210; +/** Extract a ADDRESSING_HORIZONTAL_NORMAL pixel from the image. + * + * This reverses the y since the teensy's are at the bottom of the + * strips, while the image coordinate frame is at the top. + */ static const uint8_t * bitmap_pixel( const uint8_t * const bitmap, @@ -39,7 +44,7 @@ bitmap_pixel( const unsigned y ) { - return bitmap + (y * width + x) * 3; + return bitmap + ((height - y - 1) * width + x) * 3; } @@ -184,7 +189,7 @@ typedef struct typedef struct { unsigned id; - unsigned y_offset; + unsigned x_offset; teensy_dev_t * dev; uint8_t bad[MAX_PIXELS]; // which pixels are to be masked out } teensy_strip_t; @@ -396,7 +401,7 @@ read_config( int offset = 0; int rc = sscanf(line, "%u,%u%n", &strip->id, - &strip->y_offset, + &strip->x_offset, &offset ); @@ -548,7 +553,7 @@ main( bitslice( slice + 3, buf + 1, - strip->y_offset, + strip->x_offset, strip->bad ); From 502545959c0d8810b5612db6ef55fff184c7e09e Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 10 Aug 2013 22:45:19 -0400 Subject: [PATCH 064/332] add time stamping --- teensy-udp-rx.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 03c166e7..692f97aa 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -527,6 +528,9 @@ main( slice[1] = 0; slice[2] = 0; + struct timeval start_tv, stop_tv, delta_tv; + gettimeofday(&start_tv, NULL); + #if 0 bitslice( slice + 3, @@ -535,8 +539,8 @@ main( strips[0].bad ); - hexdump(buf+1, rlen-1); - hexdump(slice+3, slice_size-3); + //hexdump(buf+1, rlen-1); + //hexdump(slice+3, slice_size-3); #else // Translate the image from packed RGB into sliced 24-bit @@ -579,6 +583,9 @@ main( strip_close(strip); } #endif + gettimeofday(&stop_tv, NULL); + timersub(&stop_tv, &start_tv, &delta_tv); + printf("%u.%06u sec\n", delta_tv.tv_sec, delta_tv.tv_usec); } return 0; From 1c92fe65c438fb166f07ad977b3b4901ec9ffc33 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 08:10:53 -0400 Subject: [PATCH 065/332] Moved bitslice() into bitslice.c, moved hexdump into util.h --- Makefile | 2 +- bitslice.c | 89 ++++++++++++++++++++++++++++++++++++++++++ bitslice.h | 25 ++++++++++++ teensy-udp-rx.c | 101 ++++-------------------------------------------- test-bitslice.c | 53 +++++++++++++++++++++++++ util.h | 19 +++++++++ 6 files changed, 195 insertions(+), 94 deletions(-) create mode 100644 bitslice.c create mode 100644 bitslice.h create mode 100644 test-bitslice.c diff --git a/Makefile b/Makefile index fed9e726..e582c252 100755 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ TARGETS += teensy-udp-rx TARGETS += rgb-test TARGETS += udp-rx -LEDSCAPE_OBJS = ledscape.o pru.o +LEDSCAPE_OBJS = ledscape.o pru.o bitslice.o LEDSCAPE_LIB := libledscape.a all: $(TARGETS) ws281x.bin diff --git a/bitslice.c b/bitslice.c new file mode 100644 index 00000000..931040b2 --- /dev/null +++ b/bitslice.c @@ -0,0 +1,89 @@ +/** \file + * Slice an RGB image into an 8-pixel GRB packed format for the Teensy. + * + * Designed to clock data out to USB teensy3 serial devices, which require + * bitslicing into the raw form for the OctoWS2811 firmware. + */ +#include +#include +#include +#include +#include "bitslice.h" + + +/** Extract a ADDRESSING_HORIZONTAL_NORMAL pixel from the image. + * + * This reverses the y since the teensy's are at the bottom of the + * strips, while the image coordinate frame is at the top. + */ +static const uint8_t * +bitmap_pixel( + const uint8_t * const bitmap, + const unsigned width, + const unsigned height, + const unsigned x, + const unsigned y +) +{ + if (1) + return bitmap + ((height - y - 1) * width + x) * 3; + else + return bitmap + ((height - y - 1) + x * height) * 3; +} + + +/** Prepare one Teensy3 worth of image data. + * + * Each Teensy handles 8 rows of data and needs the bits sliced into + * each 8 rows. + * + * Since some of the pixels might have bad single channels, + * allow them to be masked out entirely. + */ +void +bitslice( + uint8_t * const out, + const uint8_t * const bad_pixels, + const uint8_t * in, + const unsigned width, + const unsigned height, + const unsigned x_offset +) +{ + // Reorder from RGB in the input to GRB in the output + static const uint8_t channel_map[] = { 1, 0, 2 }; + + for(unsigned y=0 ; y < height ; y++) + { + for (unsigned channel = 0 ; channel < 3 ; channel++) + { + const uint8_t mapped_channel + = channel_map[channel]; + + for (unsigned bit_num = 0 ; bit_num < 8 ; bit_num++) + { + uint8_t b = 0; + const uint8_t mask = 1 << (7 - bit_num); + + for(unsigned x = 0 ; x < 8 ; x++) + { + const uint8_t bit_pos = 1 << x; + if (bad_pixels + && bad_pixels[y] & bit_pos) + continue; + const uint8_t * const p + = bitmap_pixel(in, width, height, x + x_offset, y); + const uint8_t v = p[channel]; + + // If the bit_num'th bit in v is + // set, then mark that the x'th bit + // in this output byte should be set. + if (v & mask) + b |= bit_pos; + } + + out[24*y + 8*mapped_channel + bit_num] = b; + } + } + } +} diff --git a/bitslice.h b/bitslice.h new file mode 100644 index 00000000..da85dd05 --- /dev/null +++ b/bitslice.h @@ -0,0 +1,25 @@ +#ifndef _ledscape_bitslice_h_ +#define _ledscape_bitslice_h_ + +#include + + +/** Prepare one Teensy3 worth of image data. + * + * Each Teensy handles 8 rows of data and needs the bits sliced into + * each 8 rows. + * + * Since some of the pixels might have bad single channels, + * allow them to be masked out entirely. + */ +extern void +bitslice( + uint8_t * const out, + const uint8_t * const bad_pixels, + const uint8_t * in, + const unsigned width, + const unsigned height, + const unsigned x_offset +); + +#endif diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 692f97aa..41827cdd 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -27,82 +27,12 @@ #include #include #include "util.h" +#include "bitslice.h" static int port = 9999; static unsigned width = 64; static unsigned height = 210; - -/** Extract a ADDRESSING_HORIZONTAL_NORMAL pixel from the image. - * - * This reverses the y since the teensy's are at the bottom of the - * strips, while the image coordinate frame is at the top. - */ -static const uint8_t * -bitmap_pixel( - const uint8_t * const bitmap, - const unsigned x, - const unsigned y -) -{ - return bitmap + ((height - y - 1) * width + x) * 3; -} - - -/** Prepare one Teensy3 worth of image data. - * - * Each Teensy handles 8 rows of data and needs the bits sliced into - * each 8 rows. - * - * Since some of the pixels might have bad single channels, - * allow them to be masked out entirely. - */ -void -bitslice( - uint8_t * const out, - const uint8_t * in, - const unsigned x_offset, - const uint8_t * const bad_pixels -) -{ - // Reorder from RGB in the input to GRB in the output - static const uint8_t channel_map[] = { 1, 0, 2 }; - - for(unsigned y=0 ; y < height ; y++) - { - for (unsigned channel = 0 ; channel < 3 ; channel++) - { - const uint8_t mapped_channel - = channel_map[channel]; - - for (unsigned bit_num = 0 ; bit_num < 8 ; bit_num++) - { - uint8_t b = 0; - const uint8_t mask = 1 << (7 - bit_num); - - for(unsigned x = 0 ; x < 8 ; x++) - { - const uint8_t bit_pos = 1 << x; - if (bad_pixels[y] & bit_pos) - continue; - const uint8_t * const p - = bitmap_pixel(in, x + x_offset, y); - const uint8_t v = p[channel]; - - // If the bit_num'th bit in v is - // set, then mark that the x'th bit - // in this output byte should be set. - if (v & mask) - b |= bit_pos; - } - - out[24*y + 8*mapped_channel + bit_num] = b; - } - } - } -} - - static int udp_socket( const int port @@ -439,25 +369,6 @@ read_config( } -static void -hexdump( - const void * const buf, - const size_t len -) -{ - const uint8_t * const p = buf; - - for(size_t i = 0 ; i < len ; i++) - { - if (i % 16 == 0) - printf("%s%04zu:", i == 0 ? "": "\n", i); - printf(" %02x", p[i]); - } - - printf("\n"); -} - - int main( int argc, @@ -534,9 +445,11 @@ main( #if 0 bitslice( slice + 3, + strips[0].bad buf + 1, + width, + height 8, - strips[0].bad ); //hexdump(buf+1, rlen-1); @@ -556,9 +469,11 @@ main( bitslice( slice + 3, + strip->bad, buf + 1, - strip->x_offset, - strip->bad + width, + height, + strip->x_offset ); const ssize_t rc diff --git a/test-bitslice.c b/test-bitslice.c new file mode 100644 index 00000000..f422ff37 --- /dev/null +++ b/test-bitslice.c @@ -0,0 +1,53 @@ +#include +#include "bitslice.h" +#include "util.h" + +int main(void) +{ + uint8_t bitmap[9][2][3] = { + { + { 0xFF, 0xFF, 0xFF }, + { 0x00, 0x00, 0x00 }, + }, + { + { 0xFF, 0xFF, 0xFF }, + { 0x00, 0x00, 0x00 }, + }, + { + { 0xFF, 0xFF, 0xFF }, + { 0x00, 0x00, 0x00 }, + }, + { + { 0xFF, 0xFF, 0xFF }, + { 0x00, 0x00, 0x00 }, + }, + { + { 0xFF, 0xFF, 0xFF }, + { 0x00, 0x00, 0x00 }, + }, + { + { 0xFF, 0xFF, 0xFF }, + { 0x00, 0x00, 0x00 }, + }, + { + { 0xFF, 0xFF, 0xFF }, + { 0x00, 0x00, 0x00 }, + }, + { + { 0xFF, 0xFF, 0xFF }, + { 0x00, 0x00, 0x00 }, + }, + { + { 0xFF, 0xFF, 0xFF }, + { 0x00, 0x00, 0x00 }, + }, + }; + + hexdump(bitmap, sizeof(bitmap)); + + uint8_t out[1024]; + + bitslice(out, NULL, bitmap, 9, 2, 1); + + hexdump(out, 8 * 2 * 3); +} diff --git a/util.h b/util.h index 9ea616b2..ec8cd3b6 100644 --- a/util.h +++ b/util.h @@ -31,4 +31,23 @@ exit(EXIT_FAILURE); \ } while(0) + +static inline void +hexdump( + const void * const buf, + const size_t len +) +{ + const uint8_t * const p = buf; + + for(size_t i = 0 ; i < len ; i++) + { + if (i % 16 == 0) + printf("%s%04zu:", i == 0 ? "": "\n", i); + printf(" %02x", p[i]); + } + + printf("\n"); +} + #endif From 4d34b9aaf135f91f40dd872e523ca480c106d7b6 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 08:11:15 -0400 Subject: [PATCH 066/332] ignore generated a.out --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b3efb876..725666a9 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ am335x/pasm/pasm .*.d *~ *~ +a.out From 92c3365f3c9bfc148dee6e2f1b6ed5b415ae07f5 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 08:27:25 -0400 Subject: [PATCH 067/332] Arrange the test array the right way --- test-bitslice.c | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/test-bitslice.c b/test-bitslice.c index f422ff37..c8c89add 100644 --- a/test-bitslice.c +++ b/test-bitslice.c @@ -4,42 +4,28 @@ int main(void) { - uint8_t bitmap[9][2][3] = { + uint8_t bitmap[2][9][3] = { { { 0xFF, 0xFF, 0xFF }, { 0x00, 0x00, 0x00 }, - }, - { { 0xFF, 0xFF, 0xFF }, { 0x00, 0x00, 0x00 }, - }, - { { 0xFF, 0xFF, 0xFF }, { 0x00, 0x00, 0x00 }, - }, - { { 0xFF, 0xFF, 0xFF }, { 0x00, 0x00, 0x00 }, - }, - { { 0xFF, 0xFF, 0xFF }, - { 0x00, 0x00, 0x00 }, }, { - { 0xFF, 0xFF, 0xFF }, { 0x00, 0x00, 0x00 }, - }, - { - { 0xFF, 0xFF, 0xFF }, - { 0x00, 0x00, 0x00 }, - }, - { { 0xFF, 0xFF, 0xFF }, - { 0x00, 0x00, 0x00 }, - }, - { - { 0xFF, 0xFF, 0xFF }, - { 0x00, 0x00, 0x00 }, + { 0x01, 0x02, 0x04 }, + { 0xF2, 0xF4, 0xF8 }, + { 0x04, 0x08, 0x10 }, + { 0xF8, 0xF0, 0x22 }, + { 0x10, 0x20, 0x40 }, + { 0xF1, 0x4F, 0x8F }, + { 0x02, 0x80, 0x00 }, }, }; @@ -47,7 +33,7 @@ int main(void) uint8_t out[1024]; - bitslice(out, NULL, bitmap, 9, 2, 1); + bitslice(out, NULL, (const uint8_t*) bitmap, 9, 2, 1); hexdump(out, 8 * 2 * 3); } From c350d9bf8e46c409587e17d3bdc23932ba8a0d0d Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 12:49:27 +0000 Subject: [PATCH 068/332] Linux needs _BSD_SOURCE to find timersub() --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index e582c252..abfa6323 100755 --- a/Makefile +++ b/Makefile @@ -30,6 +30,7 @@ CFLAGS += \ -std=c99 \ -W \ -Wall \ + -D_BSD_SOURCE \ -Wp,-MMD,$(dir $@).$(notdir $@).d \ -Wp,-MT,$@ \ -I. \ From 14d3357ac59c6e069371fdbe7837bdbaba3e5d56 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 12:49:35 +0000 Subject: [PATCH 069/332] Track avg fps --- teensy-udp-rx.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 41827cdd..22d66b5d 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -398,6 +398,11 @@ main( fprintf(stderr, "%u x %u, UDP port %u\n", width, height, port); + const unsigned report_interval = 10; + unsigned last_report = 0; + unsigned long delta_sum = 0; + unsigned frames = 0; + while (1) { const ssize_t rlen = recv(sock, buf, sizeof(buf), 0); @@ -500,7 +505,21 @@ main( #endif gettimeofday(&stop_tv, NULL); timersub(&stop_tv, &start_tv, &delta_tv); - printf("%u.%06u sec\n", delta_tv.tv_sec, delta_tv.tv_usec); + + frames++; + delta_sum += delta_tv.tv_usec; + if (stop_tv.tv_sec - last_report < report_interval) + continue; + + const unsigned delta_avg = delta_sum / frames; + printf("%6u usec avg, max %.2f fps, actual %.2f fps (over %u frames)\n", + delta_avg, + report_interval * 1.0e6 / delta_avg, + frames * 1.0 / report_interval, + frames + ); + + frames = delta_sum = 0; } return 0; From cd035f82df9b1cca6cba6fc90c068445ca0c4f66 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 12:53:08 +0000 Subject: [PATCH 070/332] remember when we last printed a status --- teensy-udp-rx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 22d66b5d..4749b86e 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -510,6 +510,7 @@ main( delta_sum += delta_tv.tv_usec; if (stop_tv.tv_sec - last_report < report_interval) continue; + last_report = stop_tv.tv_sec; const unsigned delta_avg = delta_sum / frames; printf("%6u usec avg, max %.2f fps, actual %.2f fps (over %u frames)\n", From 8eccf648d9cbac7b7ee8ce2d47ac113f552b4ba7 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 08:58:55 -0400 Subject: [PATCH 071/332] Actual size for the real display --- VideoDisplay/VideoDisplay.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VideoDisplay/VideoDisplay.ino b/VideoDisplay/VideoDisplay.ino index ea2757b3..a52233f9 100644 --- a/VideoDisplay/VideoDisplay.ino +++ b/VideoDisplay/VideoDisplay.ino @@ -73,7 +73,7 @@ // Since the receiving program on the host is slicing the image, // only the width matters. The height is always 8. // -#define LED_WIDTH 10 // number of LEDs horizontally +#define LED_WIDTH 210 // number of LEDs horizontally #define LED_HEIGHT 8 // number of LEDs vertically (must be 8) #define LED_LAYOUT 0 // 0 = even rows left->right, 1 = even rows right->left From af26ebb099cc6381bd9b07d91af433445e35dd11 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 08:59:08 -0400 Subject: [PATCH 072/332] Actual size for the real display --- checkerboard | 46 ++++++++++++++++++++++++++++++++++++++++++++++ rainbow | 10 +++++----- 2 files changed, 51 insertions(+), 5 deletions(-) create mode 100755 checkerboard diff --git a/checkerboard b/checkerboard new file mode 100755 index 00000000..5977379b --- /dev/null +++ b/checkerboard @@ -0,0 +1,46 @@ +#!/usr/bin/perl +use warnings; +use strict; +use IO::Socket; +use Time::HiRes 'usleep'; + +# Make an RGB checkerboard +my $host = '192.168.7.2:9999'; + +my $sock = IO::Socket::INET->new( + PeerAddr => $host, + Proto => 'udp', +) or die "Socket failed: $!\n"; + + +my $width = 64; +my $height = 210; +my $offset = 0; + +my $i = 0; + +while (1) +{ + $offset++; + my $s = chr(1); + my $bright = 0x30; + + for(my $y = 0 ; $y < $height ; $y++) + { + for(my $x = 0; $x < $width ; $x++) + { + my $r = ($i % 7 == 0) ? $bright : 0; + my $g = ($i % 7 == 1) ? $bright : 0; + my $b = ($i % 7 == 2) ? $bright : 0; + + $s .= chr($r); + $s .= chr($g); + $s .= chr($b); + $i++; + } + } + + $sock->send($s); + usleep(80000); + $i++; +} diff --git a/rainbow b/rainbow index 718621c3..d498ad2f 100755 --- a/rainbow +++ b/rainbow @@ -13,19 +13,19 @@ my $sock = IO::Socket::INET->new( ) or die "Socket failed: $!\n"; -my $width = 10; -my $height = 32; +my $width = 64; +my $height = 210; my $offset = 0; while (1) { $offset++; - my $s = '1'; - my $bright = 0x10; + my $s = chr(1); + my $bright = 0x30; for(my $y = 0 ; $y < $height ; $y++) { - for(my $x =0 ; $x < $width ; $x++) + for(my $x = 0; $x < $width ; $x++) { my $r = (($x + $offset) % $width) * $bright / $width; my $g = 0; From 7b1a075e311de43246fc722da08de3ec8920a20d Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 13:09:56 +0000 Subject: [PATCH 073/332] script to configure the bbb network over usb --- bbb-network-setup | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100755 bbb-network-setup diff --git a/bbb-network-setup b/bbb-network-setup new file mode 100755 index 00000000..2a0a64ac --- /dev/null +++ b/bbb-network-setup @@ -0,0 +1,12 @@ +#!/bin/sh +DIR="`dirname $0`" +cd "$DIR" + +route add default gw 192.168.7.1 +echo 'nameserver 8.8.8.8' > /etc/resolv.conf +echo >&2 "setting date" +ntpdate -s pool.ntp.org +date + +echo >&2 "probing serial ports" +./find-serial From 0f24b4682e8a911eaa057f8ede34aeded1de55d9 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 10:43:20 -0400 Subject: [PATCH 074/332] this one shows the problem --- checkerboard | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/checkerboard b/checkerboard index 5977379b..371d25a2 100755 --- a/checkerboard +++ b/checkerboard @@ -29,9 +29,10 @@ while (1) { for(my $x = 0; $x < $width ; $x++) { - my $r = ($i % 7 == 0) ? $bright : 0; - my $g = ($i % 7 == 1) ? $bright : 0; - my $b = ($i % 7 == 2) ? $bright : 0; + my $c = $i % 7; + my $r = ($c == 0 || $c == 2) ? $bright : 0; + my $g = ($c == 1 || $c == 2) ? $bright : 0; + my $b = 0; #($i % 7 == 2) ? $bright : 0; $s .= chr($r); $s .= chr($g); @@ -41,6 +42,7 @@ while (1) } $sock->send($s); - usleep(80000); + usleep(1e6/4); + #usleep(10); $i++; } From cca7ff21df24fd768aeaa113dc8314885c15478e Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 11:56:55 -0400 Subject: [PATCH 075/332] Move util functions into util.c, continue debugging checkerboard errors --- Makefile | 2 +- teensy-udp-rx.c | 54 ++--------------------------- util.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ util.h | 34 ++++++++++-------- 4 files changed, 114 insertions(+), 67 deletions(-) create mode 100644 util.c diff --git a/Makefile b/Makefile index abfa6323..bc228376 100755 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ TARGETS += teensy-udp-rx TARGETS += rgb-test TARGETS += udp-rx -LEDSCAPE_OBJS = ledscape.o pru.o bitslice.o +LEDSCAPE_OBJS = ledscape.o pru.o bitslice.o utils.o LEDSCAPE_LIB := libledscape.a all: $(TARGETS) ws281x.bin diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 4749b86e..891eb377 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -54,58 +54,6 @@ udp_socket( } -/** Write all the bytes to a fd, even if there is a brief interruption. - * \return number of bytes written or -1 on any fatal error. - */ -static ssize_t -write_all( - const int fd, - const void * const buf_ptr, - const size_t len -) -{ - const uint8_t * const buf = buf_ptr; - size_t offset = 0; - - while (offset < len) - { - const ssize_t rc = write(fd, buf + offset, len - offset); - if (rc < 0) - { - if (errno == EAGAIN) - continue; - return -1; - } - - if (rc == 0) - return -1; - - offset += rc; - } - - return len; -} - - -static int -serial_open( - const char * const dev -) -{ - const int fd = open(dev, O_RDWR | O_NONBLOCK | O_NOCTTY, 0666); - if (fd < 0) - return -1; - - // Disable modem control signals - struct termios attr; - tcgetattr(fd, &attr); - attr.c_cflag |= CLOCAL | CREAD; - tcsetattr(fd, TCSANOW, &attr); - - return fd; -} - - typedef struct { const char * dev; @@ -481,6 +429,8 @@ main( strip->x_offset ); + hexdump(slice+3, slice_size-3); + const ssize_t rc = write_all(dev->fd, slice, slice_size); diff --git a/util.c b/util.c new file mode 100644 index 00000000..0ad430ee --- /dev/null +++ b/util.c @@ -0,0 +1,91 @@ +/** \file + * Various utility functions + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "bitslice.h" + +/** Write all the bytes to a fd, even if there is a brief interruption. + * \return number of bytes written or -1 on any fatal error. + */ +ssize_t +write_all( + const int fd, + const void * const buf_ptr, + const size_t len +) +{ + const uint8_t * const buf = buf_ptr; + size_t offset = 0; + + while (offset < len) + { + const ssize_t rc = write(fd, buf + offset, len - offset); + if (rc < 0) + { + if (errno == EAGAIN) + continue; + return -1; + } + + if (rc == 0) + return -1; + + offset += rc; + } + + return len; +} + + +int +serial_open( + const char * const dev +) +{ + const int fd = open(dev, O_RDWR | O_NONBLOCK | O_NOCTTY, 0666); + if (fd < 0) + return -1; + + // Disable modem control signals + struct termios attr; + tcgetattr(fd, &attr); + attr.c_cflag |= CLOCAL | CREAD; + tcsetattr(fd, TCSANOW, &attr); + + return fd; +} + + +void +hexdump( + const void * const buf, + const size_t len +) +{ + const uint8_t * const p = buf; + + for(size_t i = 0 ; i < len ; i++) + { + if (i % 8 == 0) + printf("%s%04zu:", i == 0 ? "": "\n", i); + printf(" %02x", p[i]); + } + + printf("\n"); +} + diff --git a/util.h b/util.h index ec8cd3b6..68efd1f6 100644 --- a/util.h +++ b/util.h @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -32,22 +33,27 @@ } while(0) -static inline void +extern void hexdump( const void * const buf, const size_t len -) -{ - const uint8_t * const p = buf; - - for(size_t i = 0 ; i < len ; i++) - { - if (i % 16 == 0) - printf("%s%04zu:", i == 0 ? "": "\n", i); - printf(" %02x", p[i]); - } - - printf("\n"); -} +); + + +extern int +serial_open( + const char * const dev +); + + +/** Write all the bytes to a fd, even if there is a brief interruption. + * \return number of bytes written or -1 on any fatal error. + */ +extern ssize_t +write_all( + const int fd, + const void * const buf_ptr, + const size_t len +); #endif From 631f89f69d5dc8d3198d110043158072f31e6a1c Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 15:58:37 +0000 Subject: [PATCH 076/332] Check bitslice for any blue channel at low intensity --- teensy-udp-rx.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- test-bitslice.c | 16 ++++++++-------- util.h | 7 ++++--- 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 4749b86e..5e28bc06 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -369,6 +369,39 @@ read_config( } +static int +bitslice_check( + const uint8_t * const slice, + const size_t len +) +{ + // Walk one of the strips to find if there are any 0xFF values + for (size_t i = 0 ; i < len ; i += 8) + { + uint8_t byte = 0; + for (unsigned bit_num = 0 ; bit_num < 8 ; bit_num++) + { + byte <<= 1; + if (slice[i + bit_num] & 1) + byte |= 0x1; + } + + // for the fire demo there is NEVER blue + if ((i / 8) % 3 == 2 && byte != 0) + return -1; + + //printf(" %02x", byte); + //if (byte < 0x10) + continue; + warn("bad byte at %u: %02x\n", i, byte); + return -1; + } + //printf("\n"); + + return 0; +} + + int main( int argc, @@ -440,9 +473,9 @@ main( // Header for the frame to the teensy indicating that it // is to be drawn immediately. - slice[0] = '$'; + slice[0] = '*'; slice[1] = 0; - slice[2] = 0; + slice[2] = 1; struct timeval start_tv, stop_tv, delta_tv; gettimeofday(&start_tv, NULL); @@ -484,6 +517,16 @@ main( const ssize_t rc = write_all(dev->fd, slice, slice_size); + if (bitslice_check(slice+3, slice_size-3) < 0) + { + warn("bad slice! rc=%zu image:\n", rc); + hexdump(stderr, buf+1, image_size); + warn("slice %u\n", strip->x_offset); + hexdump(stderr, slice+3, slice_size-3); + die("FAILED\n"); + } + + if ((size_t) rc == slice_size) continue; diff --git a/test-bitslice.c b/test-bitslice.c index c8c89add..8b348555 100644 --- a/test-bitslice.c +++ b/test-bitslice.c @@ -6,19 +6,19 @@ int main(void) { uint8_t bitmap[2][9][3] = { { - { 0xFF, 0xFF, 0xFF }, + { 0x03, 0x03, 0x03 }, { 0x00, 0x00, 0x00 }, - { 0xFF, 0xFF, 0xFF }, + { 0x03, 0x03, 0x03 }, { 0x00, 0x00, 0x00 }, - { 0xFF, 0xFF, 0xFF }, + { 0x03, 0x03, 0x03 }, { 0x00, 0x00, 0x00 }, - { 0xFF, 0xFF, 0xFF }, + { 0x03, 0x03, 0x03 }, { 0x00, 0x00, 0x00 }, - { 0xFF, 0xFF, 0xFF }, + { 0x03, 0x03, 0x03 }, }, { { 0x00, 0x00, 0x00 }, - { 0xFF, 0xFF, 0xFF }, + { 0x03, 0x03, 0x03 }, { 0x01, 0x02, 0x04 }, { 0xF2, 0xF4, 0xF8 }, { 0x04, 0x08, 0x10 }, @@ -29,11 +29,11 @@ int main(void) }, }; - hexdump(bitmap, sizeof(bitmap)); + hexdump(stdout, bitmap, sizeof(bitmap)); uint8_t out[1024]; bitslice(out, NULL, (const uint8_t*) bitmap, 9, 2, 1); - hexdump(out, 8 * 2 * 3); + hexdump(stdout, out, 8 * 2 * 3); } diff --git a/util.h b/util.h index ec8cd3b6..894c3b91 100644 --- a/util.h +++ b/util.h @@ -34,6 +34,7 @@ static inline void hexdump( + FILE * const outfile, const void * const buf, const size_t len ) @@ -43,11 +44,11 @@ hexdump( for(size_t i = 0 ; i < len ; i++) { if (i % 16 == 0) - printf("%s%04zu:", i == 0 ? "": "\n", i); - printf(" %02x", p[i]); + fprintf(outfile, "%s%04zu:", i == 0 ? "": "\n", i); + fprintf(outfile, " %02x", p[i]); } - printf("\n"); + fprintf(outfile, "\n"); } #endif From 46d24c9a8f5416b003ad8ab4fc7ed0009ebcfc1a Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 13:37:55 -0400 Subject: [PATCH 077/332] known bad slice? --- bad-pattern.c | 18 ++ bad-pattern.txt | 631 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 649 insertions(+) create mode 100644 bad-pattern.c create mode 100644 bad-pattern.txt diff --git a/bad-pattern.c b/bad-pattern.c new file mode 100644 index 00000000..f52a4568 --- /dev/null +++ b/bad-pattern.c @@ -0,0 +1,18 @@ +#include +#include "util.h" + +int main(void) +{ + int fd = serial_open("/dev/ttyACM1"); + if (fd < 0) + die("open failed"); + + static const uint8_t bad_pattern[] = + { +#include "bad-pattern.txt" + }; + + write_all(fd, bad_pattern, sizeof(bad_pattern)); + + return 0; +} diff --git a/bad-pattern.txt b/bad-pattern.txt new file mode 100644 index 00000000..01da6a39 --- /dev/null +++ b/bad-pattern.txt @@ -0,0 +1,631 @@ +0x2a, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 From 9540fec1eb4503d378bd21b53ff37b3ce49cd912 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 18:45:02 +0000 Subject: [PATCH 078/332] Mask out the 4th bit and everything works. WTF? --- bitslice.c | 2 +- teensy-udp-rx.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/bitslice.c b/bitslice.c index 931040b2..511d3b15 100644 --- a/bitslice.c +++ b/bitslice.c @@ -82,7 +82,7 @@ bitslice( b |= bit_pos; } - out[24*y + 8*mapped_channel + bit_num] = b; + out[24*y + 8*mapped_channel + bit_num] = b & 0xF7; } } } diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 4989534f..95dc0e6b 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -462,11 +462,13 @@ main( strip->x_offset ); - hexdump(stderr, slice+3, slice_size-3); + if (0 && strip->x_offset == 0) + hexdump(stderr, slice+3, slice_size-3); const ssize_t rc = write_all(dev->fd, slice, slice_size); +#if 0 if (bitslice_check(slice+3, slice_size-3) < 0) { warn("bad slice! rc=%zu image:\n", rc); @@ -475,6 +477,7 @@ main( hexdump(stderr, slice+3, slice_size-3); die("FAILED\n"); } +#endif if ((size_t) rc == slice_size) From 830e351ad19a2ac3b087ebe1ccf52ad57c6e43a9 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 18:45:23 +0000 Subject: [PATCH 079/332] More bad bit pattern testing. Yes, channel 4 is bad. --- bad-pattern.c | 17 +++++++--- bad-pattern.txt | 85 ++++++++++++++++++++++++------------------------- 2 files changed, 54 insertions(+), 48 deletions(-) diff --git a/bad-pattern.c b/bad-pattern.c index f52a4568..7d19935a 100644 --- a/bad-pattern.c +++ b/bad-pattern.c @@ -1,18 +1,25 @@ #include #include "util.h" -int main(void) +int main(int argc, char **argv) { - int fd = serial_open("/dev/ttyACM1"); + const char * dev = argc > 1 ? argv[1] : "/dev/ttyACM2"; + int fd = serial_open(dev); if (fd < 0) - die("open failed"); + die("%s: open failed\n", dev); - static const uint8_t bad_pattern[] = + static uint8_t bad_pattern[] = { + 0x2a,0x00,0x00 #include "bad-pattern.txt" +//#include "zeros.txt" }; - write_all(fd, bad_pattern, sizeof(bad_pattern)); + for (size_t i = 3 ; i < sizeof(bad_pattern) ; i++) + bad_pattern[i] &= 0x0F; + + ssize_t rc = write_all(fd, bad_pattern, sizeof(bad_pattern)); + fprintf(stderr, "rc=%zu\n", rc); return 0; } diff --git a/bad-pattern.txt b/bad-pattern.txt index 01da6a39..1e309f89 100644 --- a/bad-pattern.txt +++ b/bad-pattern.txt @@ -1,40 +1,39 @@ -0x2a, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x08, 0x00, 0x08, 0x00, 0x00, 0xCC, 0x0c, 0x0c +, 0x08, 0x00, 0x08, 0x00, 0xFF, 0xCC, 0x0a, 0x0a +, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x08, 0x00, 0x08, 0x00, 0xFF, 0xCC, 0x18, 0x18 +, 0x08, 0x00, 0x08, 0x00, 0x11, 0xCC, 0x14, 0x14 +, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x08, 0x00, 0x08, 0x00, 0xFF, 0xFF, 0x30, 0x30 +, 0x08, 0x00, 0x08, 0x00, 0xFF, 0xFF, 0x28, 0x28 +, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x08, 0x00, 0x08, 0x00, 0x11, 0x00, 0x60, 0x60 +, 0x08, 0x00, 0x08, 0x00, 0x11, 0x00, 0x50, 0x50 +, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x08, 0x00, 0x08, 0x00, 0x11, 0x00, 0xc1, 0xc1 +, 0x08, 0x00, 0x08, 0x00, 0x11, 0x00, 0xa1, 0xa1 +, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x08, 0x00, 0x08, 0x00, 0x11, 0x00, 0x83, 0x83 +, 0x08, 0x00, 0x08, 0x00, 0x11, 0x00, 0x42, 0x42 +, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x06 +, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x0c +, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x0a +, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 +, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 +, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 +, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 +, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 +, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 +, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 +, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 @@ -620,12 +619,12 @@ , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 +, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xc1, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xa1, 0xa1 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x83, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x42, 0x42 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x06, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x85, 0x85 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 From 58bdb96c814a50ba033c67eba635cf28e8690376 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 21:04:48 +0000 Subject: [PATCH 080/332] switch between strips 2 and 4 --- bitslice.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/bitslice.c b/bitslice.c index 511d3b15..be6498c8 100644 --- a/bitslice.c +++ b/bitslice.c @@ -82,7 +82,15 @@ bitslice( b |= bit_pos; } - out[24*y + 8*mapped_channel + bit_num] = b & 0xF7; + // octows2811 bug? if strips 2 and 4 are + // both on there are massive glitches. + // switch between them each frame. + // this sucks, but works + static unsigned toggle = 0; + b &= ~(toggle ? 0x8 : 0x2); + toggle = !toggle; + + out[24*y + 8*mapped_channel + bit_num] = b; } } } From 2516ee42051f25f0cf03010feaeb9d58b2f29387 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 21:19:20 +0000 Subject: [PATCH 081/332] Move masking / checkerboarding into main rather than bitslice --- bitslice.c | 8 -------- teensy-udp-rx.c | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/bitslice.c b/bitslice.c index be6498c8..931040b2 100644 --- a/bitslice.c +++ b/bitslice.c @@ -82,14 +82,6 @@ bitslice( b |= bit_pos; } - // octows2811 bug? if strips 2 and 4 are - // both on there are massive glitches. - // switch between them each frame. - // this sucks, but works - static unsigned toggle = 0; - b &= ~(toggle ? 0x8 : 0x2); - toggle = !toggle; - out[24*y + 8*mapped_channel + bit_num] = b; } } diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 95dc0e6b..42ed1239 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -383,6 +383,7 @@ main( unsigned last_report = 0; unsigned long delta_sum = 0; unsigned frames = 0; + unsigned toggle = 0; while (1) { @@ -442,6 +443,8 @@ main( //hexdump(slice+3, slice_size-3); #else + toggle = !toggle; + // Translate the image from packed RGB into sliced 24-bit // for each teensy. for (unsigned i = 0 ; i < num_strips ; i++) @@ -465,6 +468,18 @@ main( if (0 && strip->x_offset == 0) hexdump(stderr, slice+3, slice_size-3); + // octows2811 bug? if strips 2 and 4 are + // both on there are massive glitches. + // switch between them each frame. + // this sucks, but works + toggle = 0; + for (size_t i = 0 ; i < slice_size - 3 ; i++) + { + if (i % 24 == 0) + toggle = !toggle; + slice[i+3] &= ~(toggle ? 0x8 : 0x2); + } + const ssize_t rc = write_all(dev->fd, slice, slice_size); From 8c01a2c836c3bb4a69fa88c49193f01d425c31c7 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 21:43:51 +0000 Subject: [PATCH 082/332] Screw it; disable strip 4 --- teensy-udp-rx.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 42ed1239..370ffddf 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -383,7 +383,6 @@ main( unsigned last_report = 0; unsigned long delta_sum = 0; unsigned frames = 0; - unsigned toggle = 0; while (1) { @@ -443,8 +442,6 @@ main( //hexdump(slice+3, slice_size-3); #else - toggle = !toggle; - // Translate the image from packed RGB into sliced 24-bit // for each teensy. for (unsigned i = 0 ; i < num_strips ; i++) @@ -472,12 +469,13 @@ main( // both on there are massive glitches. // switch between them each frame. // this sucks, but works - toggle = 0; + unsigned toggle = 0; for (size_t i = 0 ; i < slice_size - 3 ; i++) { if (i % 24 == 0) toggle = !toggle; - slice[i+3] &= ~(toggle ? 0x8 : 0x2); + //slice[i+3] &= ~(toggle ? 0x8 : 0x2); + slice[i+3] &= 0xF7; } const ssize_t rc From c5a52fe092a497d18aca6bae15f03c92c27c727f Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 11 Aug 2013 22:53:36 +0000 Subject: [PATCH 083/332] Simple bad pattern example --- bad-pattern.c | 8 +- bad-pattern.txt | 648 +++--------------------------------------------- 2 files changed, 33 insertions(+), 623 deletions(-) diff --git a/bad-pattern.c b/bad-pattern.c index 7d19935a..dff8d975 100644 --- a/bad-pattern.c +++ b/bad-pattern.c @@ -3,20 +3,22 @@ int main(int argc, char **argv) { +#if 1 const char * dev = argc > 1 ? argv[1] : "/dev/ttyACM2"; int fd = serial_open(dev); if (fd < 0) die("%s: open failed\n", dev); +#endif - static uint8_t bad_pattern[] = + static uint8_t bad_pattern[210*8*3+3] = { 0x2a,0x00,0x00 #include "bad-pattern.txt" //#include "zeros.txt" }; - for (size_t i = 3 ; i < sizeof(bad_pattern) ; i++) - bad_pattern[i] &= 0x0F; + for (size_t i = 3+24 ; i < sizeof(bad_pattern) ; i++) + bad_pattern[i] &= 0xFF; ssize_t rc = write_all(fd, bad_pattern, sizeof(bad_pattern)); fprintf(stderr, "rc=%zu\n", rc); diff --git a/bad-pattern.txt b/bad-pattern.txt index 1e309f89..8ee7c787 100644 --- a/bad-pattern.txt +++ b/bad-pattern.txt @@ -1,630 +1,38 @@ -, 0x08, 0x00, 0x08, 0x00, 0x00, 0xCC, 0x0c, 0x0c -, 0x08, 0x00, 0x08, 0x00, 0xFF, 0xCC, 0x0a, 0x0a -, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x08, 0x00, 0x08, 0x00, 0xFF, 0xCC, 0x18, 0x18 -, 0x08, 0x00, 0x08, 0x00, 0x11, 0xCC, 0x14, 0x14 -, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x08, 0x00, 0x08, 0x00, 0xFF, 0xFF, 0x30, 0x30 -, 0x08, 0x00, 0x08, 0x00, 0xFF, 0xFF, 0x28, 0x28 -, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x08, 0x00, 0x08, 0x00, 0x11, 0x00, 0x60, 0x60 -, 0x08, 0x00, 0x08, 0x00, 0x11, 0x00, 0x50, 0x50 -, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x08, 0x00, 0x08, 0x00, 0x11, 0x00, 0xc1, 0xc1 -, 0x08, 0x00, 0x08, 0x00, 0x11, 0x00, 0xa1, 0xa1 -, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x08, 0x00, 0x08, 0x00, 0x11, 0x00, 0x83, 0x83 -, 0x08, 0x00, 0x08, 0x00, 0x11, 0x00, 0x42, 0x42 -, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a /* Change to 0x0a to 0x02 and it is fine */ , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 + +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a + +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 + +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 + +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 + +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 + +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 + +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 + +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xc1, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xa1, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x83, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x42, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x06, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x85, 0x85 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30 +, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 From 5351381dca8fcee24473b90bafb0a44f1c97d24d Mon Sep 17 00:00:00 2001 From: Naim Busek Date: Thu, 15 Aug 2013 01:03:03 -0700 Subject: [PATCH 084/332] enabling raw output --- util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/util.c b/util.c index 3ece4329..723043b0 100644 --- a/util.c +++ b/util.c @@ -65,6 +65,7 @@ serial_open( struct termios attr; tcgetattr(fd, &attr); attr.c_cflag |= CLOCAL | CREAD; + attr.c_oflag &= ~OPOST; tcsetattr(fd, TCSANOW, &attr); return fd; From 5bb6a93d5546f89f73c4fb41ab3266fe25bd2e9d Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 16 Aug 2013 19:41:52 -0400 Subject: [PATCH 085/332] remove lots of debugging code --- teensy-udp-rx.c | 77 +------------------------------------------------ 1 file changed, 1 insertion(+), 76 deletions(-) diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c index 370ffddf..9f6f34df 100644 --- a/teensy-udp-rx.c +++ b/teensy-udp-rx.c @@ -317,39 +317,6 @@ read_config( } -static int -bitslice_check( - const uint8_t * const slice, - const size_t len -) -{ - // Walk one of the strips to find if there are any 0xFF values - for (size_t i = 0 ; i < len ; i += 8) - { - uint8_t byte = 0; - for (unsigned bit_num = 0 ; bit_num < 8 ; bit_num++) - { - byte <<= 1; - if (slice[i + bit_num] & 1) - byte |= 0x1; - } - - // for the fire demo there is NEVER blue - if ((i / 8) % 3 == 2 && byte != 0) - return -1; - - //printf(" %02x", byte); - //if (byte < 0x10) - continue; - warn("bad byte at %u: %02x\n", i, byte); - return -1; - } - //printf("\n"); - - return 0; -} - - int main( int argc, @@ -428,20 +395,6 @@ main( struct timeval start_tv, stop_tv, delta_tv; gettimeofday(&start_tv, NULL); -#if 0 - bitslice( - slice + 3, - strips[0].bad - buf + 1, - width, - height - 8, - ); - - //hexdump(buf+1, rlen-1); - //hexdump(slice+3, slice_size-3); - -#else // Translate the image from packed RGB into sliced 24-bit // for each teensy. for (unsigned i = 0 ; i < num_strips ; i++) @@ -462,37 +415,9 @@ main( strip->x_offset ); - if (0 && strip->x_offset == 0) - hexdump(stderr, slice+3, slice_size-3); - - // octows2811 bug? if strips 2 and 4 are - // both on there are massive glitches. - // switch between them each frame. - // this sucks, but works - unsigned toggle = 0; - for (size_t i = 0 ; i < slice_size - 3 ; i++) - { - if (i % 24 == 0) - toggle = !toggle; - //slice[i+3] &= ~(toggle ? 0x8 : 0x2); - slice[i+3] &= 0xF7; - } - const ssize_t rc = write_all(dev->fd, slice, slice_size); -#if 0 - if (bitslice_check(slice+3, slice_size-3) < 0) - { - warn("bad slice! rc=%zu image:\n", rc); - hexdump(stderr, buf+1, image_size); - warn("slice %u\n", strip->x_offset); - hexdump(stderr, slice+3, slice_size-3); - die("FAILED\n"); - } -#endif - - if ((size_t) rc == slice_size) continue; @@ -511,7 +436,7 @@ main( strip_close(strip); } -#endif + gettimeofday(&stop_tv, NULL); timersub(&stop_tv, &start_tv, &delta_tv); From 4379ae89e8efe10c58bd2cb583589cddf5eb1dae Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 16 Aug 2013 19:52:41 -0400 Subject: [PATCH 086/332] improve comment --- VideoDisplay/VideoDisplay.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VideoDisplay/VideoDisplay.ino b/VideoDisplay/VideoDisplay.ino index a52233f9..b56e4255 100644 --- a/VideoDisplay/VideoDisplay.ino +++ b/VideoDisplay/VideoDisplay.ino @@ -84,8 +84,8 @@ // video it displays. By reading these numbers, the video application can // automatically configure itself, regardless of which serial port COM number // or device names are assigned to each Teensy 3.0 by your operating system. -#define VIDEO_XOFFSET 0 -#define VIDEO_YOFFSET 0 // display entire image +#define VIDEO_XOFFSET 0 // always 0 for Disorient pyramid +#define VIDEO_YOFFSET 0 // display entire image -- always 0 for Disorient pyramid #define VIDEO_WIDTH 100 #define VIDEO_HEIGHT 100 From 1fe41c7731f4002d992ef342b0aa59e2ca345068 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 6 Sep 2013 12:47:34 -0400 Subject: [PATCH 087/332] 16x2 LED matrix bracket --- matrix-bracket.scad | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 matrix-bracket.scad diff --git a/matrix-bracket.scad b/matrix-bracket.scad new file mode 100644 index 00000000..b5e20580 --- /dev/null +++ b/matrix-bracket.scad @@ -0,0 +1,20 @@ +/** \file + * Bracket to hold a 16x2 LED panel in an Octoscroller configuration. + */ + +module bracket() +{ + render() difference() + { + cube([16,5,10]); + + translate([13,10,5]) + rotate([90,0,0]) + cylinder(r=2, h=20, $fs=1); + } +} + +rotate([0,0,+45/2]) bracket(); +rotate([0,0,-45/2-180]) translate([0,-5,0]) bracket(); + +%translate([0,0,-1]) cube([200,200,2], center=true); From d40fee6cbb1d15d00f5b082e1366590725d86e6f Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 6 Sep 2013 18:12:09 -0400 Subject: [PATCH 088/332] As printed --- matrix-bracket.scad | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/matrix-bracket.scad b/matrix-bracket.scad index b5e20580..2306a779 100644 --- a/matrix-bracket.scad +++ b/matrix-bracket.scad @@ -2,11 +2,11 @@ * Bracket to hold a 16x2 LED panel in an Octoscroller configuration. */ -module bracket() +module bracket_half() { render() difference() { - cube([16,5,10]); + cube([18,7,10]); translate([13,10,5]) rotate([90,0,0]) @@ -14,7 +14,19 @@ module bracket() } } -rotate([0,0,+45/2]) bracket(); -rotate([0,0,-45/2-180]) translate([0,-5,0]) bracket(); +module bracket() +{ + rotate([0,0,+45/2]) bracket_half(); + rotate([0,0,-45/2-180]) translate([0,-7,0]) bracket_half(); +} + +for (i = [0:1]) +{ + translate([i*35,0,0]) { + for (j = [0:7]) { + translate([0,10*j,0]) bracket(); + } + } +} %translate([0,0,-1]) cube([200,200,2], center=true); From e2a1b192df5705c3437f006c573d234cced63c7a Mon Sep 17 00:00:00 2001 From: root Date: Sat, 1 Jan 2000 15:04:04 +0000 Subject: [PATCH 089/332] started on LED matrix code; this breaks the ws2821x code for now --- matrix-test.c | 112 ++++++++++++++++ matrix.p | 348 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 460 insertions(+) create mode 100644 matrix-test.c create mode 100644 matrix.p diff --git a/matrix-test.c b/matrix-test.c new file mode 100644 index 00000000..7b7f240e --- /dev/null +++ b/matrix-test.c @@ -0,0 +1,112 @@ +/** \file + * Test the matrix LCD PRU firmware. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "ledscape.h" + +static void +ledscape_fill_color( + ledscape_frame_t * const frame, + const unsigned num_pixels, + const uint8_t r, + const uint8_t g, + const uint8_t b +) +{ + for (unsigned i = 0 ; i < num_pixels ; i++) + for (unsigned strip = 0 ; strip < LEDSCAPE_NUM_STRIPS ; strip++) + ledscape_set_color(frame, strip, i, r, g, b); +} + + +int main (void) +{ + const int num_pixels = 512; + ledscape_t * const leds = ledscape_init(num_pixels); + printf("init done\n"); + time_t last_time = time(NULL); + unsigned last_i = 0; + + unsigned i = 0; + while (1) + { + // Alternate frame buffers on each draw command + const unsigned frame_num = i++ % 2; + ledscape_frame_t * const frame + = ledscape_frame(leds, frame_num); + + uint32_t * const p = (void*) frame; + memset(p, 0, 4 * 32 * 512); + + ledscape_draw(leds, frame_num); +#if 1 + for (unsigned x = 0 ; x < 512 ; x++) + { + for (unsigned y = 0 ; y < 16 ; y++) + { + uint8_t * const px = (void*) &p[x + 512 * y]; + const unsigned v = (i >> 10) % 16; + px[0] = x <= 14 ? v : 0; + px[1] = 11 < x && x <= 26 ? v : 0; + px[2] = 17 < x && x <= 32 ? v : 0; + + if (x > 32) + p[0] = 4; + } + } +#else + uint8_t val = i >> 1; + uint16_t r = ((i >> 0) & 0xFF); + uint16_t g = ((i >> 8) & 0xFF); + uint16_t b = ((i >> 16) & 0xFF); + ledscape_fill_color(frame, num_pixels, val, val, val); + + for (unsigned strip = 0 ; strip < 32 ; strip++) + { + for (unsigned p = 0 ; p < num_pixels ; p++) + { + ledscape_set_color( + frame, + strip, + p, +#if 1 + ((strip % 3) == 0) ? (i) : 0, + ((strip % 3) == 1) ? (i) : 0, + ((strip % 3) == 2) ? (i) : 0 +#else + ((strip % 3) == 0) ? 100 : 0, + ((strip % 3) == 1) ? 100 : 0, + ((strip % 3) == 2) ? 100 : 0 +#endif + ); + //ledscape_set_color(frame, strip, 3*p+1, 0, p+val + 80, 0); + //ledscape_set_color(frame, strip, 3*p+2, 0, 0, p+val + 160); + } + } +#endif + + // wait for the previous frame to finish; + //const uint32_t response = ledscape_wait(leds); + const uint32_t response = 0; + time_t now = time(NULL); + if (now != last_time) + { + printf("%d fps. starting %d previous %"PRIx32"\n", + i - last_i, i, response); + last_i = i; + last_time = now; + } + + } + + ledscape_close(leds); + + return EXIT_SUCCESS; +} diff --git a/matrix.p b/matrix.p new file mode 100644 index 00000000..ec43e64b --- /dev/null +++ b/matrix.p @@ -0,0 +1,348 @@ +// \file + /* PRU based 16x32 LED Matrix driver. + * + * Drives up to sixteen 16x32 matrices using the PRU hardware. + * + * Uses sixteen data pins in GPIO0 (one for each data line on each + * matrix) and six control pins in GPIO1 shared between all the matrices. + * + * The ARM writes a 24-bit color 512x16 into the shared RAM, sets the + * frame buffer pointer in the command structure and the PRU clocks it out + * to the sixteen matrices. Since there is no PWM in the matrix hardware, + * the PRU will cycle through various brightness levels. After each PWM + * cycle it rechecks the frame buffer pointer, allowing a glitch-free + * transition to a new frame. + * + * To pause the redraw loop, write a NULL to the buffer pointer. + * To shut down the PRU, write -1 to the buffer pointer. + * + * HOW WE THINK THIS WORKS IS WRONG: it is not serial on all three rows, + * but instead each R, G and B has its own input, and the two rows that + * are simultaneously being scanned have their own. So there are only 32 + * clocks for the input. + * + * This means that we need 6 IOs/panel for data, which is far more than + * we thought. + * 16 GPIO0 IOs == 2 with 4 IO left over. + */ +// Pins available in GPIO0 +#define gpio0_row1_r 2 +#define gpio0_row1_g 3 +#define gpio0_row1_b 7 +#define gpio0_row2_r 5 +#define gpio0_row2_b 4 +#define gpio0_row2_g 12 +#define gpio0_row3_r 13 +#define gpio0_row3_g 14 +#define gpio0_row3_b 15 +#define gpio0_row4_r 20 +#define gpio0_row4_g 22 +#define gpio0_row4_b 23 +#define gpio0_bit12 26 +#define gpio0_bit13 27 +#define gpio0_bit14 30 +#define gpio0_bit15 31 + +// could move clock and sel into gpio0 + +// Pins available in GPIO1 +#define gpio1_sel0 12 +#define gpio1_sel1 13 +#define gpio1_sel2 14 +#define gpio1_latch 28 +#define gpio1_oe 29 +#define gpio1_clock 19 + +/** Generate a bitmask of which pins in GPIO0-3 are used. + * + * \todo wtf "parameter too long": only 128 chars allowed? + */ +#define GPIO0_LED_MASK (0\ +|(1< Date: Sat, 1 Jan 2000 15:04:56 +0000 Subject: [PATCH 090/332] started on LED matrix code; this breaks the ws2821x code for now --- Makefile | 3 ++- ledscape.c | 10 ++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index a546a370..89e09b07 100755 --- a/Makefile +++ b/Makefile @@ -4,12 +4,13 @@ # TARGETS += teensy-udp-rx TARGETS += rgb-test +TARGETS += matrix-test TARGETS += udp-rx LEDSCAPE_OBJS = ledscape.o pru.o bitslice.o util.o LEDSCAPE_LIB := libledscape.a -all: $(TARGETS) ws281x.bin +all: $(TARGETS) ws281x.bin matrix.bin ifeq ($(shell uname -m),armv7l) diff --git a/ledscape.c b/ledscape.c index e57cb396..386c23db 100644 --- a/ledscape.c +++ b/ledscape.c @@ -97,13 +97,14 @@ ledscape_draw( ) { leds->ws281x->pixels_dma = leds->pru->ddr_addr + leds->frame_size * frame; - +#if 0 // Wait for any current command to have been acknowledged while (leds->ws281x->command) ; // Send the start command leds->ws281x->command = 1; +#endif } @@ -167,12 +168,17 @@ ledscape_init( pru_gpio(3, gpios3[i], 1, 0); // Initiate the PRU program - pru_exec(pru, "./ws281x.bin"); + if (1) + pru_exec(pru, "./matrix.bin"); + else + pru_exec(pru, "./ws281x.bin"); // Watch for a done response that indicates a proper startup // \todo timeout if it fails + printf("waiting for response\n"); while (!leds->ws281x->response) ; + printf("got response\n"); return leds; } From 770eee29246f142015b5895daedb80a870a890d0 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 1 Jan 2000 15:13:51 +0000 Subject: [PATCH 091/332] Entire width works, with two chained --- matrix-test.c | 14 ++++---- matrix.p | 90 +++++++++++++++++++++------------------------------ 2 files changed, 44 insertions(+), 60 deletions(-) diff --git a/matrix-test.c b/matrix-test.c index 7b7f240e..0b67f687 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -43,7 +43,6 @@ int main (void) = ledscape_frame(leds, frame_num); uint32_t * const p = (void*) frame; - memset(p, 0, 4 * 32 * 512); ledscape_draw(leds, frame_num); #if 1 @@ -52,13 +51,14 @@ int main (void) for (unsigned y = 0 ; y < 16 ; y++) { uint8_t * const px = (void*) &p[x + 512 * y]; - const unsigned v = (i >> 10) % 16; - px[0] = x <= 14 ? v : 0; - px[1] = 11 < x && x <= 26 ? v : 0; - px[2] = 17 < x && x <= 32 ? v : 0; + uint8_t j = x % 30; + const unsigned v = (i >> 10); + px[0] = j <= 14 ? v : 0; + px[1] = 11 < j && j <= 26 ? v : 0; + px[2] = 17 < j && j <= 40 ? v : 0; - if (x > 32) - p[0] = 4; + if (j > 32) + p[0] = 0x40; } } #else diff --git a/matrix.p b/matrix.p index ec43e64b..e8806f0a 100644 --- a/matrix.p +++ b/matrix.p @@ -175,10 +175,9 @@ START: // handles the exit case if an invalid value is written to the start // start position. -#define DISPLAY_WIDTH 32 -#define DISPLAYS 16 /* Maximum! */ +#define DISPLAY_WIDTH 64 +#define DISPLAYS 8 /* Maximum! */ #define ROW_WIDTH (DISPLAYS * DISPLAY_WIDTH) -#define MAX_BRIGHT 16 /* for bright in 0..MAX_BRIGHT: @@ -266,58 +265,43 @@ PWM_LOOP: SET out1_set, gpio1_sel2 sel2: - // write bits to output + // write select bits to output SBBO out1_set, gpio1_set, 0, 4 XOR out1_set, out1_set, gpio1_sel_mask SBBO out1_set, gpio1_clr, 0, 4 - - MOV scan, 0 - SCAN_LOOP: - ADD pix_ptr, data_addr, offset - ADD pix_ptr, pix_ptr, pixel - - MOV pixel, 0 - PIXEL_LOOP: - MOV out0_set, 0 - - // This should be unrolled for every display - // read a pixel worth of data - LBBO pix, pix_ptr, 0*DISPLAY_WIDTH, 4 - QBGE disp0_r, pix.b0, bright - SET out0_set, gpio0_row1_r - - disp0_r: - QBGE disp0_g, pix.b1, bright - SET out0_set, gpio0_row1_g - - disp0_g: - QBGE disp0_b, pix.b2, bright - SET out0_set, gpio0_row1_b - disp0_b: - - // All bits are configured; - // the non-set ones will be cleared - SBBO out0_set, gpio0_set, 0, 4 - XOR out0_set, out0_set, gpio0_led_mask - SBBO out0_set, gpio0_clr, 0, 4 - CLOCK(PIX) - - ADD pix_ptr, pix_ptr, 4 - ADD pixel, pixel, 1 - QBNE PIXEL_LOOP, pixel, DISPLAY_WIDTH - -#if 0 -// WRONG WRONG WRONG -- the second half is scanned simultaneousl - // The panel scans rows 0 and 8 in the - // same pass. Adjust the pixel pointer - // to the 8th row; pix_ptr is now pointing to - // the end of the row that was scanned - MOV p2, (8-1) * ROW_WIDTH - ADD pix_ptr, pix_ptr, p2 - ADD scan, scan, 1 - QBNE SCAN_LOOP, scan, 2 -#endif + // compute where we are in the image + + MOV pixel, 0 + ADD pix_ptr, data_addr, offset + PIXEL_LOOP: + MOV out0_set, 0 + + // This should be unrolled for every display + // read a pixel worth of data + LBBO pix, pix_ptr, 0*DISPLAY_WIDTH, 4 + QBGE disp0_r, pix.b0, bright + SET out0_set, gpio0_row1_r + + disp0_r: + QBGE disp0_g, pix.b1, bright + SET out0_set, gpio0_row1_g + + disp0_g: + QBGE disp0_b, pix.b2, bright + SET out0_set, gpio0_row1_b + disp0_b: + + // All bits are configured; + // the non-set ones will be cleared + SBBO out0_set, gpio0_set, 0, 4 + XOR out0_set, out0_set, gpio0_led_mask + SBBO out0_set, gpio0_clr, 0, 4 + CLOCK(PIX) + + ADD pix_ptr, pix_ptr, 4 + ADD pixel, pixel, 1 + QBNE PIXEL_LOOP, pixel, DISPLAY_WIDTH // We have clocked out all of the pixels for // this row and the one eigth rows later. @@ -332,8 +316,8 @@ PWM_LOOP: // We have clocked out all of the panels. // Celebrate and go back to the PWM loop // Limit brightness to 0..MAX_BRIGHT - ADD bright, bright, 1 - AND bright, bright, (MAX_BRIGHT-1) + ADD bright, bright, 16 + AND bright, bright, 0xFF QBA PWM_LOOP From 8be82c02b6546ea6a09ca9334f68350404384004 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 1 Jan 2000 15:56:02 +0000 Subject: [PATCH 092/332] Scrolling and driving four in daisy chain seems ok --- matrix.p | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/matrix.p b/matrix.p index e8806f0a..578b8859 100644 --- a/matrix.p +++ b/matrix.p @@ -175,8 +175,8 @@ START: // handles the exit case if an invalid value is written to the start // start position. -#define DISPLAY_WIDTH 64 -#define DISPLAYS 8 /* Maximum! */ +#define DISPLAY_WIDTH 128 +#define DISPLAYS 4 #define ROW_WIDTH (DISPLAYS * DISPLAY_WIDTH) /* @@ -301,7 +301,8 @@ PWM_LOOP: ADD pix_ptr, pix_ptr, 4 ADD pixel, pixel, 1 - QBNE PIXEL_LOOP, pixel, DISPLAY_WIDTH + MOV p2, DISPLAY_WIDTH + QBNE PIXEL_LOOP, pixel, p2 // We have clocked out all of the pixels for // this row and the one eigth rows later. From 4f3c091180186b4feb92949563aeb1a07735a288 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 1 Jan 2000 15:56:10 +0000 Subject: [PATCH 093/332] Scrolling and driving four in daisy chain seems ok --- matrix-test.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/matrix-test.c b/matrix-test.c index 0b67f687..4258f8e7 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -51,16 +51,14 @@ int main (void) for (unsigned y = 0 ; y < 16 ; y++) { uint8_t * const px = (void*) &p[x + 512 * y]; - uint8_t j = x % 30; - const unsigned v = (i >> 10); + uint8_t j = (x + (i >> 8)) % 30; + const unsigned v = (i >> 4) % 0x80; px[0] = j <= 14 ? v : 0; px[1] = 11 < j && j <= 26 ? v : 0; px[2] = 17 < j && j <= 40 ? v : 0; - - if (j > 32) - p[0] = 0x40; } } + usleep(1000); #else uint8_t val = i >> 1; uint16_t r = ((i >> 0) & 0xFF); From 1cf9b742915b02229cc72f7480804de435209165 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 1 Jan 2000 01:46:50 +0000 Subject: [PATCH 094/332] works with cape design thus far --- matrix.p | 75 +++++++++++++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/matrix.p b/matrix.p index 578b8859..9b912499 100644 --- a/matrix.p +++ b/matrix.p @@ -26,50 +26,47 @@ * 16 GPIO0 IOs == 2 with 4 IO left over. */ // Pins available in GPIO0 -#define gpio0_row1_r 2 -#define gpio0_row1_g 3 -#define gpio0_row1_b 7 -#define gpio0_row2_r 5 -#define gpio0_row2_b 4 -#define gpio0_row2_g 12 -#define gpio0_row3_r 13 -#define gpio0_row3_g 14 -#define gpio0_row3_b 15 -#define gpio0_row4_r 20 -#define gpio0_row4_g 22 -#define gpio0_row4_b 23 -#define gpio0_bit12 26 -#define gpio0_bit13 27 -#define gpio0_bit14 30 -#define gpio0_bit15 31 - -// could move clock and sel into gpio0 +#define gpio0_r1 3 +#define gpio0_g1 30 +#define gpio0_b1 15 + +#define gpio0_r2 2 +#define gpio0_b2 14 +#define gpio0_g2 31 + +#define gpio0_r3 20 +#define gpio0_b3 7 +#define gpio0_g3 22 + +#define gpio0_r4 23 +#define gpio0_b4 27 +#define gpio0_g4 26 // Pins available in GPIO1 -#define gpio1_sel0 12 -#define gpio1_sel1 13 -#define gpio1_sel2 14 -#define gpio1_latch 28 -#define gpio1_oe 29 -#define gpio1_clock 19 +#define gpio1_sel0 12 /* 44 */ +#define gpio1_sel1 13 /* 45 */ +#define gpio1_sel2 14 /* 46 */ +#define gpio1_latch 28 /* 60 */ +#define gpio1_oe 15 /* 47 */ +#define gpio1_clock 19 /* 51 */ /** Generate a bitmask of which pins in GPIO0-3 are used. * * \todo wtf "parameter too long": only 128 chars allowed? */ #define GPIO0_LED_MASK (0\ -|(1< Date: Sat, 1 Jan 2000 03:28:49 +0000 Subject: [PATCH 095/332] Off by one error in row assignment fixed; brightness is not so great --- matrix-test.c | 14 ++--- matrix.p | 154 ++++++++++++++++++++++---------------------------- 2 files changed, 76 insertions(+), 92 deletions(-) diff --git a/matrix-test.c b/matrix-test.c index 4258f8e7..ea73c05f 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -28,7 +28,7 @@ ledscape_fill_color( int main (void) { - const int num_pixels = 512; + const int num_pixels = 256; ledscape_t * const leds = ledscape_init(num_pixels); printf("init done\n"); time_t last_time = time(NULL); @@ -44,21 +44,21 @@ int main (void) uint32_t * const p = (void*) frame; - ledscape_draw(leds, frame_num); #if 1 - for (unsigned x = 0 ; x < 512 ; x++) + for (unsigned x = 0 ; x < num_pixels ; x++) { for (unsigned y = 0 ; y < 16 ; y++) { - uint8_t * const px = (void*) &p[x + 512 * y]; - uint8_t j = (x + (i >> 8)) % 30; - const unsigned v = (i >> 4) % 0x80; + uint8_t * const px = (void*) &p[x + num_pixels * y]; + uint8_t j = (x + y + (i >> 8)) % 30; + const unsigned v = y * 16; px[0] = j <= 14 ? v : 0; px[1] = 11 < j && j <= 26 ? v : 0; px[2] = 17 < j && j <= 40 ? v : 0; } } - usleep(1000); + ledscape_draw(leds, frame_num); + usleep(100); #else uint8_t val = i >> 1; uint16_t r = ((i >> 0) & 0xFF); diff --git a/matrix.p b/matrix.p index 9b912499..bf1cd9c0 100644 --- a/matrix.p +++ b/matrix.p @@ -34,12 +34,12 @@ #define gpio0_b2 14 #define gpio0_g2 31 -#define gpio0_r3 20 -#define gpio0_b3 7 +#define gpio0_r3 7 +#define gpio0_b3 20 #define gpio0_g3 22 -#define gpio0_r4 23 -#define gpio0_b4 27 +#define gpio0_r4 27 +#define gpio0_b4 23 #define gpio0_g4 26 // Pins available in GPIO1 @@ -127,18 +127,28 @@ lab: .endm -#define CLOCK(pin) \ - SLEEPNS 50, 1, pin##_on ; \ +#define CLOCK_LO \ SBBO clock_pin, gpio1_set, 0, 4; \ - SLEEPNS 50, 1, pin##_off ; \ + +#define CLOCK_HI \ SBBO clock_pin, gpio1_clr, 0, 4; \ -#define LATCH \ - SLEEPNS 50, 1, latch_on ; \ +#define LATCH_HI \ SBBO latch_pin, gpio1_set, 0, 4; \ - SLEEPNS 50, 1, latch_off ; \ + +#define LATCH_LO \ SBBO latch_pin, gpio1_clr, 0, 4; \ +#define DISPLAY_OFF \ + MOV out1_set, 0; \ + SET out1_set, gpio1_oe; \ + SBBO out1_set, gpio1_set, 0, 4; \ + +#define DISPLAY_ON \ + MOV out1_set, 0; \ + SET out1_set, gpio1_oe; \ + SBBO out1_set, gpio1_clr, 0, 4; \ + START: // Enable OCP master port @@ -173,49 +183,9 @@ START: // start position. #define DISPLAY_WIDTH 128 -#define DISPLAYS 4 +#define DISPLAYS 2 #define ROW_WIDTH (DISPLAYS * DISPLAY_WIDTH) -/* -for bright in 0..MAX_BRIGHT: - for row in 0..7: - set_address row - offset = row * ROW_WIDTH - for pixel in 0..32: - for scan in 0..1: - r_clr = r_set = 0 - g_clr = g_set = 0 - b_clr = b_set = 0 - for display in 0..DISPLAYS: - read rgb from 4*(pixel + display*DISPLAY_WIDTH + offset) - pin = display_pin(display) - if r < bright: - r_clr |= pin - if b < bright: - b_clr |= pin - if g < bright: - g_clr |= pin - - # All bitmasks have been built, clock them out - clr_bits r_clr - set_bits r_set - clock - clr_bits g_clr - set_bits g_set - clock - clr_bits b_clr - set_bits b_set - clock - - # read the paired row for the next pass - # on the second scan - offset += 8 * DISPLAY_WIDTH - - # latch after both scan rows have been output - latch - # Check for new frame buffer now; this is a safe time to change it -*/ - MOV bright, #0 MOV gpio0_set, GPIO0 | GPIO_SETDATAOUT @@ -250,61 +220,75 @@ PWM_LOOP: MOV row, 0 ROW_LOOP: - // set address; pins in gpio1 - MOV out1_set, 0 - QBBC sel0, row, 0 - SET out1_set, gpio1_sel0 - sel0: - QBBC sel1, row, 1 - SET out1_set, gpio1_sel1 - sel1: - QBBC sel2, row, 2 - SET out1_set, gpio1_sel2 - sel2: - - // write select bits to output - SBBO out1_set, gpio1_set, 0, 4 - XOR out1_set, out1_set, gpio1_sel_mask - SBBO out1_set, gpio1_clr, 0, 4 - // compute where we are in the image MOV pixel, 0 ADD pix_ptr, data_addr, offset + PIXEL_LOOP: MOV out0_set, 0 + CLOCK_HI - // This should be unrolled for every display // read a pixel worth of data - LBBO pix, pix_ptr, 0*DISPLAY_WIDTH, 4 - QBGE disp0_r, pix.b0, bright - SET out0_set, gpio0_r1 - - disp0_r: - QBGE disp0_g, pix.b1, bright - SET out0_set, gpio0_g1 - - disp0_g: - QBGE disp0_b, pix.b2, bright - SET out0_set, gpio0_b1 - disp0_b: +#define OUTPUT_ROW(N, OFFSET) \ + MOV p2, (OFFSET); \ + LBBO pix, pix_ptr, p2, 4; \ + QBGE skip_r##N, pix.b0, bright; \ + SET out0_set, gpio0_r##N; \ + skip_r##N:; \ + QBGE skip_g##N, pix.b1, bright; \ + SET out0_set, gpio0_g##N; \ + skip_g##N:; \ + QBGE skip_b##N, pix.b2, bright; \ + SET out0_set, gpio0_b##N; \ + skip_b##N:; \ + + OUTPUT_ROW(1, 0) + OUTPUT_ROW(2, 8*ROW_WIDTH*4) + OUTPUT_ROW(3, DISPLAY_WIDTH*4) + OUTPUT_ROW(4, 8*ROW_WIDTH*4 + DISPLAY_WIDTH*4) // All bits are configured; // the non-set ones will be cleared SBBO out0_set, gpio0_set, 0, 4 XOR out0_set, out0_set, gpio0_led_mask SBBO out0_set, gpio0_clr, 0, 4 - CLOCK(PIX) + + // give it a few ns to settle + //SLEEPNS 50, 1, data_setup + CLOCK_LO ADD pix_ptr, pix_ptr, 4 ADD pixel, pixel, 1 MOV p2, DISPLAY_WIDTH QBNE PIXEL_LOOP, pixel, p2 + // Disable output before we latch and set the address + DISPLAY_OFF + LATCH_HI + + // set address; pins in gpio1 + MOV out1_set, 0 + QBBC sel0, row, 0 + SET out1_set, gpio1_sel0 + sel0: + QBBC sel1, row, 1 + SET out1_set, gpio1_sel1 + sel1: + QBBC sel2, row, 2 + SET out1_set, gpio1_sel2 + sel2: + + // write select bits to output + SBBO out1_set, gpio1_set, 0, 4 + XOR out1_set, out1_set, gpio1_sel_mask + SBBO out1_set, gpio1_clr, 0, 4 + // We have clocked out all of the pixels for // this row and the one eigth rows later. - // Latch the data - LATCH + // Latch the display register and then turn the display on + LATCH_LO + DISPLAY_ON ADD row, row, 1 MOV p2, ROW_WIDTH * 4 @@ -314,7 +298,7 @@ PWM_LOOP: // We have clocked out all of the panels. // Celebrate and go back to the PWM loop // Limit brightness to 0..MAX_BRIGHT - ADD bright, bright, 16 + ADD bright, bright, 32 AND bright, bright, 0xFF QBA PWM_LOOP From 73f5cd3e44585e6847ca00b558f1b572a3d1f956 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 7 Sep 2013 21:34:05 +0000 Subject: [PATCH 096/332] remove sleep before clock --- matrix.p | 2 -- 1 file changed, 2 deletions(-) diff --git a/matrix.p b/matrix.p index bf1cd9c0..2eac06c7 100644 --- a/matrix.p +++ b/matrix.p @@ -254,8 +254,6 @@ PWM_LOOP: XOR out0_set, out0_set, gpio0_led_mask SBBO out0_set, gpio0_clr, 0, 4 - // give it a few ns to settle - //SLEEPNS 50, 1, data_setup CLOCK_LO ADD pix_ptr, pix_ptr, 4 From d581eef4e7e42b629fa829be9b233bfd14e837d5 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 7 Sep 2013 21:59:41 +0000 Subject: [PATCH 097/332] Better PWM; turn off the display during dim periods --- matrix.p | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/matrix.p b/matrix.p index 2eac06c7..f0111394 100644 --- a/matrix.p +++ b/matrix.p @@ -256,6 +256,17 @@ PWM_LOOP: CLOCK_LO + // If the brightness is less than the pixel, turn off +#if 1 + LSL p2, pixel, 2 + ADD p2, p2, pixel + ADD p2, p2, pixel + ADD p2, p2, pixel + QBLT no_blank, bright, p2 + DISPLAY_OFF + no_blank: +#endif + ADD pix_ptr, pix_ptr, 4 ADD pixel, pixel, 1 MOV p2, DISPLAY_WIDTH From e315c5ad94fcf67befefbfb55f182ddd4dc6032b Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 7 Sep 2013 22:35:04 +0000 Subject: [PATCH 098/332] More tests; looking pretty good with the pwm --- Makefile | 1 + bitmap-test.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ matrix-test.c | 2 +- 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 bitmap-test.c diff --git a/Makefile b/Makefile index 89e09b07..3d30c19d 100755 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ TARGETS += teensy-udp-rx TARGETS += rgb-test TARGETS += matrix-test +TARGETS += bitmap-test TARGETS += udp-rx LEDSCAPE_OBJS = ledscape.o pru.o bitslice.o util.o diff --git a/bitmap-test.c b/bitmap-test.c new file mode 100644 index 00000000..9345c5c9 --- /dev/null +++ b/bitmap-test.c @@ -0,0 +1,76 @@ +/** \file + * Test the matrix LCD PRU firmware by displaying an image. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "ledscape.h" + +int +main( + int argc, + char ** argv +) +{ + const int num_pixels = 256; + ledscape_t * const leds = ledscape_init(num_pixels); + + FILE * f = fopen(argv[1], "r"); + uint8_t * buf = calloc(1<<20, 1); + size_t len = fread(buf, 1, 1<<20, f); + printf("len=%zu\n", len); + + buf += 0x82; // skip the BMP header (hardcoded) + + time_t last_time = time(NULL); + unsigned last_i = 0; + + unsigned i = 0; + while (1) + { + // Alternate frame buffers on each draw command + const unsigned frame_num = i++ % 2; + ledscape_frame_t * const frame + = ledscape_frame(leds, frame_num); + + uint32_t * const p = (void*) frame; + + for (unsigned x = 0 ; x < num_pixels ; x++) + { + for (unsigned y = 0 ; y < 16 ; y++) + { + uint8_t j = (i >> 8); + uint8_t * const inpx = (void*) &buf[4 * ((x + j) % num_pixels) + num_pixels * (16 - y) * 4]; + uint8_t * const px = (void*) &p[x + num_pixels * y]; + + px[0] = inpx[0]; + px[1] = inpx[1]; + px[2] = inpx[2]; + } + } + ledscape_draw(leds, frame_num); + usleep(100); + + // wait for the previous frame to finish; + //const uint32_t response = ledscape_wait(leds); + const uint32_t response = 0; + time_t now = time(NULL); + if (now != last_time) + { + printf("%d fps. starting %d previous %"PRIx32"\n", + i - last_i, i, response); + last_i = i; + last_time = now; + } + + } + + ledscape_close(leds); + + return EXIT_SUCCESS; +} diff --git a/matrix-test.c b/matrix-test.c index ea73c05f..04e58f94 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -50,7 +50,7 @@ int main (void) for (unsigned y = 0 ; y < 16 ; y++) { uint8_t * const px = (void*) &p[x + num_pixels * y]; - uint8_t j = (x + y + (i >> 8)) % 30; + uint8_t j = (x + y + (i >> 8)) % 32; const unsigned v = y * 16; px[0] = j <= 14 ? v : 0; px[1] = 11 < j && j <= 26 ? v : 0; From c3dbdc938688fe81bd2c31fc24967b29f42d7875 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 8 Sep 2013 01:22:07 +0000 Subject: [PATCH 099/332] remove old debugging code --- matrix.p | 3 --- 1 file changed, 3 deletions(-) diff --git a/matrix.p b/matrix.p index f0111394..77ac87fb 100644 --- a/matrix.p +++ b/matrix.p @@ -202,9 +202,6 @@ START: SET latch_pin, gpio1_latch PWM_LOOP: - //CLOCK - //QBA PWM_LOOP - // Load the pointer to the buffer from PRU DRAM into r0 and the // length (in bytes-bit words) into r1. // start command into r2 From 797b1ce01ed6ed977b7b20479e06096583d7040d Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 7 Sep 2013 23:31:48 -0400 Subject: [PATCH 100/332] files that will be needed to configuration another bbb --- am335x-boneblack.dtb | Bin 0 -> 24125 bytes ledscape.service | 10 ++++++++++ run-ledscape | 6 ++++++ 3 files changed, 16 insertions(+) create mode 100644 am335x-boneblack.dtb create mode 100755 ledscape.service create mode 100755 run-ledscape diff --git a/am335x-boneblack.dtb b/am335x-boneblack.dtb new file mode 100644 index 0000000000000000000000000000000000000000..1cc81659c74981e6c7a21d3c6c0278edfb7f0ee2 GIT binary patch literal 24125 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 Ee_J?6`~Uy| literal 0 HcmV?d00001 diff --git a/ledscape.service b/ledscape.service new file mode 100755 index 00000000..8a91526f --- /dev/null +++ b/ledscape.service @@ -0,0 +1,10 @@ +[Unit] +Description=BeagleBone LED matrix driver + +[Service] +WorkingDirectory=/home/root/LEDscape/ +ExecStart=/home/root/LEDscape/run-ledscape +KillMode=process + +[Install] +WantedBy=multi-user.target diff --git a/run-ledscape b/run-ledscape new file mode 100755 index 00000000..e311b61c --- /dev/null +++ b/run-ledscape @@ -0,0 +1,6 @@ +#!/bin/sh +DIRNAME="`dirname "$0"`" +cd "$DIRNAME" + +modprobe uio_pruss +exec ./matrix-test From 96360350207463b6fa995df7393846230b4107ab Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 8 Sep 2013 21:07:47 +0000 Subject: [PATCH 101/332] improve matrix test to do fancy hue shifting --- matrix-test.c | 159 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 104 insertions(+), 55 deletions(-) diff --git a/matrix-test.c b/matrix-test.c index 04e58f94..2df5b7e1 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -1,5 +1,5 @@ /** \file - * Test the matrix LCD PRU firmware. + * Test the matrix LCD PRU firmware with a multi-hue rainbow. */ #include #include @@ -11,22 +11,104 @@ #include #include "ledscape.h" + +// Borrowed by OctoWS2811 rainbow test +static unsigned int +h2rgb( + unsigned int v1, + unsigned int v2, + unsigned int hue +) +{ + if (hue < 60) + return v1 * 60 + (v2 - v1) * hue; + if (hue < 180) + return v2 * 60; + if (hue < 240) + return v1 * 60 + (v2 - v1) * (240 - hue); + + return v1 * 60; +} + + +// Convert HSL (Hue, Saturation, Lightness) to RGB (Red, Green, Blue) +// +// hue: 0 to 359 - position on the color wheel, 0=red, 60=orange, +// 120=yellow, 180=green, 240=blue, 300=violet +// +// saturation: 0 to 100 - how bright or dull the color, 100=full, 0=gray +// +// lightness: 0 to 100 - how light the color is, 100=white, 50=color, 0=black +// +static uint32_t +makeColor( + unsigned int hue, + unsigned int saturation, + unsigned int lightness +) +{ + unsigned int red, green, blue; + unsigned int var1, var2; + + if (hue > 359) + hue = hue % 360; + if (saturation > 100) + saturation = 100; + if (lightness > 100) + lightness = 100; + + // algorithm from: http://www.easyrgb.com/index.php?X=MATH&H=19#text19 + if (saturation == 0) { + red = green = blue = lightness * 255 / 100; + } else { + if (lightness < 50) { + var2 = lightness * (100 + saturation); + } else { + var2 = ((lightness + saturation) * 100) - (saturation * lightness); + } + var1 = lightness * 200 - var2; + red = h2rgb(var1, var2, (hue < 240) ? hue + 120 : hue - 240) * 255 / 600000; + green = h2rgb(var1, var2, hue) * 255 / 600000; + blue = h2rgb(var1, var2, (hue >= 120) ? hue - 120 : hue + 240) * 255 / 600000; + } + return (red << 16) | (green << 8) | blue; +} + + + +static uint32_t rainbowColors[180]; + + +// phaseShift is the shift between each row. phaseShift=0 +// causes all rows to show the same colors moving together. +// phaseShift=180 causes each row to be the opposite colors +// as the previous. +// +// cycleTime is the number of milliseconds to shift through +// the entire 360 degrees of the color wheel: +// Red -> Orange -> Yellow -> Green -> Blue -> Violet -> Red +// static void -ledscape_fill_color( - ledscape_frame_t * const frame, - const unsigned num_pixels, - const uint8_t r, - const uint8_t g, - const uint8_t b +rainbow( + uint32_t * const pixels, + unsigned num_leds, + unsigned phaseShift, + unsigned cycle ) { - for (unsigned i = 0 ; i < num_pixels ; i++) - for (unsigned strip = 0 ; strip < LEDSCAPE_NUM_STRIPS ; strip++) - ledscape_set_color(frame, strip, i, r, g, b); + const unsigned color = cycle % 180; + + for (unsigned x=0; x < num_leds; x++) { + for (unsigned y=0; y < 16; y++) { + const int index = (color + x + y*phaseShift/2) % 180; + pixels[x + y*num_leds] = rainbowColors[index]; + } + } } -int main (void) +int +main(void) { const int num_pixels = 256; ledscape_t * const leds = ledscape_init(num_pixels); @@ -34,6 +116,15 @@ int main (void) time_t last_time = time(NULL); unsigned last_i = 0; + // pre-compute the 180 rainbow colors + for (int i=0; i<180; i++) + { + int hue = i * 2; + int saturation = 100; + int lightness = 50; + rainbowColors[i] = makeColor(hue, saturation, lightness); + } + unsigned i = 0; while (1) { @@ -44,51 +135,9 @@ int main (void) uint32_t * const p = (void*) frame; -#if 1 - for (unsigned x = 0 ; x < num_pixels ; x++) - { - for (unsigned y = 0 ; y < 16 ; y++) - { - uint8_t * const px = (void*) &p[x + num_pixels * y]; - uint8_t j = (x + y + (i >> 8)) % 32; - const unsigned v = y * 16; - px[0] = j <= 14 ? v : 0; - px[1] = 11 < j && j <= 26 ? v : 0; - px[2] = 17 < j && j <= 40 ? v : 0; - } - } + rainbow(p, num_pixels, 10, i); ledscape_draw(leds, frame_num); - usleep(100); -#else - uint8_t val = i >> 1; - uint16_t r = ((i >> 0) & 0xFF); - uint16_t g = ((i >> 8) & 0xFF); - uint16_t b = ((i >> 16) & 0xFF); - ledscape_fill_color(frame, num_pixels, val, val, val); - - for (unsigned strip = 0 ; strip < 32 ; strip++) - { - for (unsigned p = 0 ; p < num_pixels ; p++) - { - ledscape_set_color( - frame, - strip, - p, -#if 1 - ((strip % 3) == 0) ? (i) : 0, - ((strip % 3) == 1) ? (i) : 0, - ((strip % 3) == 2) ? (i) : 0 -#else - ((strip % 3) == 0) ? 100 : 0, - ((strip % 3) == 1) ? 100 : 0, - ((strip % 3) == 2) ? 100 : 0 -#endif - ); - //ledscape_set_color(frame, strip, 3*p+1, 0, p+val + 80, 0); - //ledscape_set_color(frame, strip, 3*p+2, 0, 0, p+val + 160); - } - } -#endif + usleep(10000); // wait for the previous frame to finish; //const uint32_t response = ledscape_wait(leds); From 43dccccaec0b7ecd8087de1d9745fae654a01cc5 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 8 Sep 2013 23:03:06 +0000 Subject: [PATCH 102/332] Receieve frames from the pyramid transmitter to display on the matrix --- Makefile | 3 +- matrix-udp-rx.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 matrix-udp-rx.c diff --git a/Makefile b/Makefile index 3d30c19d..1d88f406 100755 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ TARGETS += teensy-udp-rx TARGETS += rgb-test TARGETS += matrix-test +TARGETS += matrix-udp-rx TARGETS += bitmap-test TARGETS += udp-rx @@ -72,7 +73,7 @@ PASM_DIR ?= ./am335x/pasm PASM := $(PASM_DIR)/pasm %.bin: %.p $(PASM) - $(CPP) - < $< | perl -p -e 's/^#.*//; s/;/\n/g' > $<.i + $(CPP) - < $< | perl -p -e 's/^#.*//; s/;/\n/g; s/BYTE\((\d+)\)/t\1/g' > $<.i $(PASM) -V3 -b $<.i $(basename $@) $(RM) $<.i diff --git a/matrix-udp-rx.c b/matrix-udp-rx.c new file mode 100644 index 00000000..97e3afaf --- /dev/null +++ b/matrix-udp-rx.c @@ -0,0 +1,161 @@ +/** \file + * UDP image packet receiver. + * + * Based on the HackRockCity LED Display code: + * https://github.com/agwn/pyramidTransmitter/blob/master/LEDDisplay.pde + * + * Designed to render into the LED matrix. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "bitslice.h" +#include "ledscape.h" + +static int port = 9999; +static unsigned width = 64; +static unsigned height = 210; + +static int +udp_socket( + const int port +) +{ + const int sock = socket(AF_INET, SOCK_DGRAM, 0); + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_port = htons(port), + .sin_addr.s_addr = INADDR_ANY, + }; + + if (sock < 0) + return -1; + if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr)) < 0) + return -1; + + return sock; +} + + +int +main( + int argc, + char ** argv +) +{ + const int port = 9999; + const int sock = udp_socket(port); + if (sock < 0) + die("socket port %d failed: %s\n", port, strerror(errno)); + + const unsigned width = 256; + const unsigned height = 16; + const size_t image_size = width * height * 3; + + // largest possible UDP packet + uint8_t buf[65536]; + if (sizeof(buf) < image_size + 1) + die("%u x %u too large for UDP\n", width, height); + + fprintf(stderr, "%u x %u, UDP port %u\n", width, height, port); + + ledscape_t * const leds = ledscape_init(width); + + const unsigned report_interval = 10; + unsigned last_report = 0; + unsigned long delta_sum = 0; + unsigned frames = 0; + + + while (1) + { + const ssize_t rlen = recv(sock, buf, sizeof(buf), 0); + if (rlen < 0) + die("recv failed: %s\n", strerror(errno)); + warn_once("received %zu bytes\n", rlen); + + if (buf[0] == 2) + { + // image type + printf("image type: %.*s\n", + (int) rlen - 1, + &buf[1] + ); + continue; + } + + if (buf[0] != 1) + { + // What is it? + warn_once("Unknown image type '%c' (%02x)\n", + buf[0], + buf[0] + ); + continue; + } + + if ((size_t) rlen != image_size + 1) + { + warn_once("WARNING: Received packet %zu bytes, expected %zu\n", + rlen, + image_size + 1 + ); + } + + struct timeval start_tv, stop_tv, delta_tv; + gettimeofday(&start_tv, NULL); + + const unsigned frame_num = 0; + ledscape_frame_t * const frame + = ledscape_frame(leds, frame_num); + uint32_t * const fb = (void*) frame; + + for (unsigned x = 0 ; x < width ; x++) + { + for (unsigned y = 0 ; y < height ; y++) + { + uint8_t * const out = (void*) &fb[x + y*width]; + const uint8_t * const in = &buf[1 + (x*64 + y+24)*3]; + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + } + } + + ledscape_draw(leds, frame_num); + + gettimeofday(&stop_tv, NULL); + timersub(&stop_tv, &start_tv, &delta_tv); + + frames++; + delta_sum += delta_tv.tv_usec; + if (stop_tv.tv_sec - last_report < report_interval) + continue; + last_report = stop_tv.tv_sec; + + const unsigned delta_avg = delta_sum / frames; + printf("%6u usec avg, max %.2f fps, actual %.2f fps (over %u frames)\n", + delta_avg, + report_interval * 1.0e6 / delta_avg, + frames * 1.0 / report_interval, + frames + ); + + frames = delta_sum = 0; + } + + return 0; +} From f4bb13bb737ca8ee434ae39f154dc57f23436da4 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 8 Sep 2013 23:21:53 +0000 Subject: [PATCH 103/332] Adjust the brightness for the correct value --- matrix.p | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/matrix.p b/matrix.p index 77ac87fb..d094d55b 100644 --- a/matrix.p +++ b/matrix.p @@ -127,6 +127,8 @@ lab: .endm +#define BRIGHT_STEP 32 + #define CLOCK_LO \ SBBO clock_pin, gpio1_set, 0, 4; \ @@ -254,11 +256,17 @@ PWM_LOOP: CLOCK_LO // If the brightness is less than the pixel, turn off + // but keep in mind that this is the brightness of + // the previous row, not this one. #if 1 LSL p2, pixel, 2 ADD p2, p2, pixel ADD p2, p2, pixel ADD p2, p2, pixel + + SUB out0_set, bright, BRIGHT_STEP + AND out0_set, out0_set, 0xFF + QBLT no_blank, bright, p2 DISPLAY_OFF no_blank: @@ -304,7 +312,7 @@ PWM_LOOP: // We have clocked out all of the panels. // Celebrate and go back to the PWM loop // Limit brightness to 0..MAX_BRIGHT - ADD bright, bright, 32 + ADD bright, bright, BRIGHT_STEP AND bright, bright, 0xFF QBA PWM_LOOP From a76fb1dc2c364a6567b9f86e635d6c3404dfd6c5 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 8 Sep 2013 23:22:23 +0000 Subject: [PATCH 104/332] startup script since systemd is awful --- run-ledscape | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100755 run-ledscape diff --git a/run-ledscape b/run-ledscape new file mode 100755 index 00000000..e311b61c --- /dev/null +++ b/run-ledscape @@ -0,0 +1,6 @@ +#!/bin/sh +DIRNAME="`dirname "$0"`" +cd "$DIRNAME" + +modprobe uio_pruss +exec ./matrix-test From 1695b4a41015fd3f5d32261dfade18c3743c7f99 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Mon, 9 Sep 2013 00:12:03 +0000 Subject: [PATCH 105/332] Run bitmap faster, hues slower --- bitmap-test.c | 2 +- matrix-test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bitmap-test.c b/bitmap-test.c index 9345c5c9..cf40ca8d 100644 --- a/bitmap-test.c +++ b/bitmap-test.c @@ -44,7 +44,7 @@ main( { for (unsigned y = 0 ; y < 16 ; y++) { - uint8_t j = (i >> 8); + uint8_t j = (i >> 6); uint8_t * const inpx = (void*) &buf[4 * ((x + j) % num_pixels) + num_pixels * (16 - y) * 4]; uint8_t * const px = (void*) &p[x + num_pixels * y]; diff --git a/matrix-test.c b/matrix-test.c index 2df5b7e1..17b2a491 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -137,7 +137,7 @@ main(void) rainbow(p, num_pixels, 10, i); ledscape_draw(leds, frame_num); - usleep(10000); + usleep(20000); // wait for the previous frame to finish; //const uint32_t response = ledscape_wait(leds); From 98ff46b3c2f30a004ca9816a21fa201486a3af71 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Mon, 9 Sep 2013 00:12:21 +0000 Subject: [PATCH 106/332] more thoughts on pwm improvements --- matrix.p | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/matrix.p b/matrix.p index d094d55b..cca55701 100644 --- a/matrix.p +++ b/matrix.p @@ -258,15 +258,15 @@ PWM_LOOP: // If the brightness is less than the pixel, turn off // but keep in mind that this is the brightness of // the previous row, not this one. + // \todo: Test turning OE on and off every other, + // every fourth, every eigth, etc pixel based on + // the current brightness. #if 1 LSL p2, pixel, 2 ADD p2, p2, pixel ADD p2, p2, pixel ADD p2, p2, pixel - SUB out0_set, bright, BRIGHT_STEP - AND out0_set, out0_set, 0xFF - QBLT no_blank, bright, p2 DISPLAY_OFF no_blank: From 0e90cc0d628ce5f687475d336a47ececc07023b3 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Mon, 9 Sep 2013 12:05:16 +0000 Subject: [PATCH 107/332] Save a few ns per data loop by writing both set/clr bits in the same SBBO --- matrix.p | 51 ++++++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/matrix.p b/matrix.p index cca55701..7f84e521 100644 --- a/matrix.p +++ b/matrix.p @@ -15,15 +15,6 @@ * * To pause the redraw loop, write a NULL to the buffer pointer. * To shut down the PRU, write -1 to the buffer pointer. - * - * HOW WE THINK THIS WORKS IS WRONG: it is not serial on all three rows, - * but instead each R, G and B has its own input, and the two rows that - * are simultaneously being scanned have their own. So there are only 32 - * clocks for the input. - * - * This means that we need 6 IOs/panel for data, which is far more than - * we thought. - * 16 GPIO0 IOs == 2 with 4 IO left over. */ // Pins available in GPIO0 #define gpio0_r1 3 @@ -103,8 +94,8 @@ #define scan r6 #define pix_ptr r7 #define pixel r8 -#define out0_set r9 -#define out1_set r10 +#define out_clr r9 // must be one less than out_set +#define out_set r10 #define p2 r12 #define bright r13 #define gpio0_led_mask r14 @@ -142,14 +133,14 @@ lab: SBBO latch_pin, gpio1_clr, 0, 4; \ #define DISPLAY_OFF \ - MOV out1_set, 0; \ - SET out1_set, gpio1_oe; \ - SBBO out1_set, gpio1_set, 0, 4; \ + MOV out_set, 0; \ + SET out_set, gpio1_oe; \ + SBBO out_set, gpio1_set, 0, 4; \ #define DISPLAY_ON \ - MOV out1_set, 0; \ - SET out1_set, gpio1_oe; \ - SBBO out1_set, gpio1_clr, 0, 4; \ + MOV out_set, 0; \ + SET out_set, gpio1_oe; \ + SBBO out_set, gpio1_clr, 0, 4; \ START: @@ -225,7 +216,7 @@ PWM_LOOP: ADD pix_ptr, data_addr, offset PIXEL_LOOP: - MOV out0_set, 0 + MOV out_set, 0 CLOCK_HI // read a pixel worth of data @@ -233,13 +224,13 @@ PWM_LOOP: MOV p2, (OFFSET); \ LBBO pix, pix_ptr, p2, 4; \ QBGE skip_r##N, pix.b0, bright; \ - SET out0_set, gpio0_r##N; \ + SET out_set, gpio0_r##N; \ skip_r##N:; \ QBGE skip_g##N, pix.b1, bright; \ - SET out0_set, gpio0_g##N; \ + SET out_set, gpio0_g##N; \ skip_g##N:; \ QBGE skip_b##N, pix.b2, bright; \ - SET out0_set, gpio0_b##N; \ + SET out_set, gpio0_b##N; \ skip_b##N:; \ OUTPUT_ROW(1, 0) @@ -249,9 +240,8 @@ PWM_LOOP: // All bits are configured; // the non-set ones will be cleared - SBBO out0_set, gpio0_set, 0, 4 - XOR out0_set, out0_set, gpio0_led_mask - SBBO out0_set, gpio0_clr, 0, 4 + XOR out_clr, out_set, gpio0_led_mask + SBBO out_clr, gpio0_clr, 0, 8 // write both clr and set CLOCK_LO @@ -282,21 +272,20 @@ PWM_LOOP: LATCH_HI // set address; pins in gpio1 - MOV out1_set, 0 + MOV out_set, 0 QBBC sel0, row, 0 - SET out1_set, gpio1_sel0 + SET out_set, gpio1_sel0 sel0: QBBC sel1, row, 1 - SET out1_set, gpio1_sel1 + SET out_set, gpio1_sel1 sel1: QBBC sel2, row, 2 - SET out1_set, gpio1_sel2 + SET out_set, gpio1_sel2 sel2: // write select bits to output - SBBO out1_set, gpio1_set, 0, 4 - XOR out1_set, out1_set, gpio1_sel_mask - SBBO out1_set, gpio1_clr, 0, 4 + XOR out_clr, out_set, gpio1_sel_mask + SBBO out_clr, gpio1_clr, 0, 8 // set both // We have clocked out all of the pixels for // this row and the one eigth rows later. From 0b5a6155254a6e7e99974551d1eaa7710355f363 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Mon, 9 Sep 2013 12:12:25 +0000 Subject: [PATCH 108/332] Save a few registers and cycles by writing row with a shift --- matrix.p | 62 +++++++++++++++++++++++--------------------------------- 1 file changed, 25 insertions(+), 37 deletions(-) diff --git a/matrix.p b/matrix.p index 7f84e521..b2e21c5a 100644 --- a/matrix.p +++ b/matrix.p @@ -34,7 +34,7 @@ #define gpio0_g4 26 // Pins available in GPIO1 -#define gpio1_sel0 12 /* 44 */ +#define gpio1_sel0 12 /* 44, must be sequential with sel1 and sel2 */ #define gpio1_sel1 13 /* 45 */ #define gpio1_sel2 14 /* 46 */ #define gpio1_latch 28 /* 60 */ @@ -72,23 +72,21 @@ #include "ws281x.hp" /** Mappings of the GPIO devices */ -#define GPIO0 0x44E07000 -#define GPIO1 0x4804c000 -#define GPIO2 0x481AC000 -#define GPIO3 0x481AE000 +#define GPIO0 (0x44E07000 + 0x100) +#define GPIO1 (0x4804c000 + 0x100) +#define GPIO2 (0x481AC000 + 0x100) +#define GPIO3 (0x481AE000 + 0x100) /** Offsets for the clear and set registers in the devices. - * These are adjacent; can one sbbo instruction be used? + * Since the offsets can only be 0xFF, we deliberately add offsets */ -#define GPIO_CLRDATAOUT 0x190 -#define GPIO_SETDATAOUT 0x194 +#define GPIO_CLRDATAOUT (0x190 - 0x100) +#define GPIO_SETDATAOUT (0x194 - 0x100) /** Register map */ #define data_addr r0 -#define gpio0_set r20 -#define gpio0_clr r21 -#define gpio1_set r2 -#define gpio1_clr r3 +#define gpio0_base r2 +#define gpio1_base r3 #define row r4 #define offset r5 #define scan r6 @@ -121,26 +119,26 @@ lab: #define BRIGHT_STEP 32 #define CLOCK_LO \ - SBBO clock_pin, gpio1_set, 0, 4; \ + SBBO clock_pin, gpio1_base, GPIO_SETDATAOUT, 4; \ #define CLOCK_HI \ - SBBO clock_pin, gpio1_clr, 0, 4; \ + SBBO clock_pin, gpio1_base, GPIO_CLRDATAOUT, 4; \ #define LATCH_HI \ - SBBO latch_pin, gpio1_set, 0, 4; \ + SBBO latch_pin, gpio1_base, GPIO_SETDATAOUT, 4; \ #define LATCH_LO \ - SBBO latch_pin, gpio1_clr, 0, 4; \ + SBBO latch_pin, gpio1_base, GPIO_CLRDATAOUT, 4; \ #define DISPLAY_OFF \ MOV out_set, 0; \ SET out_set, gpio1_oe; \ - SBBO out_set, gpio1_set, 0, 4; \ + SBBO out_set, gpio1_base, GPIO_SETDATAOUT, 4; \ #define DISPLAY_ON \ MOV out_set, 0; \ SET out_set, gpio1_oe; \ - SBBO out_set, gpio1_clr, 0, 4; \ + SBBO out_set, gpio1_base, GPIO_CLRDATAOUT, 4; \ START: @@ -181,12 +179,10 @@ START: MOV bright, #0 - MOV gpio0_set, GPIO0 | GPIO_SETDATAOUT - MOV gpio0_clr, GPIO0 | GPIO_CLRDATAOUT + MOV gpio0_base, GPIO0 MOV gpio0_led_mask, GPIO0_LED_MASK - MOV gpio1_set, GPIO1 | GPIO_SETDATAOUT - MOV gpio1_clr, GPIO1 | GPIO_CLRDATAOUT + MOV gpio1_base, GPIO1 MOV gpio1_sel_mask, GPIO1_SEL_MASK MOV clock_pin, 0 @@ -240,8 +236,11 @@ PWM_LOOP: // All bits are configured; // the non-set ones will be cleared + // We write 8 bytes since CLR and DATA are contiguous, + // which will write both the 0 and 1 bits in the + // same instruction. XOR out_clr, out_set, gpio0_led_mask - SBBO out_clr, gpio0_clr, 0, 8 // write both clr and set + SBBO out_clr, gpio0_base, GPIO_CLRDATAOUT, 8 CLOCK_LO @@ -271,21 +270,10 @@ PWM_LOOP: DISPLAY_OFF LATCH_HI - // set address; pins in gpio1 - MOV out_set, 0 - QBBC sel0, row, 0 - SET out_set, gpio1_sel0 - sel0: - QBBC sel1, row, 1 - SET out_set, gpio1_sel1 - sel1: - QBBC sel2, row, 2 - SET out_set, gpio1_sel2 - sel2: - - // write select bits to output + // set address; select pins in gpio1 are sequential + LSL out_set, row, gpio1_sel0 XOR out_clr, out_set, gpio1_sel_mask - SBBO out_clr, gpio1_clr, 0, 8 // set both + SBBO out_clr, gpio1_base, GPIO_CLRDATAOUT, 8 // set both // We have clocked out all of the pixels for // this row and the one eigth rows later. From 0e3ef3da19f67b59442bb41b07eb9cb03af269ba Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Mon, 9 Sep 2013 12:15:55 +0000 Subject: [PATCH 109/332] todo -- track four pointers to save v20ns per data clock --- matrix.p | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/matrix.p b/matrix.p index b2e21c5a..14086ea6 100644 --- a/matrix.p +++ b/matrix.p @@ -101,20 +101,10 @@ #define pix r16 #define clock_pin r17 #define latch_pin r18 - -/** Sleep a given number of nanoseconds with 10 ns resolution. - * - * This busy waits for a given number of cycles. Not for use - * with things that must happen on a tight schedule. - */ -.macro SLEEPNS -.mparam ns,inst,lab - MOV p2, (ns/10)-1-inst -lab: - SUB p2, p2, 1 - QBNE lab, p2, 0 -.endm - +#define row1_ptr r19 +#define row2_ptr r20 +#define row3_ptr r21 +#define row4_ptr r22 #define BRIGHT_STEP 32 @@ -216,6 +206,7 @@ PWM_LOOP: CLOCK_HI // read a pixel worth of data + // \todo: track the four pointers separately #define OUTPUT_ROW(N, OFFSET) \ MOV p2, (OFFSET); \ LBBO pix, pix_ptr, p2, 4; \ From 6e5225fb5b20c46be0917afda7ea867384b2adc7 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 11 Sep 2013 00:35:45 +0000 Subject: [PATCH 110/332] Track the four outputs individually, save a few ns per data cycle --- matrix.p | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/matrix.p b/matrix.p index 14086ea6..ec87f025 100644 --- a/matrix.p +++ b/matrix.p @@ -85,12 +85,13 @@ /** Register map */ #define data_addr r0 +#define row_skip_bytes r1 #define gpio0_base r2 #define gpio1_base r3 #define row r4 #define offset r5 #define scan r6 -#define pix_ptr r7 +#define display_width_bytes r7 #define pixel r8 #define out_clr r9 // must be one less than out_set #define out_set r10 @@ -175,6 +176,9 @@ START: MOV gpio1_base, GPIO1 MOV gpio1_sel_mask, GPIO1_SEL_MASK + MOV display_width_bytes, 4*DISPLAY_WIDTH + MOV row_skip_bytes, 4*8*ROW_WIDTH + MOV clock_pin, 0 MOV latch_pin, 0 SET clock_pin, gpio1_clock @@ -195,11 +199,15 @@ PWM_LOOP: MOV offset, 0 MOV row, 0 + // Store the pointers to each of the four outputs + ADD row1_ptr, data_addr, 0 + ADD row2_ptr, row1_ptr, row_skip_bytes + ADD row3_ptr, row1_ptr, display_width_bytes + ADD row4_ptr, row3_ptr, row_skip_bytes + ROW_LOOP: // compute where we are in the image - - MOV pixel, 0 - ADD pix_ptr, data_addr, offset + MOV pixel, 0 PIXEL_LOOP: MOV out_set, 0 @@ -207,9 +215,8 @@ PWM_LOOP: // read a pixel worth of data // \todo: track the four pointers separately -#define OUTPUT_ROW(N, OFFSET) \ - MOV p2, (OFFSET); \ - LBBO pix, pix_ptr, p2, 4; \ +#define OUTPUT_ROW(N) \ + LBBO pix, row##N##_ptr, offset, 4; \ QBGE skip_r##N, pix.b0, bright; \ SET out_set, gpio0_r##N; \ skip_r##N:; \ @@ -220,10 +227,10 @@ PWM_LOOP: SET out_set, gpio0_b##N; \ skip_b##N:; \ - OUTPUT_ROW(1, 0) - OUTPUT_ROW(2, 8*ROW_WIDTH*4) - OUTPUT_ROW(3, DISPLAY_WIDTH*4) - OUTPUT_ROW(4, 8*ROW_WIDTH*4 + DISPLAY_WIDTH*4) + OUTPUT_ROW(1) + OUTPUT_ROW(2) + OUTPUT_ROW(3) + OUTPUT_ROW(4) // All bits are configured; // the non-set ones will be cleared @@ -252,10 +259,14 @@ PWM_LOOP: no_blank: #endif - ADD pix_ptr, pix_ptr, 4 + ADD offset, offset, 4 ADD pixel, pixel, 1 +#if DISPLAY_WIDTH > 0xFF MOV p2, DISPLAY_WIDTH QBNE PIXEL_LOOP, pixel, p2 +#else + QBNE PIXEL_LOOP, pixel, DISPLAY_WIDTH +#endif // Disable output before we latch and set the address DISPLAY_OFF @@ -272,9 +283,11 @@ PWM_LOOP: LATCH_LO DISPLAY_ON + // We have drawn half the image on each chain; + // skip the second half + ADD offset, offset, display_width_bytes + ADD row, row, 1 - MOV p2, ROW_WIDTH * 4 - ADD offset, offset, p2 QBNE ROW_LOOP, row, 8 // We have clocked out all of the panels. From 2eaba0141c56836c55b9cda36072a63d4913a7a6 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 11 Sep 2013 01:45:23 +0000 Subject: [PATCH 111/332] tweak the pwm params --- matrix-test.c | 16 +++++++++++++++- matrix.p | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/matrix-test.c b/matrix-test.c index 17b2a491..1707b70d 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -101,7 +101,21 @@ rainbow( for (unsigned x=0; x < num_leds; x++) { for (unsigned y=0; y < 16; y++) { const int index = (color + x + y*phaseShift/2) % 180; - pixels[x + y*num_leds] = rainbowColors[index]; + const uint32_t in = rainbowColors[index]; + uint8_t * const out = &pixels[x + y*num_leds]; +#if 0 + out[0] = ((in >> 0) & 0xFF) * y / 16; + out[1] = ((in >> 8) & 0xFF) * y / 16; + out[2] = ((in >> 16) & 0xFF) * y / 16; + + out[0] = 0xFF * y / 16; + out[1] = 0xFF * y / 16; + out[2] = 0xFF * y / 16; +#else + out[0] = ((in >> 0) & 0xFF); + out[1] = ((in >> 8) & 0xFF); + out[2] = ((in >> 16) & 0xFF); +#endif } } } diff --git a/matrix.p b/matrix.p index ec87f025..677ede97 100644 --- a/matrix.p +++ b/matrix.p @@ -249,7 +249,7 @@ PWM_LOOP: // every fourth, every eigth, etc pixel based on // the current brightness. #if 1 - LSL p2, pixel, 2 + LSL p2, pixel, 4 ADD p2, p2, pixel ADD p2, p2, pixel ADD p2, p2, pixel From 1f757675f3105710a215bf41033577385467930e Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 11 Sep 2013 16:58:22 -0400 Subject: [PATCH 112/332] v1 of the cape --- pcb/octoscroller.brd | 1368 ++++++++++++++++++++++++++++++++ pcb/octoscroller.sch | 1761 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 3129 insertions(+) create mode 100644 pcb/octoscroller.brd create mode 100644 pcb/octoscroller.sch diff --git a/pcb/octoscroller.brd b/pcb/octoscroller.brd new file mode 100644 index 00000000..945140f9 --- /dev/null +++ b/pcb/octoscroller.brd @@ -0,0 +1,1368 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Octoscroller +2013-09-11 v1 +http://trmm.net/Octoscroller + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +>NAME +>VALUE +P8 +P9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Pin Header Connectors</b><p> +<author>Created by librarian@cadsoft.de</author> + + +<b>PIN HEADER</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>EAGLE Design Rules</b> +<p> +Die Standard-Design-Rules sind so gewählt, dass sie für +die meisten Anwendungen passen. Sollte ihre Platine +besondere Anforderungen haben, treffen Sie die erforderlichen +Einstellungen hier und speichern die Design Rules unter +einem neuen Namen ab. +<b>EAGLE Design Rules</b> +<p> +The default Design Rules have been set to cover +a wide range of applications. Your particular design +may have different requirements, so please make the +necessary adjustments and save your customized +design rules under a new name. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcb/octoscroller.sch b/pcb/octoscroller.sch new file mode 100644 index 00000000..b768fb66 --- /dev/null +++ b/pcb/octoscroller.sch @@ -0,0 +1,1761 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +>NAME +>VALUE +P8 +P9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +P8 +P9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Should match A3 pinout - but not completely tested + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Pin Header Connectors</b><p> +<author>Created by librarian@cadsoft.de</author> + + +<b>PIN HEADER</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + +<b>PIN HEADER</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + +<b>PIN HEADER</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Supply Symbols</b><p> + GND, VCC, 0V, +5V, -5V, etc.<p> + Please keep in mind, that these devices are necessary for the + automatic wiring of the supply signals.<p> + The pin name defined in the symbol is identical to the net which is to be wired automatically.<p> + In this library the device names are the same as the pin names of the symbols, therefore the correct signal names appear next to the supply symbols in the schematic.<p> + <author>Created by librarian@cadsoft.de</author> + + + + + +>VALUE + + + + + +<b>SUPPLY SYMBOL</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 34c01153e2e67b44d0083cc8e688dfda4745d321 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 11 Sep 2013 21:37:11 +0000 Subject: [PATCH 113/332] fix brightness error on rows 7 and 15 by adding a bogus dummy row --- matrix.p | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/matrix.p b/matrix.p index 677ede97..30d4cb3c 100644 --- a/matrix.p +++ b/matrix.p @@ -249,10 +249,7 @@ PWM_LOOP: // every fourth, every eigth, etc pixel based on // the current brightness. #if 1 - LSL p2, pixel, 4 - ADD p2, p2, pixel - ADD p2, p2, pixel - ADD p2, p2, pixel + LSL p2, pixel, 1 QBLT no_blank, bright, p2 DISPLAY_OFF @@ -269,7 +266,10 @@ PWM_LOOP: #endif // Disable output before we latch and set the address + // Unless we've just done a full image, in which case + // we treat this as a dummy row and go back to the top DISPLAY_OFF + QBEQ NEXT_ROW, row, 8 LATCH_HI // set address; select pins in gpio1 are sequential @@ -288,8 +288,9 @@ PWM_LOOP: ADD offset, offset, display_width_bytes ADD row, row, 1 - QBNE ROW_LOOP, row, 8 + QBA ROW_LOOP +NEXT_ROW: // We have clocked out all of the panels. // Celebrate and go back to the PWM loop // Limit brightness to 0..MAX_BRIGHT From f01adda04ebe7778c6b3ee03ee251ed8789b2fae Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 11 Sep 2013 21:45:11 +0000 Subject: [PATCH 114/332] matrix test with a few other color options --- matrix-test.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/matrix-test.c b/matrix-test.c index 1707b70d..2bd82232 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -103,18 +103,17 @@ rainbow( const int index = (color + x + y*phaseShift/2) % 180; const uint32_t in = rainbowColors[index]; uint8_t * const out = &pixels[x + y*num_leds]; -#if 0 - out[0] = ((in >> 0) & 0xFF) * y / 16; - out[1] = ((in >> 8) & 0xFF) * y / 16; - out[2] = ((in >> 16) & 0xFF) * y / 16; - - out[0] = 0xFF * y / 16; - out[1] = 0xFF * y / 16; - out[2] = 0xFF * y / 16; +#if 1 + out[0] = ((in >> 0) & 0xFF); // * y / 16; + out[1] = ((in >> 8) & 0xFF); // * y / 16; + out[2] = ((in >> 16) & 0xFF); // * y / 16; #else - out[0] = ((in >> 0) & 0xFF); - out[1] = ((in >> 8) & 0xFF); - out[2] = ((in >> 16) & 0xFF); + //out[0] = ((in >> 0) & 0xFF); + //out[1] = ((in >> 8) & 0xFF); + //out[2] = ((in >> 16) & 0xFF); + out[0] = y + 3*x + cycle; + out[1] = y + 3*x + cycle; + out[2] = y + 3*x + cycle; #endif } } From edba42c67bbc37418e9646e3291a09732f075300 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 11 Sep 2013 21:45:19 +0000 Subject: [PATCH 115/332] need to update pin list --- ledscape.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ledscape.c b/ledscape.c index 386c23db..81e91c0f 100644 --- a/ledscape.c +++ b/ledscape.c @@ -22,6 +22,10 @@ * If these are changed, be sure to check the mappings in * ws281x.p! * + * The RGB matrix uses a subset of these pins, although with + * the HDMI disabled it might use quite a few more for the four + * output version. + * * \todo: Find a way to unify this with the defines in the .p file */ static const uint8_t gpios0[] = { From f93c2f4fe746d8699569d236295fdfc8085e9214 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 15 Sep 2013 17:55:23 +0000 Subject: [PATCH 116/332] Send data using the python image library --- matrix-udp-rx.c | 7 ++++--- python-test | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) create mode 100755 python-test diff --git a/matrix-udp-rx.c b/matrix-udp-rx.c index 97e3afaf..848aec41 100644 --- a/matrix-udp-rx.c +++ b/matrix-udp-rx.c @@ -26,8 +26,8 @@ #include "ledscape.h" static int port = 9999; -static unsigned width = 64; -static unsigned height = 210; +static unsigned width = 16; +static unsigned height = 256; static int udp_socket( @@ -128,7 +128,8 @@ main( for (unsigned y = 0 ; y < height ; y++) { uint8_t * const out = (void*) &fb[x + y*width]; - const uint8_t * const in = &buf[1 + (x*64 + y+24)*3]; + //const uint8_t * const in = &buf[1 + (x*64 + y+24)*3]; + const uint8_t * const in = &buf[1 + 3*(x + y*width)]; out[0] = in[0]; out[1] = in[1]; out[2] = in[2]; diff --git a/python-test b/python-test new file mode 100755 index 00000000..b4d7b806 --- /dev/null +++ b/python-test @@ -0,0 +1,15 @@ +#!/usr/bin/python +# Draw images with PIL and send them to the display. +# +import Image +import socket + +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +dest = ("localhost", 9999) + +#im = Image.new("RGB", (256,16), "black") +im = Image.open("futurecrew.png") +print im.format, im.size, im.mode + +sock.sendto(chr(1) + im.convert("RGB").tostring(), dest) + From 0e1508e50c1bf6de4ae43d9dc302dc0d7bb96821 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 15 Sep 2013 18:36:41 +0000 Subject: [PATCH 117/332] Scrolling time display works. --- python-test | 28 +++++++++++++++++++++++----- spincycle.ttf | Bin 0 -> 41000 bytes 2 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 spincycle.ttf diff --git a/python-test b/python-test index b4d7b806..0ba46679 100755 --- a/python-test +++ b/python-test @@ -1,15 +1,33 @@ #!/usr/bin/python # Draw images with PIL and send them to the display. # -import Image +import Image, ImageFont, ImageDraw import socket +import time, datetime sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) dest = ("localhost", 9999) -#im = Image.new("RGB", (256,16), "black") -im = Image.open("futurecrew.png") -print im.format, im.size, im.mode +logo = Image.open("futurecrew.png") +#print im.format, im.size, im.mode +# use a truetype font +font = ImageFont.truetype("spincycle.ttf", 24) -sock.sendto(chr(1) + im.convert("RGB").tostring(), dest) +i = 0 +width = 256 +disp = Image.new("RGB", (256,16), "black") +im = Image.new("RGB", (width,16), "black") +draw = ImageDraw.Draw(im) +while True: + im.paste("black", (0,0,width,16)) + t = datetime.datetime.now().strftime("%a %d %b %H:%M:%S") + draw.text((0, -4), t, font=font) + + disp.paste(im.crop((0,0,i,16)), (256-i,0)) + disp.paste(im.crop((i+1,0,255,16)), (0,0)) + + # Slice a 256 size image from the large image + sock.sendto(chr(1) + disp.tostring(), dest) + i = (i+1) % width + time.sleep(0.025) diff --git a/spincycle.ttf b/spincycle.ttf new file mode 100644 index 0000000000000000000000000000000000000000..7f6de674ac6acc4225c888091fe1e854c790876d GIT binary patch literal 41000 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 z%0A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

FA0RVaEEb2n~Oe=B8Q%kv+LI+xI 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 Date: Sun, 15 Sep 2013 18:59:26 +0000 Subject: [PATCH 118/332] Scrolling multi-color example; removed bitmap test since it is no longer used --- bitmap-test.c | 76 ------------------------------------------ pf_tempesta_seven.ttf | Bin 0 -> 77568 bytes python-test | 30 +++++++++++++---- 3 files changed, 24 insertions(+), 82 deletions(-) delete mode 100644 bitmap-test.c create mode 100644 pf_tempesta_seven.ttf diff --git a/bitmap-test.c b/bitmap-test.c deleted file mode 100644 index cf40ca8d..00000000 --- a/bitmap-test.c +++ /dev/null @@ -1,76 +0,0 @@ -/** \file - * Test the matrix LCD PRU firmware by displaying an image. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "ledscape.h" - -int -main( - int argc, - char ** argv -) -{ - const int num_pixels = 256; - ledscape_t * const leds = ledscape_init(num_pixels); - - FILE * f = fopen(argv[1], "r"); - uint8_t * buf = calloc(1<<20, 1); - size_t len = fread(buf, 1, 1<<20, f); - printf("len=%zu\n", len); - - buf += 0x82; // skip the BMP header (hardcoded) - - time_t last_time = time(NULL); - unsigned last_i = 0; - - unsigned i = 0; - while (1) - { - // Alternate frame buffers on each draw command - const unsigned frame_num = i++ % 2; - ledscape_frame_t * const frame - = ledscape_frame(leds, frame_num); - - uint32_t * const p = (void*) frame; - - for (unsigned x = 0 ; x < num_pixels ; x++) - { - for (unsigned y = 0 ; y < 16 ; y++) - { - uint8_t j = (i >> 6); - uint8_t * const inpx = (void*) &buf[4 * ((x + j) % num_pixels) + num_pixels * (16 - y) * 4]; - uint8_t * const px = (void*) &p[x + num_pixels * y]; - - px[0] = inpx[0]; - px[1] = inpx[1]; - px[2] = inpx[2]; - } - } - ledscape_draw(leds, frame_num); - usleep(100); - - // wait for the previous frame to finish; - //const uint32_t response = ledscape_wait(leds); - const uint32_t response = 0; - time_t now = time(NULL); - if (now != last_time) - { - printf("%d fps. starting %d previous %"PRIx32"\n", - i - last_i, i, response); - last_i = i; - last_time = now; - } - - } - - ledscape_close(leds); - - return EXIT_SUCCESS; -} diff --git a/pf_tempesta_seven.ttf b/pf_tempesta_seven.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1a85a620a0e20571849b7b8062dd596bbc33edad GIT binary patch literal 77568 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 literal 0 HcmV?d00001 diff --git a/python-test b/python-test index 0ba46679..b6d2d2cc 100755 --- a/python-test +++ b/python-test @@ -1,33 +1,51 @@ #!/usr/bin/python # Draw images with PIL and send them to the display. +# Dual scrolling example with fixed time on each side and +# the date scrolling around. # import Image, ImageFont, ImageDraw import socket import time, datetime +from colorsys import hsv_to_rgb sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) dest = ("localhost", 9999) -logo = Image.open("futurecrew.png") #print im.format, im.size, im.mode # use a truetype font -font = ImageFont.truetype("spincycle.ttf", 24) +font = ImageFont.truetype("spincycle.ttf", 18) +font_sm = ImageFont.truetype("pf_tempesta_seven.ttf", 8) i = 0 width = 256 disp = Image.new("RGB", (256,16), "black") im = Image.new("RGB", (width,16), "black") -draw = ImageDraw.Draw(im) +im_draw = ImageDraw.Draw(im) +disp_draw = ImageDraw.Draw(disp) + +def rainbow(i): + rgb = [int(x*256) for x in hsv_to_rgb(i/256.0,0.8,0.8)] + return (rgb[0],rgb[1],rgb[2]) + while True: im.paste("black", (0,0,width,16)) - t = datetime.datetime.now().strftime("%a %d %b %H:%M:%S") - draw.text((0, -4), t, font=font) + now = datetime.datetime.now() + d = now.strftime("%a %d %b %Y") + t = now.strftime("%H:%M") + # Draw the date + im_draw.text((0, -2), d, font=font, fill=rainbow(i)) + + # Make it scroll disp.paste(im.crop((0,0,i,16)), (256-i,0)) disp.paste(im.crop((i+1,0,255,16)), (0,0)) - # Slice a 256 size image from the large image + # draw the time on each face + for x in range(0,7): + disp_draw.text((4+x*32, 8-3), t, font=font_sm) + + # Send it to the drawing server sock.sendto(chr(1) + disp.tostring(), dest) i = (i+1) % width time.sleep(0.025) From 88f9d1d88a3412f5c0b85ab7bee9bf080fab914e Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Thu, 19 Sep 2013 02:15:39 +0000 Subject: [PATCH 119/332] Remove bitmap test --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 1d88f406..2feeae1e 100755 --- a/Makefile +++ b/Makefile @@ -6,7 +6,6 @@ TARGETS += teensy-udp-rx TARGETS += rgb-test TARGETS += matrix-test TARGETS += matrix-udp-rx -TARGETS += bitmap-test TARGETS += udp-rx LEDSCAPE_OBJS = ledscape.o pru.o bitslice.o util.o From ae5e6c2dfd41a9c2a4da421288105ffe217c6ec2 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 29 Sep 2013 11:47:04 -0400 Subject: [PATCH 120/332] octoscroller gets octo-outputs --- pcb/octoscroller.brd | 514 +++++++++++----------- pcb/octoscroller.sch | 987 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 1114 insertions(+), 387 deletions(-) diff --git a/pcb/octoscroller.brd b/pcb/octoscroller.brd index 945140f9..12f4a4c0 100644 --- a/pcb/octoscroller.brd +++ b/pcb/octoscroller.brd @@ -1,6 +1,6 @@ - + @@ -664,6 +664,37 @@ + +<b>Dual In Line Package</b> + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + @@ -953,10 +984,15 @@ design rules under a new name. - - - - + + + + + + + + + @@ -970,36 +1006,46 @@ design rules under a new name. - + + + + + + - - - - - - - - - + + + + + + + + + + + + + + - + - + @@ -1010,357 +1056,309 @@ design rules under a new name. - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcb/octoscroller.sch b/pcb/octoscroller.sch index b768fb66..8083da4c 100644 --- a/pcb/octoscroller.sch +++ b/pcb/octoscroller.sch @@ -1,6 +1,6 @@ - + @@ -659,6 +659,234 @@ + +<b>Dual In Line Package</b> + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>Wide Small Outline package</b> 300 mil + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Leadless Chip Carrier</b><p> Ceramic Package + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + @@ -767,6 +995,39 @@ + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + +>NAME +GND +VCC + + + @@ -876,6 +1137,123 @@ + +Octal <b>BUS TRANSCEIVER</b>, 3-state + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1198,6 +1576,15 @@ + + + + + + + + + @@ -1213,6 +1600,15 @@ + + + + + + + + + @@ -1228,6 +1624,41 @@ From b95058048807a34ad097ebb647dd7f4e6c0df602 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 29 Sep 2013 12:45:22 -0400 Subject: [PATCH 121/332] octoscroller renamed outputs --- pcb/octoscroller.brd | 457 +++++++++++------- pcb/octoscroller.sch | 1043 +++++++++++++++++++++++++++--------------- 2 files changed, 979 insertions(+), 521 deletions(-) diff --git a/pcb/octoscroller.brd b/pcb/octoscroller.brd index 12f4a4c0..142833ba 100644 --- a/pcb/octoscroller.brd +++ b/pcb/octoscroller.brd @@ -123,9 +123,9 @@ -Octoscroller -2013-09-11 v1 -http://trmm.net/Octoscroller +Octoscroller +2013-09-11 v1 +http://trmm.net/Octoscroller @@ -1035,7 +1035,8 @@ design rules under a new name. - + + @@ -1054,84 +1055,19 @@ design rules under a new name. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1139,18 +1075,18 @@ design rules under a new name. + - - - - + + + + - @@ -1158,18 +1094,18 @@ design rules under a new name. + - - - - + + + + - @@ -1177,18 +1113,18 @@ design rules under a new name. + + - - - - + + + - @@ -1196,56 +1132,24 @@ design rules under a new name. - + - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1253,18 +1157,18 @@ design rules under a new name. + - - - - + + + + - @@ -1272,14 +1176,15 @@ design rules under a new name. + + - - - - - + + + + @@ -1287,33 +1192,9 @@ design rules under a new name. - - - - - - - - - - - - - - - - - - - - - - - - @@ -1337,7 +1218,6 @@ design rules under a new name. - @@ -1345,20 +1225,277 @@ design rules under a new name. + - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcb/octoscroller.sch b/pcb/octoscroller.sch index 8083da4c..21a26208 100644 --- a/pcb/octoscroller.sch +++ b/pcb/octoscroller.sch @@ -1585,6 +1585,7 @@ + @@ -1609,197 +1610,38 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1808,11 +1650,6 @@ - - - - + + + + @@ -1855,11 +1697,6 @@ - - - - + + + + @@ -1902,11 +1744,6 @@ - - - - + + + + @@ -1949,11 +1791,6 @@ - - - - - - - - - + + + + - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2137,11 +1899,6 @@ @@ -2290,6 +2052,16 @@ + + + + + + + + + + @@ -2305,48 +2077,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2354,20 +2084,6 @@ - - - - - - - - - - - - @@ -2424,11 +2140,6 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 16ae931b003ae7abfb5ea67526edbb87c7ddf406 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 29 Sep 2013 15:52:08 -0400 Subject: [PATCH 122/332] As ordered from OSH Park --- pcb/octoscroller.brd | 1010 +++++++++++++++++++++++++++++++++--------- pcb/octoscroller.sch | 496 ++++++++++----------- 2 files changed, 1030 insertions(+), 476 deletions(-) diff --git a/pcb/octoscroller.brd b/pcb/octoscroller.brd index 142833ba..ab56442c 100644 --- a/pcb/octoscroller.brd +++ b/pcb/octoscroller.brd @@ -1,6 +1,6 @@ - + @@ -123,9 +123,9 @@ -Octoscroller -2013-09-11 v1 -http://trmm.net/Octoscroller +Octoscroller^2 +http://trmm.net/Octoscroller +2013-09-30 @@ -891,9 +891,9 @@ design rules under a new name. - + - + @@ -908,7 +908,7 @@ design rules under a new name. - + @@ -983,20 +983,19 @@ design rules under a new name. - - - - - - - - - - + + + + + + + + + + - @@ -1007,12 +1006,6 @@ design rules under a new name. - - - - - - @@ -1037,35 +1030,32 @@ design rules under a new name. + + + + + + + + + + + + - + - - - - + - - - - - - - - - - - - @@ -1076,14 +1066,45 @@ design rules under a new name. - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1095,14 +1116,50 @@ design rules under a new name. - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1114,14 +1171,47 @@ design rules under a new name. - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1133,20 +1223,44 @@ design rules under a new name. - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1158,14 +1272,53 @@ design rules under a new name. - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1177,44 +1330,46 @@ design rules under a new name. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1226,276 +1381,711 @@ design rules under a new name. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + - + + + + + + + + + + - + + + + + + + + - + + + + + + + - + + + + + + + + + + + + + + + - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - + + + - + + + + - + + + + + - + + + + + + + + + - + + + + + + - + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + - + + + + + + - + + + + + + + + + + + - + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcb/octoscroller.sch b/pcb/octoscroller.sch index 21a26208..40ab640f 100644 --- a/pcb/octoscroller.sch +++ b/pcb/octoscroller.sch @@ -1,6 +1,6 @@ - + @@ -8,20 +8,20 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + @@ -30,8 +30,8 @@ - - + + @@ -39,17 +39,17 @@ - - - - - - - - - - - + + + + + + + + + + + @@ -1584,7 +1584,7 @@ - + @@ -1611,38 +1611,11 @@ + - - - - - - - - - - - - - - - - - - - - - - - - @@ -1831,20 +1804,6 @@ - - - - - - - - - - - - @@ -2061,76 +2020,15 @@ + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2180,62 +2078,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2320,76 +2162,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2480,6 +2252,11 @@ + + + + @@ -2487,6 +2264,11 @@ + + + + @@ -2506,6 +2288,11 @@ + + + + @@ -2513,6 +2300,11 @@ + + + + @@ -2520,6 +2312,11 @@ + + + + @@ -2587,6 +2384,11 @@ + + + + @@ -2594,6 +2396,11 @@ + + + + @@ -2601,6 +2408,11 @@ + + + + @@ -2608,6 +2420,11 @@ + + + + @@ -2615,6 +2432,11 @@ + + + + @@ -2622,6 +2444,11 @@ + + + + @@ -2629,6 +2456,11 @@ + + + + @@ -2636,6 +2468,11 @@ + + + + @@ -2643,6 +2480,11 @@ + + + + @@ -2650,6 +2492,11 @@ + + + + @@ -2657,6 +2504,11 @@ + + + + @@ -2664,6 +2516,11 @@ + + + + @@ -2671,6 +2528,11 @@ + + + + @@ -2678,6 +2540,11 @@ + + + + @@ -2685,6 +2552,11 @@ + + + + @@ -2692,6 +2564,11 @@ + + + + @@ -2699,6 +2576,11 @@ + + + + @@ -2706,6 +2588,11 @@ + + + + @@ -2713,6 +2600,11 @@ + + + + @@ -2720,6 +2612,11 @@ + + + + @@ -2727,6 +2624,11 @@ + + + + @@ -2734,6 +2636,11 @@ + + + + @@ -2741,6 +2648,11 @@ + + + + @@ -2748,6 +2660,11 @@ + + + + @@ -2755,6 +2672,11 @@ + + + + @@ -2762,6 +2684,11 @@ + + + + @@ -2769,6 +2696,11 @@ + + + + @@ -2776,6 +2708,11 @@ + + + + @@ -2783,6 +2720,11 @@ + + + + @@ -2790,6 +2732,23 @@ + + + + + + + + + + + + + + @@ -2799,12 +2758,17 @@ - + + + + + + From c431388c0be2b65639be2da5364ee30d3919dc37 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 29 Sep 2013 20:18:28 -0400 Subject: [PATCH 123/332] port of the pyramid Fire to the octascroller --- Makefile | 1 + fire.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 fire.c diff --git a/Makefile b/Makefile index 2feeae1e..c4ca86cf 100755 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ TARGETS += teensy-udp-rx TARGETS += rgb-test TARGETS += matrix-test +TARGETS += fire TARGETS += matrix-udp-rx TARGETS += udp-rx diff --git a/fire.c b/fire.c new file mode 100644 index 00000000..3b9dc598 --- /dev/null +++ b/fire.c @@ -0,0 +1,208 @@ +/** \file + * Draw fire patterns, derived from the pyramid Fire code. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "ledscape.h" + + +// Borrowed by OctoWS2811 rainbow test +static unsigned int +h2rgb( + unsigned int v1, + unsigned int v2, + unsigned int hue +) +{ + if (hue < 60) + return v1 * 60 + (v2 - v1) * hue; + if (hue < 180) + return v2 * 60; + if (hue < 240) + return v1 * 60 + (v2 - v1) * (240 - hue); + + return v1 * 60; +} + + +// Convert HSL (Hue, Saturation, Lightness) to RGB (Red, Green, Blue) +// +// hue: 0 to 359 - position on the color wheel, 0=red, 60=orange, +// 120=yellow, 180=green, 240=blue, 300=violet +// +// saturation: 0 to 100 - how bright or dull the color, 100=full, 0=gray +// +// lightness: 0 to 100 - how light the color is, 100=white, 50=color, 0=black +// +static uint32_t +hsv2rgb( + unsigned int hue, + unsigned int saturation, + unsigned int lightness +) +{ + unsigned int red, green, blue; + unsigned int var1, var2; + + if (hue > 359) + hue = hue % 360; + if (saturation > 100) + saturation = 100; + if (lightness > 100) + lightness = 100; + + // algorithm from: http://www.easyrgb.com/index.php?X=MATH&H=19#text19 + if (saturation == 0) { + red = green = blue = lightness * 255 / 100; + } else { + if (lightness < 50) { + var2 = lightness * (100 + saturation); + } else { + var2 = ((lightness + saturation) * 100) - (saturation * lightness); + } + var1 = lightness * 200 - var2; + red = h2rgb(var1, var2, (hue < 240) ? hue + 120 : hue - 240) * 255 / 600000; + green = h2rgb(var1, var2, hue) * 255 / 600000; + blue = h2rgb(var1, var2, (hue >= 120) ? hue - 120 : hue + 240) * 255 / 600000; + } + return (blue << 16) | (green << 8) | red; +} + + +static const int w = 256; +static const int h = 16; + +// This will contain the pixels used to calculate the fire effect +static uint8_t fire[256][16]; + + // Flame colors +static uint32_t palette[255]; +static float angle; +static uint32_t calc1[256], calc2[256], calc3[256], calc4[256], calc5[256]; + +static void draw(uint32_t * frame) +{ + memset(frame, 0, w*h*sizeof(*frame)); + + angle = angle + 0.05; + + // Randomize the bottom row of the fire buffer + for (int x = 0; x < w; x++) + { + fire[x][h-1] = random() % 190; + } + + int counter = 0; + // Do the fire calculations for every pixel, from top to bottom + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + // Add pixel values around current pixel + + fire[x][y] = + ((fire[calc3[x]][calc2[y]] + + fire[calc1[x]][calc2[y]] + + fire[calc4[x]][calc2[y]] + + fire[calc1[x]][calc5[y]]) << 5) / (128+(abs(x-w/2))/4); // 129; + + // Output everything to screen using our palette colors + frame[counter] = palette[fire[x][y]]; + //frame[counter] = fire[x][y]; + + // Extract the red value using right shift and bit mask + // equivalent of red(pgTemp.pixels[x+y*w]) + if ((frame[counter++] >> 8 & 0xFF) == 128) { + // Only map 3D cube 'lit' pixels onto fire array needed for next frame + fire[x][y] = 128; + } + } + } +} + + +static int constrain( + int x, + int min, + int max +) +{ + if (x < min) + return min; + if (x > max) + return max; + return x; +} + +static void +init_pallete(void) +{ + for (int x = 0; x < 255; x++) { + //Hue goes from 0 to 85: red to yellow + //Saturation is always the maximum: 255 + //Lightness is 0..255 for x=0..128, and 255 for x=128..255 + palette[x] = hsv2rgb(x/3.5, 100, constrain(x, 0, 70)); + } + + // Precalculate which pixel values to add during animation loop + // this speeds up the effect by 10fps + for (int x = 0; x < w; x++) { + calc1[x] = x % w; + calc3[x] = (x - 1 + w) % w; + calc4[x] = (x + 1) % w; + } + + for (int y = 0; y < h; y++) { + calc2[y] = (y + 1) % h; + calc5[y] = (y + 2) % h; + } +} + + +int +main(void) +{ + const int num_pixels = 256; + ledscape_t * const leds = ledscape_init(num_pixels); + printf("init done\n"); + time_t last_time = time(NULL); + unsigned last_i = 0; + + unsigned i = 0; + init_pallete(); + + while (1) + { + // Alternate frame buffers on each draw command + const unsigned frame_num = i++ % 2; + ledscape_frame_t * const frame + = ledscape_frame(leds, frame_num); + + uint32_t * const p = (void*) frame; + + draw(p); + ledscape_draw(leds, frame_num); + usleep(20000); + + // wait for the previous frame to finish; + //const uint32_t response = ledscape_wait(leds); + const uint32_t response = 0; + time_t now = time(NULL); + if (now != last_time) + { + printf("%d fps. starting %d previous %"PRIx32"\n", + i - last_i, i, response); + last_i = i; + last_time = now; + } + + } + + ledscape_close(leds); + + return EXIT_SUCCESS; +} From 985a05e44c98b33d9b00996ca60cd6b28992df66 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 29 Sep 2013 20:43:27 -0400 Subject: [PATCH 124/332] slow it down, tweak pallete and avoid empty first line --- fire.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/fire.c b/fire.c index 3b9dc598..a99070b1 100644 --- a/fire.c +++ b/fire.c @@ -76,10 +76,10 @@ hsv2rgb( static const int w = 256; -static const int h = 16; +static const int h = 20; // This will contain the pixels used to calculate the fire effect -static uint8_t fire[256][16]; +static uint8_t fire[256][32]; // Flame colors static uint32_t palette[255]; @@ -88,7 +88,7 @@ static uint32_t calc1[256], calc2[256], calc3[256], calc4[256], calc5[256]; static void draw(uint32_t * frame) { - memset(frame, 0, w*h*sizeof(*frame)); + memset(frame, 0, w*16*sizeof(*frame)); angle = angle + 0.05; @@ -111,15 +111,17 @@ static void draw(uint32_t * frame) + fire[calc1[x]][calc5[y]]) << 5) / (128+(abs(x-w/2))/4); // 129; // Output everything to screen using our palette colors - frame[counter] = palette[fire[x][y]]; + const uint32_t c = palette[fire[x][y]]; //frame[counter] = fire[x][y]; // Extract the red value using right shift and bit mask // equivalent of red(pgTemp.pixels[x+y*w]) - if ((frame[counter++] >> 8 & 0xFF) == 128) { - // Only map 3D cube 'lit' pixels onto fire array needed for next frame + // Only map 3D cube 'lit' pixels onto fire array needed for next frame + if (((c >> 0) & 0xFF) == 128) fire[x][y] = 128; - } + + if (y > 1 && y < 2 + 16) + frame[counter++] = c; } } } @@ -145,7 +147,7 @@ init_pallete(void) //Hue goes from 0 to 85: red to yellow //Saturation is always the maximum: 255 //Lightness is 0..255 for x=0..128, and 255 for x=128..255 - palette[x] = hsv2rgb(x/3.5, 100, constrain(x, 0, 70)); + palette[x] = hsv2rgb(x/2, 100, constrain(x, 0, 40)); } // Precalculate which pixel values to add during animation loop @@ -186,7 +188,7 @@ main(void) draw(p); ledscape_draw(leds, frame_num); - usleep(20000); + usleep(30000); // wait for the previous frame to finish; //const uint32_t response = ledscape_wait(leds); From 35cc4c5088ab5a195bfce8e88bebdcbb5a0145d2 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 29 Sep 2013 20:54:43 -0400 Subject: [PATCH 125/332] reset occasionally --- fire.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fire.c b/fire.c index a99070b1..7ed029ec 100644 --- a/fire.c +++ b/fire.c @@ -188,18 +188,19 @@ main(void) draw(p); ledscape_draw(leds, frame_num); - usleep(30000); + usleep(50000); // wait for the previous frame to finish; //const uint32_t response = ledscape_wait(leds); const uint32_t response = 0; time_t now = time(NULL); - if (now != last_time) + if (now > last_time + 10) { printf("%d fps. starting %d previous %"PRIx32"\n", i - last_i, i, response); last_i = i; last_time = now; + memset(fire, 0, sizeof(fire)); } } From 4185a7286f6690ffbe5033c50b3703e89a5cafc3 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 7 Jan 2000 12:13:11 -0500 Subject: [PATCH 126/332] add sparkles --- fire.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/fire.c b/fire.c index 7ed029ec..2d04f4d0 100644 --- a/fire.c +++ b/fire.c @@ -86,7 +86,10 @@ static uint32_t palette[255]; static float angle; static uint32_t calc1[256], calc2[256], calc3[256], calc4[256], calc5[256]; -static void draw(uint32_t * frame) +static void +fire_draw( + uint32_t * const frame +) { memset(frame, 0, w*16*sizeof(*frame)); @@ -127,6 +130,16 @@ static void draw(uint32_t * frame) } +static void +sparkles( + uint32_t * const frame, + int num_sparkles +) +{ + for(int i = 0 ; i < num_sparkles ; i++) + frame[rand() % (16*256)] = 0xFFFFFF; +} + static int constrain( int x, int min, @@ -186,18 +199,21 @@ main(void) uint32_t * const p = (void*) frame; - draw(p); + time_t now = time(NULL); + const uint32_t delta = now - last_time; + + fire_draw(p); + sparkles(p, delta); ledscape_draw(leds, frame_num); usleep(50000); // wait for the previous frame to finish; //const uint32_t response = ledscape_wait(leds); const uint32_t response = 0; - time_t now = time(NULL); - if (now > last_time + 10) + if (delta > 30) { printf("%d fps. starting %d previous %"PRIx32"\n", - i - last_i, i, response); + (i - last_i) / delta, i, response); last_i = i; last_time = now; memset(fire, 0, sizeof(fire)); From c066f5e421d7ced81a37bd316dd8eb16b83bf2b9 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 31 Dec 1999 19:23:51 -0500 Subject: [PATCH 127/332] started conversion for new layout --- matrix.p | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/matrix.p b/matrix.p index 30d4cb3c..e6aa6250 100644 --- a/matrix.p +++ b/matrix.p @@ -34,12 +34,13 @@ #define gpio0_g4 26 // Pins available in GPIO1 -#define gpio1_sel0 12 /* 44, must be sequential with sel1 and sel2 */ -#define gpio1_sel1 13 /* 45 */ -#define gpio1_sel2 14 /* 46 */ -#define gpio1_latch 28 /* 60 */ -#define gpio1_oe 15 /* 47 */ -#define gpio1_clock 19 /* 51 */ +#define gpio1_sel0 12 /* must be sequential with sel1 and sel2 */ +#define gpio1_sel1 13 +#define gpio1_sel2 14 +#define gpio1_sel3 15 +#define gpio1_latch 28 +#define gpio1_oe 29 +#define gpio1_clock 19 /** Generate a bitmask of which pins in GPIO0-3 are used. * @@ -64,6 +65,7 @@ |(1< Date: Fri, 31 Dec 1999 20:10:19 -0500 Subject: [PATCH 128/332] output 1 works! --- ledscape.c | 8 +-- matrix.p | 159 ++++++++++++++++++++++++++++++++--------------------- 2 files changed, 99 insertions(+), 68 deletions(-) diff --git a/ledscape.c b/ledscape.c index 81e91c0f..f5fe8da8 100644 --- a/ledscape.c +++ b/ledscape.c @@ -29,19 +29,19 @@ * \todo: Find a way to unify this with the defines in the .p file */ static const uint8_t gpios0[] = { - 2, 3, 4, 5, 7, 12, 13, 14, 15, 20, 22, 23, 26, 27, 30, 31, + 27, 22, 10, 9, 8, 26, 11, 30, 31, 5, 3, 20, 4, 2, 14, 7 }; static const uint8_t gpios1[] = { - 12, 13, 14, 15, 16, 17, 18, 19, 28, 29, + 13, 15, 12, 14, 29, 16, 17, 28, 18, 19, }; static const uint8_t gpios2[] = { - 1, 2, 3, 4, 5, + 2, 5, 22, 23, 14, 12, 10, 8, 6, 3, 4, 1, 24, 25, 17, 16, 15, 13, 11, 9, 7, }; static const uint8_t gpios3[] = { - 16, 19, + 21, 19, 15, 14, 17, 16 }; #define ARRAY_COUNT(a) ((sizeof(a) / sizeof(*a))) diff --git a/matrix.p b/matrix.p index e6aa6250..07dbdbf2 100644 --- a/matrix.p +++ b/matrix.p @@ -17,23 +17,24 @@ * To shut down the PRU, write -1 to the buffer pointer. */ // Pins available in GPIO0 -#define gpio0_r1 3 -#define gpio0_g1 30 -#define gpio0_b1 15 +#define r11_gpio 2 +#define r11_pin 2 +#define g11_gpio 2 +#define g11_pin 3 +#define b11_gpio 2 +#define b11_pin 5 -#define gpio0_r2 2 -#define gpio0_b2 14 -#define gpio0_g2 31 +#define r12_gpio 0 +#define r12_pin 23 +#define g12_gpio 2 +#define g12_pin 4 +#define b12_gpio 0 +#define b12_pin 26 -#define gpio0_r3 7 -#define gpio0_b3 20 -#define gpio0_g3 22 -#define gpio0_r4 27 -#define gpio0_b4 23 -#define gpio0_g4 26 +#define CAT3(X,Y,Z) X##Y##Z -// Pins available in GPIO1 +// Control pins are all in GPIO1 #define gpio1_sel0 12 /* must be sequential with sel1 and sel2 */ #define gpio1_sel1 13 #define gpio1_sel2 14 @@ -47,20 +48,24 @@ * \todo wtf "parameter too long": only 128 chars allowed? */ #define GPIO0_LED_MASK (0\ -|(1< Date: Fri, 31 Dec 1999 19:32:43 -0500 Subject: [PATCH 129/332] output 2 works --- matrix.p | 76 +++++++++++++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/matrix.p b/matrix.p index 07dbdbf2..37292985 100644 --- a/matrix.p +++ b/matrix.p @@ -16,7 +16,6 @@ * To pause the redraw loop, write a NULL to the buffer pointer. * To shut down the PRU, write -1 to the buffer pointer. */ -// Pins available in GPIO0 #define r11_gpio 2 #define r11_pin 2 #define g11_gpio 2 @@ -31,6 +30,19 @@ #define b12_gpio 0 #define b12_pin 26 +#define r21_gpio 0 +#define r21_pin 27 +#define g21_gpio 2 +#define g21_pin 1 +#define b21_gpio 0 +#define b21_pin 22 + +#define r22_gpio 2 +#define r22_pin 22 +#define g22_gpio 2 +#define g22_pin 23 +#define b22_gpio 2 +#define b22_pin 24 #define CAT3(X,Y,Z) X##Y##Z @@ -47,24 +59,6 @@ * * \todo wtf "parameter too long": only 128 chars allowed? */ -#define GPIO0_LED_MASK (0\ -|(r11_gpio==0)< Date: Fri, 31 Dec 1999 20:04:26 -0500 Subject: [PATCH 130/332] add outputs 3 and 4. i2c is messing them up? --- matrix.p | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 81 insertions(+), 7 deletions(-) diff --git a/matrix.p b/matrix.p index 37292985..8f61d135 100644 --- a/matrix.p +++ b/matrix.p @@ -44,6 +44,34 @@ #define b22_gpio 2 #define b22_pin 24 +#define r31_gpio 0 +#define r31_pin 30 +#define g31_gpio 1 +#define g31_pin 18 +#define b31_gpio 0 +#define b31_pin 31 + +#define r32_gpio 1 +#define r32_pin 16 +#define g32_gpio 0 +#define g32_pin 3 +#define b32_gpio 0 // not working? +#define b32_pin 5 + +#define r41_gpio 0 +#define r41_pin 2 +#define g41_gpio 0 +#define g41_pin 15 +#define b41_gpio 1 +#define b41_pin 17 + +#define r42_gpio 3 +#define r42_pin 21 +#define g42_gpio 3 +#define g42_pin 19 +#define b42_gpio 0 +#define b42_pin 4 + #define CAT3(X,Y,Z) X##Y##Z // Control pins are all in GPIO1 @@ -90,19 +118,21 @@ #define gpio0_base r2 #define gpio1_base r3 #define gpio2_base r4 +#define gpio3_base r9 #define row r5 #define offset r6 #define scan r7 #define display_width_bytes r8 -#define pixel r9 #define out_clr r10 // must be one less than out_set #define out_set r11 #define p2 r12 #define bright r13 #define gpio0_led_mask r14 +#define gpio1_led_mask r27 #define gpio2_led_mask r15 +#define gpio3_led_mask r28 #define gpio1_sel_mask r16 -#define pix r17 +#define pixel r17 #define clock_pin r18 #define latch_pin r19 #define row11_ptr r20 @@ -110,7 +140,9 @@ #define row21_ptr r22 #define row22_ptr r23 #define gpio0_set r24 -#define gpio2_set r25 +#define gpio1_set r25 +#define gpio2_set r26 +#define gpio3_set r29 #define BRIGHT_STEP 32 @@ -178,11 +210,15 @@ START: MOV gpio0_base, GPIO0 MOV gpio1_base, GPIO1 MOV gpio2_base, GPIO2 + MOV gpio3_base, GPIO3 MOV gpio1_sel_mask, GPIO1_SEL_MASK MOV gpio0_led_mask, 0 + MOV gpio1_led_mask, 0 MOV gpio2_led_mask, 0 + MOV gpio3_led_mask, 0 + #define GPIO_MASK(X) CAT3(gpio,X,_led_mask) SET GPIO_MASK(r11_gpio), r11_pin SET GPIO_MASK(g11_gpio), g11_pin @@ -198,6 +234,20 @@ START: SET GPIO_MASK(g22_gpio), g22_pin SET GPIO_MASK(b22_gpio), b22_pin + SET GPIO_MASK(r31_gpio), r31_pin + SET GPIO_MASK(g31_gpio), g31_pin + SET GPIO_MASK(b31_gpio), b31_pin + SET GPIO_MASK(r32_gpio), r32_pin + SET GPIO_MASK(g32_gpio), g32_pin + SET GPIO_MASK(b32_gpio), b32_pin + + SET GPIO_MASK(r41_gpio), r41_pin + SET GPIO_MASK(g41_gpio), g41_pin + SET GPIO_MASK(b41_gpio), b41_pin + SET GPIO_MASK(r42_gpio), r42_pin + SET GPIO_MASK(g42_gpio), g42_pin + SET GPIO_MASK(b42_gpio), b42_pin + MOV display_width_bytes, 4*DISPLAY_WIDTH MOV row_skip_bytes, 4*8*ROW_WIDTH @@ -237,17 +287,31 @@ PWM_LOOP: #define GPIO(R) CAT3(gpio,R,_set) MOV gpio0_set, 0 + MOV gpio1_set, 0 MOV gpio2_set, 0 + MOV gpio3_set, 0 #define OUTPUT_ROW(N) \ - LBBO pix, row##N##_ptr, offset, 4; \ - QBGE skip_r##N, pix.b0, bright; \ + LBBO p2, row##N##_ptr, offset, 4; \ + QBGE skip_r##N, p2.b0, bright; \ SET GPIO(r##N##_gpio), r##N##_pin; \ skip_r##N: \ - QBGE skip_g##N, pix.b1, bright; \ + QBGE skip_g##N, p2.b1, bright; \ SET GPIO(g##N##_gpio), g##N##_pin; \ skip_g##N: \ - QBGE skip_b##N, pix.b2, bright; \ + QBGE skip_b##N, p2.b2, bright; \ + SET GPIO(b##N##_gpio), b##N##_pin; \ + skip_b##N: \ + +#define OUTPUT_ROW2(P,N) \ + LBBO p2, row##P##_ptr, offset, 4; \ + QBGE skip_r##N, p2.b0, bright; \ + SET GPIO(r##N##_gpio), r##N##_pin; \ + skip_r##N: \ + QBGE skip_g##N, p2.b1, bright; \ + SET GPIO(g##N##_gpio), g##N##_pin; \ + skip_g##N: \ + QBGE skip_b##N, p2.b2, bright; \ SET GPIO(b##N##_gpio), b##N##_pin; \ skip_b##N: \ @@ -255,6 +319,8 @@ PWM_LOOP: OUTPUT_ROW(12) OUTPUT_ROW(21) OUTPUT_ROW(22) + OUTPUT_ROW2(11,41) + OUTPUT_ROW2(12,42) // All bits are configured; // the non-set ones will be cleared @@ -265,10 +331,18 @@ PWM_LOOP: XOR out_clr, out_set, gpio0_led_mask SBBO out_clr, gpio0_base, GPIO_CLRDATAOUT, 8 + AND out_set, gpio1_set, gpio1_led_mask + XOR out_clr, out_set, gpio1_led_mask + SBBO out_clr, gpio1_base, GPIO_CLRDATAOUT, 8 + AND out_set, gpio2_set, gpio2_led_mask XOR out_clr, out_set, gpio2_led_mask SBBO out_clr, gpio2_base, GPIO_CLRDATAOUT, 8 + AND out_set, gpio3_set, gpio3_led_mask + XOR out_clr, out_set, gpio3_led_mask + SBBO out_clr, gpio3_base, GPIO_CLRDATAOUT, 8 + CLOCK_LO // If the brightness is less than the pixel, turn off From 9c70a798ffddf22758577290505c51c082a1601c Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 31 Dec 1999 19:15:08 -0500 Subject: [PATCH 131/332] all pins mapped and almost all functional --- ledscape.c | 2 +- matrix.p | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/ledscape.c b/ledscape.c index f5fe8da8..852c0ba7 100644 --- a/ledscape.c +++ b/ledscape.c @@ -29,7 +29,7 @@ * \todo: Find a way to unify this with the defines in the .p file */ static const uint8_t gpios0[] = { - 27, 22, 10, 9, 8, 26, 11, 30, 31, 5, 3, 20, 4, 2, 14, 7 + 23, 27, 22, 10, 9, 8, 26, 11, 30, 31, 5, 3, 20, 4, 2, 14, 7 }; static const uint8_t gpios1[] = { diff --git a/matrix.p b/matrix.p index 8f61d135..c275f314 100644 --- a/matrix.p +++ b/matrix.p @@ -72,6 +72,62 @@ #define b42_gpio 0 #define b42_pin 4 +#define r51_gpio 2 +#define r51_pin 25 +#define g51_gpio 0 +#define g51_pin 11 +#define b51_gpio 0 +#define b51_pin 10 + +#define r52_gpio 0 +#define r52_pin 9 +#define g52_gpio 0 +#define g52_pin 8 +#define b52_gpio 2 +#define b52_pin 17 + +#define r61_gpio 2 +#define r61_pin 16 +#define g61_gpio 2 +#define g61_pin 15 +#define b61_gpio 2 +#define b61_pin 14 + +#define r62_gpio 2 +#define r62_pin 13 +#define g62_gpio 2 +#define g62_pin 10 +#define b62_gpio 2 +#define b62_pin 12 + +#define r71_gpio 2 +#define r71_pin 11 +#define g71_gpio 2 +#define g71_pin 9 +#define b71_gpio 2 +#define b71_pin 8 + +#define r72_gpio 2 +#define r72_pin 6 +#define g72_gpio 0 +#define g72_pin 7 +#define b72_gpio 2 +#define b72_pin 7 + +#define r81_gpio 3 +#define r81_pin 17 +#define g81_gpio 3 +#define g81_pin 16 +#define b81_gpio 3 +#define b81_pin 15 + +#define r82_gpio 3 +#define r82_pin 14 +#define g82_gpio 0 +#define g82_pin 14 +#define b82_gpio 0 +#define b82_pin 20 + #define CAT3(X,Y,Z) X##Y##Z // Control pins are all in GPIO1 @@ -248,6 +304,34 @@ START: SET GPIO_MASK(g42_gpio), g42_pin SET GPIO_MASK(b42_gpio), b42_pin + SET GPIO_MASK(r51_gpio), r51_pin + SET GPIO_MASK(g51_gpio), g51_pin + SET GPIO_MASK(b51_gpio), b51_pin + SET GPIO_MASK(r52_gpio), r52_pin + SET GPIO_MASK(g52_gpio), g52_pin + SET GPIO_MASK(b52_gpio), b52_pin + + SET GPIO_MASK(r61_gpio), r61_pin + SET GPIO_MASK(g61_gpio), g61_pin + SET GPIO_MASK(b61_gpio), b61_pin + SET GPIO_MASK(r62_gpio), r62_pin + SET GPIO_MASK(g62_gpio), g62_pin + SET GPIO_MASK(b62_gpio), b62_pin + + SET GPIO_MASK(r71_gpio), r71_pin + SET GPIO_MASK(g71_gpio), g71_pin + SET GPIO_MASK(b71_gpio), b71_pin + SET GPIO_MASK(r72_gpio), r72_pin + SET GPIO_MASK(g72_gpio), g72_pin + SET GPIO_MASK(b72_gpio), b72_pin + + SET GPIO_MASK(r81_gpio), r81_pin + SET GPIO_MASK(g81_gpio), g81_pin + SET GPIO_MASK(b81_gpio), b81_pin + SET GPIO_MASK(r82_gpio), r82_pin + SET GPIO_MASK(g82_gpio), g82_pin + SET GPIO_MASK(b82_gpio), b82_pin + MOV display_width_bytes, 4*DISPLAY_WIDTH MOV row_skip_bytes, 4*8*ROW_WIDTH @@ -319,8 +403,8 @@ PWM_LOOP: OUTPUT_ROW(12) OUTPUT_ROW(21) OUTPUT_ROW(22) - OUTPUT_ROW2(11,41) - OUTPUT_ROW2(12,42) + OUTPUT_ROW2(11,81) + OUTPUT_ROW2(12,82) // All bits are configured; // the non-set ones will be cleared From 16c62f45c55d2101a7aa672e1687054dd12253c6 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 31 Dec 1999 20:46:28 -0500 Subject: [PATCH 132/332] send pre-formatted matrix to pru, rearrange based on config values --- fire.c | 15 ++-- ledscape.c | 113 +++++++++++++++++++++++++++--- ledscape.h | 12 +--- matrix-test.c | 27 ++++---- matrix.p | 189 +++++++++++++++++++++++--------------------------- 5 files changed, 209 insertions(+), 147 deletions(-) diff --git a/fire.c b/fire.c index 2d04f4d0..0a9c24f7 100644 --- a/fire.c +++ b/fire.c @@ -76,10 +76,10 @@ hsv2rgb( static const int w = 256; -static const int h = 20; +static const int h = 64; // This will contain the pixels used to calculate the fire effect -static uint8_t fire[256][32]; +static uint8_t fire[256][64]; // Flame colors static uint32_t palette[255]; @@ -181,30 +181,25 @@ init_pallete(void) int main(void) { - const int num_pixels = 256; - ledscape_t * const leds = ledscape_init(num_pixels); + ledscape_t * const leds = ledscape_init(w,h); printf("init done\n"); time_t last_time = time(NULL); unsigned last_i = 0; unsigned i = 0; init_pallete(); + uint32_t * const p = calloc(w*h,4); while (1) { // Alternate frame buffers on each draw command - const unsigned frame_num = i++ % 2; - ledscape_frame_t * const frame - = ledscape_frame(leds, frame_num); - - uint32_t * const p = (void*) frame; time_t now = time(NULL); const uint32_t delta = now - last_time; fire_draw(p); sparkles(p, delta); - ledscape_draw(leds, frame_num); + ledscape_draw(leds, p); usleep(50000); // wait for the previous frame to finish; diff --git a/ledscape.c b/ledscape.c index 852c0ba7..fc99c97c 100644 --- a/ledscape.c +++ b/ledscape.c @@ -69,16 +69,34 @@ typedef struct volatile unsigned response; } __attribute__((__packed__)) ws281x_command_t; +typedef struct +{ + uint32_t x_offset; + uint32_t y_offset; +} led_matrix_t; + +#define NUM_MATRIX 16 + +typedef struct +{ + uint32_t matrix_width; // of a full chain + uint32_t matrix_height; // number of rows per-output (8 or 16) + led_matrix_t matrix[NUM_MATRIX]; +} led_matrix_config_t; + + struct ledscape { ws281x_command_t * ws281x; pru_t * pru; - unsigned num_pixels; - size_t frame_size; + unsigned width;; + unsigned height;; + led_matrix_config_t * matrix; }; +#if 0 /** Retrieve one of the two frame buffers. */ ledscape_frame_t * ledscape_frame( @@ -91,16 +109,59 @@ ledscape_frame( return (ledscape_frame_t*)((uint8_t*) leds->pru->ddr + leds->frame_size * frame); } - +#endif + -/** Initiate the transfer of a frame to the LED strips */ +/** Translate the RGBA buffer to the correct output type and + * initiate the transfer of a frame to the LED strips. + * + * Matrix drivers shuffle to have consecutive bits, ws281x do bit slicing. + */ void ledscape_draw( ledscape_t * const leds, - unsigned int frame + const void * const buffer ) { - leds->ws281x->pixels_dma = leds->pru->ddr_addr + leds->frame_size * frame; + unsigned int frame = 0; + const uint32_t * const in = buffer; + uint8_t * const out = leds->pru->ddr; // + leds->frame_size * frame; + +#if 1 + // matrix packed is: + // p(0,0)p(0,8)p(64,0)p(64,8).... + // this way the PRU can read all sixteen output pixels in + // one LBBO and clock them out. + // there is an array of NUM_MATRIX output coordinates (one for each of + // the sixteen drivers). + for (unsigned i = 0 ; i < NUM_MATRIX ; i++) + { + const led_matrix_t * const m = &leds->matrix->matrix[i]; + + for (uint32_t y = 0 ; y < leds->matrix->matrix_height ; y++) + { + const uint32_t * const in_row = &in[(y+m->y_offset) * leds->width]; + uint8_t * const out_row = &out[y * leds->matrix->matrix_width * 3 * NUM_MATRIX]; + + for (uint32_t x = 0 ; x < leds->matrix->matrix_width ; x++) + { + const uint8_t * const rgb = (const void*) &in_row[x + m->x_offset]; + uint8_t * const out_rgb = &out_row[(i + x * NUM_MATRIX)*3]; + out_rgb[0] = rgb[0]; + out_rgb[1] = rgb[1]; + out_rgb[2] = rgb[2]; + } + } + } +#else + static int i = 0; + memset(out, i++, leds->width *leds->height * 3); + out[0] = 0x80; out[1] = 0x00; out[2] = 0x00; + out[3] = 0x00; out[4] = 0x80; out[5] = 0x00; + out[6] = 0x00; out[7] = 0x00; out[8] = 0x80; +#endif + + leds->ws281x->pixels_dma = leds->pru->ddr_addr; // + leds->frame_size * frame; #if 0 // Wait for any current command to have been acknowledged while (leds->ws281x->command) @@ -133,34 +194,64 @@ ledscape_wait( ledscape_t * ledscape_init( - unsigned num_pixels + unsigned width, + unsigned height ) { pru_t * const pru = pru_init(0); - const size_t frame_size = num_pixels * LEDSCAPE_NUM_STRIPS * 4; +#if 0 + const size_t frame_size = num_pixels * 16 * 3; //LEDSCAPE_NUM_STRIPS * 4; if (2 *frame_size > pru->ddr_size) die("Pixel data needs at least 2 * %zu, only %zu in DDR\n", frame_size, pru->ddr_size ); +#endif ledscape_t * const leds = calloc(1, sizeof(*leds)); *leds = (ledscape_t) { .pru = pru, - .num_pixels = num_pixels, - .frame_size = frame_size, + .width = width, + .height = height, .ws281x = pru->data_ram, + .matrix = calloc(sizeof(*leds->matrix), 1), + }; + + *(leds->matrix) = (led_matrix_config_t) { + .matrix_width = 128, + .matrix_height = 8, + .matrix = { + { 0, 0 }, + { 0, 8 }, + { 0, 16 }, + { 0, 24 }, + { 0, 32 }, + { 0, 40 }, + { 0, 48 }, + { 0, 56 }, + { 128, 0 }, + { 128, 8 }, + { 128, 16 }, + { 128, 24 }, + { 128, 32 }, + { 128, 40 }, + { 128, 48 }, + { 128, 56 }, + }, }; *(leds->ws281x) = (ws281x_command_t) { .pixels_dma = 0, // will be set in draw routine + .num_pixels = (leds->matrix->matrix_width * 3) * 16, .command = 0, .response = 0, - .num_pixels = leds->num_pixels, }; + printf("%d\n", leds->ws281x->num_pixels); + + // Configure all of our output pins. for (unsigned i = 0 ; i < ARRAY_COUNT(gpios0) ; i++) pru_gpio(0, gpios0[i], 1, 0); diff --git a/ledscape.h b/ledscape.h index 475420dc..45456abf 100644 --- a/ledscape.h +++ b/ledscape.h @@ -47,21 +47,15 @@ typedef struct ledscape ledscape_t; extern ledscape_t * ledscape_init( - unsigned num_pixels -); - - -extern ledscape_frame_t * -ledscape_frame( - ledscape_t * const leds, - unsigned frame + unsigned width, + unsigned height ); extern void ledscape_draw( ledscape_t * const leds, - unsigned frame + const void * const rgb // 4-byte rgb data ); diff --git a/matrix-test.c b/matrix-test.c index 2bd82232..bc9ec0ff 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -91,18 +91,19 @@ static uint32_t rainbowColors[180]; static void rainbow( uint32_t * const pixels, - unsigned num_leds, + unsigned width, + unsigned height, unsigned phaseShift, unsigned cycle ) { const unsigned color = cycle % 180; - for (unsigned x=0; x < num_leds; x++) { - for (unsigned y=0; y < 16; y++) { + for (unsigned x=0; x < width; x++) { + for (unsigned y=0; y < height; y++) { const int index = (color + x + y*phaseShift/2) % 180; const uint32_t in = rainbowColors[index]; - uint8_t * const out = &pixels[x + y*num_leds]; + uint8_t * const out = &pixels[x + y*width]; #if 1 out[0] = ((in >> 0) & 0xFF); // * y / 16; out[1] = ((in >> 8) & 0xFF); // * y / 16; @@ -123,8 +124,9 @@ rainbow( int main(void) { - const int num_pixels = 256; - ledscape_t * const leds = ledscape_init(num_pixels); + const int width = 256; + const int height = 64; + ledscape_t * const leds = ledscape_init(width, height); printf("init done\n"); time_t last_time = time(NULL); unsigned last_i = 0; @@ -139,17 +141,12 @@ main(void) } unsigned i = 0; + uint32_t * const p = calloc(width*height,4); + while (1) { - // Alternate frame buffers on each draw command - const unsigned frame_num = i++ % 2; - ledscape_frame_t * const frame - = ledscape_frame(leds, frame_num); - - uint32_t * const p = (void*) frame; - - rainbow(p, num_pixels, 10, i); - ledscape_draw(leds, frame_num); + rainbow(p, width, height, 10, i++); + ledscape_draw(leds, p); usleep(20000); // wait for the previous frame to finish; diff --git a/matrix.p b/matrix.p index c275f314..0f335c4d 100644 --- a/matrix.p +++ b/matrix.p @@ -170,35 +170,26 @@ /** Register map */ #define data_addr r0 -#define row_skip_bytes r1 -#define gpio0_base r2 -#define gpio1_base r3 -#define gpio2_base r4 -#define gpio3_base r9 -#define row r5 -#define offset r6 -#define scan r7 -#define display_width_bytes r8 -#define out_clr r10 // must be one less than out_set -#define out_set r11 -#define p2 r12 -#define bright r13 -#define gpio0_led_mask r14 -#define gpio1_led_mask r27 -#define gpio2_led_mask r15 -#define gpio3_led_mask r28 -#define gpio1_sel_mask r16 -#define pixel r17 -#define clock_pin r18 -#define latch_pin r19 -#define row11_ptr r20 -#define row12_ptr r21 -#define row21_ptr r22 -#define row22_ptr r23 -#define gpio0_set r24 -#define gpio1_set r25 -#define gpio2_set r26 -#define gpio3_set r29 +#define width r1 +#define row r2 +#define bright r3 +#define offset r4 +#define out_clr r5 // must be one less than out_set +#define out_set r6 +#define gpio0_set r6 // overloaded with out_set +#define gpio1_set r7 +#define gpio2_set r8 +#define gpio3_set r9 +#define gpio0_led_mask r10 +#define gpio1_led_mask r11 +#define gpio2_led_mask r13 +#define gpio3_led_mask r14 +#define clock_pin r15 +#define gpio0_base r16 +#define gpio1_base r17 +#define gpio2_base r18 +#define gpio3_base r19 +#define pixel_data r20 // the next 12 registers, too #define BRIGHT_STEP 32 @@ -209,10 +200,12 @@ SBBO clock_pin, gpio1_base, GPIO_CLRDATAOUT, 4; \ #define LATCH_HI \ - SBBO latch_pin, gpio1_base, GPIO_SETDATAOUT, 4; \ + MOV out_set, 1 << gpio1_latch; \ + SBBO out_set, gpio1_base, GPIO_SETDATAOUT, 4; \ #define LATCH_LO \ - SBBO latch_pin, gpio1_base, GPIO_CLRDATAOUT, 4; \ + MOV out_clr, 1 << gpio1_latch; \ + SBBO out_clr, gpio1_base, GPIO_CLRDATAOUT, 4; \ #define DISPLAY_OFF \ MOV out_set, 0; \ @@ -257,10 +250,6 @@ START: // handles the exit case if an invalid value is written to the start // start position. -#define DISPLAY_WIDTH 128 -#define DISPLAYS 2 -#define ROW_WIDTH (DISPLAYS * DISPLAY_WIDTH) - MOV bright, #0 MOV gpio0_base, GPIO0 @@ -268,8 +257,6 @@ START: MOV gpio2_base, GPIO2 MOV gpio3_base, GPIO3 - MOV gpio1_sel_mask, GPIO1_SEL_MASK - MOV gpio0_led_mask, 0 MOV gpio1_led_mask, 0 MOV gpio2_led_mask, 0 @@ -332,19 +319,12 @@ START: SET GPIO_MASK(g82_gpio), g82_pin SET GPIO_MASK(b82_gpio), b82_pin - MOV display_width_bytes, 4*DISPLAY_WIDTH - MOV row_skip_bytes, 4*8*ROW_WIDTH - - MOV clock_pin, 0 - MOV latch_pin, 0 - SET clock_pin, gpio1_clock - SET latch_pin, gpio1_latch + MOV clock_pin, 1 << gpio1_clock PWM_LOOP: // Load the pointer to the buffer from PRU DRAM into r0 and the - // length (in bytes-bit words) into r1. - // start command into r2 - LBCO data_addr, CONST_PRUDRAM, 0, 4 + // length (in pixels) into r1. + LBCO data_addr, CONST_PRUDRAM, 0, 8 // Wait for a non-zero command QBEQ PWM_LOOP, data_addr, #0 @@ -352,65 +332,69 @@ PWM_LOOP: // Command of 0xFF is the signal to exit QBEQ EXIT, data_addr, #0xFF - MOV offset, 0 - MOV row, 0 + // scale the width into number of bytes that we will read + // 16 outputs * 3 bytes per output +/******** + ADD offset, width, width + ADD offset, offset, width + LSL width, offset, 4 +*/ - // Store the pointers to each of the four outputs - ADD row11_ptr, data_addr, 0 - ADD row12_ptr, row11_ptr, row_skip_bytes - ADD row21_ptr, row11_ptr, display_width_bytes - ADD row22_ptr, row21_ptr, row_skip_bytes + MOV row, 0 ROW_LOOP: - // compute where we are in the image - MOV pixel, 0 + MOV offset, 0 + // compute where we are in the image PIXEL_LOOP: - MOV out_set, 0 CLOCK_HI + // Load the sixteen RGB outputs into + // consecutive registers, starting at pixel_data. + // This takes about 250 ns + LBBO pixel_data, data_addr, offset, 3*16 + MOV gpio0_set, 0 + MOV gpio1_set, 0 + MOV gpio2_set, 0 + MOV gpio3_set, 0 #define GPIO(R) CAT3(gpio,R,_set) - MOV gpio0_set, 0 - MOV gpio1_set, 0 - MOV gpio2_set, 0 - MOV gpio3_set, 0 - -#define OUTPUT_ROW(N) \ - LBBO p2, row##N##_ptr, offset, 4; \ - QBGE skip_r##N, p2.b0, bright; \ +#define OUTPUT_ROW(N,reg_r,reg_g,reg_b) \ + QBGE skip_r##N, reg_r, bright; \ SET GPIO(r##N##_gpio), r##N##_pin; \ skip_r##N: \ - QBGE skip_g##N, p2.b1, bright; \ + QBGE skip_g##N, reg_g, bright; \ SET GPIO(g##N##_gpio), g##N##_pin; \ skip_g##N: \ - QBGE skip_b##N, p2.b2, bright; \ + QBGE skip_b##N, reg_b, bright; \ SET GPIO(b##N##_gpio), b##N##_pin; \ skip_b##N: \ -#define OUTPUT_ROW2(P,N) \ - LBBO p2, row##P##_ptr, offset, 4; \ - QBGE skip_r##N, p2.b0, bright; \ - SET GPIO(r##N##_gpio), r##N##_pin; \ - skip_r##N: \ - QBGE skip_g##N, p2.b1, bright; \ - SET GPIO(g##N##_gpio), g##N##_pin; \ - skip_g##N: \ - QBGE skip_b##N, p2.b2, bright; \ - SET GPIO(b##N##_gpio), b##N##_pin; \ - skip_b##N: \ + OUTPUT_ROW(11, r20.b0, r20.b1, r20.b2) + OUTPUT_ROW(12, r20.b3, r21.b0, r21.b1) + OUTPUT_ROW(21, r21.b2, r21.b3, r22.b0) + OUTPUT_ROW(22, r22.b1, r22.b2, r22.b3) + + OUTPUT_ROW(31, r23.b0, r23.b1, r23.b2) + OUTPUT_ROW(32, r23.b3, r24.b0, r24.b1) + OUTPUT_ROW(41, r24.b2, r24.b3, r25.b0) + OUTPUT_ROW(42, r25.b1, r25.b2, r25.b3) + + OUTPUT_ROW(51, r26.b0, r26.b1, r26.b2) + OUTPUT_ROW(52, r26.b3, r27.b0, r27.b1) + OUTPUT_ROW(61, r27.b2, r27.b3, r28.b0) + OUTPUT_ROW(62, r28.b1, r28.b2, r28.b3) - OUTPUT_ROW(11) - OUTPUT_ROW(12) - OUTPUT_ROW(21) - OUTPUT_ROW(22) - OUTPUT_ROW2(11,81) - OUTPUT_ROW2(12,82) + OUTPUT_ROW(71, r29.b0, r29.b1, r29.b2) + OUTPUT_ROW(72, r29.b3, r30.b0, r30.b1) + OUTPUT_ROW(81, r30.b2, r30.b3, r31.b0) + OUTPUT_ROW(82, r31.b1, r31.b2, r31.b3) // All bits are configured; // the non-set ones will be cleared // We write 8 bytes since CLR and DATA are contiguous, // which will write both the 0 and 1 bits in the - // same instruction. + // same instruction. gpio0 and out_set are the same + // register, so they must be done first. AND out_set, gpio0_set, gpio0_led_mask XOR out_clr, out_set, gpio0_led_mask SBBO out_clr, gpio0_base, GPIO_CLRDATAOUT, 8 @@ -435,33 +419,32 @@ PWM_LOOP: // \todo: Test turning OE on and off every other, // every fourth, every eigth, etc pixel based on // the current brightness. -#if 1 - LSL p2, pixel, 1 +#if 0 + LSL out_sel, offset, 1 QBLT no_blank, bright, p2 DISPLAY_OFF no_blank: #endif - ADD offset, offset, 4 - ADD pixel, pixel, 1 -#if DISPLAY_WIDTH > 0xFF - MOV p2, DISPLAY_WIDTH - QBNE PIXEL_LOOP, pixel, p2 -#else - QBNE PIXEL_LOOP, pixel, DISPLAY_WIDTH -#endif + ADD offset, offset, 3*16 + QBNE PIXEL_LOOP, offset, width // Disable output before we latch and set the address // Unless we've just done a full image, in which case // we treat this as a dummy row and go back to the top DISPLAY_OFF +#ifdef fix_dim QBEQ NEXT_ROW, row, 8 +#endif LATCH_HI // set address; select pins in gpio1 are sequential + // xor with the select bit mask to set which ones should LSL out_set, row, gpio1_sel0 - XOR out_clr, out_set, gpio1_sel_mask + MOV out_clr, GPIO1_SEL_MASK + AND out_set, out_set, out_clr // ensure no extra bits + XOR out_clr, out_clr, out_set // complement the bits into clr SBBO out_clr, gpio1_base, GPIO_CLRDATAOUT, 8 // set both // We have clocked out all of the pixels for @@ -470,15 +453,17 @@ PWM_LOOP: LATCH_LO DISPLAY_ON - // We have drawn half the image on each chain; - // skip the second half - ADD offset, offset, display_width_bytes - ADD row, row, 1 + QBEQ LAST_ROW, row, 8 + + // Before going to the next row, increment our data_offset + // to the next row and reset our offset + ADD data_addr, data_addr, offset + MOV offset, 0 QBA ROW_LOOP -NEXT_ROW: - // We have clocked out all of the panels. +LAST_ROW: + // We have clocked out this row to all of the panels. // Celebrate and go back to the PWM loop // Limit brightness to 0..MAX_BRIGHT ADD bright, bright, BRIGHT_STEP From e937a81a01a8ccd514c612d783e021a2dab024d7 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 31 Dec 1999 21:30:24 -0500 Subject: [PATCH 133/332] draw a identifying text on each panel --- identify | 71 +++++++++++++++++++++++++++---------------------- matrix-udp-rx.c | 13 +++------ 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/identify b/identify index dd28a9bf..0a70717b 100755 --- a/identify +++ b/identify @@ -1,32 +1,39 @@ -#!/usr/bin/perl -use warnings; -use strict; - -# Make a bargraph to help identify which port is which -# R Y G C B W - -my $width = 10; -my $height = 32; - -my $s = '1'; - -for(my $y = 0 ; $y < $height ; $y++) -{ - for(my $x = 0 ; $x < $width ; $x++) - { - my $v = ($y % 8) >= $x ? 0x10 : 0; - my $r = 0; - my $g = 0; - my $b = 0; - $r = $v if int($y / 8) == 0; - $g = $v if int($y / 8) == 1; - $b = $v if int($y / 8) == 2; - $g = $r = $v if int($y / 8) == 3; - - $s .= chr($r); - $s .= chr($g); - $s .= chr($b); - } -} - -print $s; +#!/usr/bin/python +# Draw an image with PIl that has the coordinates +# in flashing colors +# +import Image, ImageFont, ImageDraw +import socket +import time, datetime +from colorsys import hsv_to_rgb + +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +dest = ("localhost", 9999) + +#print im.format, im.size, im.mode +# use a truetype font +font = ImageFont.truetype("pf_tempesta_seven.ttf", 8) + +i = 0 +width = 256 +height = 64 +disp = Image.new("RGB", (width,height), "black") +disp_draw = ImageDraw.Draw(disp) + +def rainbow(i): + rgb = [int(x*256) for x in hsv_to_rgb(i/256.0,0.8,0.8)] + return (rgb[0],rgb[1],rgb[2]) + + +while True: + disp.paste("black", (0,0,width,height)) + + for x in range(0,width, 32): + for y in range(0,height, 16): + s = str(x) + "," + str(y) + disp_draw.text((x+2, y), s, font=font, fill=rainbow(i)) + + # Send it to the drawing server + sock.sendto(chr(1) + disp.tostring(), dest) + i = (i+1) % width + time.sleep(0.025) diff --git a/matrix-udp-rx.c b/matrix-udp-rx.c index 848aec41..5f328f1e 100644 --- a/matrix-udp-rx.c +++ b/matrix-udp-rx.c @@ -25,9 +25,6 @@ #include "bitslice.h" #include "ledscape.h" -static int port = 9999; -static unsigned width = 16; -static unsigned height = 256; static int udp_socket( @@ -62,7 +59,7 @@ main( die("socket port %d failed: %s\n", port, strerror(errno)); const unsigned width = 256; - const unsigned height = 16; + const unsigned height = 64; const size_t image_size = width * height * 3; // largest possible UDP packet @@ -72,13 +69,14 @@ main( fprintf(stderr, "%u x %u, UDP port %u\n", width, height, port); - ledscape_t * const leds = ledscape_init(width); + ledscape_t * const leds = ledscape_init(width, height); const unsigned report_interval = 10; unsigned last_report = 0; unsigned long delta_sum = 0; unsigned frames = 0; + uint32_t * const fb = calloc(width*128,4); while (1) { @@ -119,9 +117,6 @@ main( gettimeofday(&start_tv, NULL); const unsigned frame_num = 0; - ledscape_frame_t * const frame - = ledscape_frame(leds, frame_num); - uint32_t * const fb = (void*) frame; for (unsigned x = 0 ; x < width ; x++) { @@ -136,7 +131,7 @@ main( } } - ledscape_draw(leds, frame_num); + ledscape_draw(leds, fb); gettimeofday(&stop_tv, NULL); timersub(&stop_tv, &start_tv, &delta_tv); From 05cabfeb3fd06b1619b455cf61dbbd557b38ec8b Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 31 Dec 1999 21:31:26 -0500 Subject: [PATCH 134/332] disable output during low-brightness stages --- matrix-test.c | 19 +++++++++++++++++++ matrix.p | 6 +++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/matrix-test.c b/matrix-test.c index bc9ec0ff..7af7ca42 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -121,6 +121,24 @@ rainbow( } +static void +gradient( + uint32_t * const pixels, + unsigned width, + unsigned height, + unsigned phaseShift, + unsigned cycle +) +{ + cycle >>= 3; + for (unsigned x=0; x < width; x++) { + for (unsigned y=0; y < height; y++) { + uint8_t * const out = &pixels[x + y*width]; + out[2] = 0x80 * (1 & (((x+cycle) >> 2) ^ ((y+cycle) >> 2))); + } + } +} + int main(void) { @@ -146,6 +164,7 @@ main(void) while (1) { rainbow(p, width, height, 10, i++); + //gradient(p, width, height, 10, i++); ledscape_draw(leds, p); usleep(20000); diff --git a/matrix.p b/matrix.p index 0f335c4d..509d21a9 100644 --- a/matrix.p +++ b/matrix.p @@ -419,10 +419,10 @@ PWM_LOOP: // \todo: Test turning OE on and off every other, // every fourth, every eigth, etc pixel based on // the current brightness. -#if 0 - LSL out_sel, offset, 1 +#if 1 + LSR out_set, offset, 2 - QBLT no_blank, bright, p2 + QBLT no_blank, bright, out_set DISPLAY_OFF no_blank: #endif From c85611ec485c915f04e1eda60e7e9ae159092426 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 31 Dec 1999 19:20:18 -0500 Subject: [PATCH 135/332] fix bright rows 7 and 15. adjust brightness scaling --- matrix-test.c | 12 +++++++++--- matrix.p | 8 +++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/matrix-test.c b/matrix-test.c index 7af7ca42..591bd1ab 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -134,7 +134,11 @@ gradient( for (unsigned x=0; x < width; x++) { for (unsigned y=0; y < height; y++) { uint8_t * const out = &pixels[x + y*width]; - out[2] = 0x80 * (1 & (((x+cycle) >> 2) ^ ((y+cycle) >> 2))); + //out[0] = ((x+cycle) % 32) * 8; + //out[1] = ((y+cycle) % 16) * 16; + out[0] = ((x+y+cycle) % 32) * 8; + out[1] = ((x+y+cycle) % 32) * 8; + out[2] = ((x+y+cycle) % 32) * 8; } } } @@ -163,8 +167,10 @@ main(void) while (1) { - rainbow(p, width, height, 10, i++); - //gradient(p, width, height, 10, i++); + if (1) + rainbow(p, width, height, 10, i++); + else + gradient(p, width, height, 10, i++); ledscape_draw(leds, p); usleep(20000); diff --git a/matrix.p b/matrix.p index 509d21a9..30f7d2f4 100644 --- a/matrix.p +++ b/matrix.p @@ -420,7 +420,7 @@ PWM_LOOP: // every fourth, every eigth, etc pixel based on // the current brightness. #if 1 - LSR out_set, offset, 2 + LSR out_set, offset, 1 QBLT no_blank, bright, out_set DISPLAY_OFF @@ -434,9 +434,7 @@ PWM_LOOP: // Unless we've just done a full image, in which case // we treat this as a dummy row and go back to the top DISPLAY_OFF -#ifdef fix_dim - QBEQ NEXT_ROW, row, 8 -#endif + QBEQ LAST_ROW, row, 8 LATCH_HI // set address; select pins in gpio1 are sequential @@ -454,7 +452,7 @@ PWM_LOOP: DISPLAY_ON ADD row, row, 1 - QBEQ LAST_ROW, row, 8 + //QBEQ LAST_ROW, row, 8 // Before going to the next row, increment our data_offset // to the next row and reset our offset From e7b1f17e919b3b93213f21633d2d3a8766142fce Mon Sep 17 00:00:00 2001 From: root Date: Sun, 20 Apr 2014 17:22:00 +0000 Subject: [PATCH 136/332] tweak parameters a bit --- src/perlin/pattern.cpp | 12 ++++++------ src/perlin/perlin-ledscape.cpp | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/perlin/pattern.cpp b/src/perlin/pattern.cpp index bd0fee54..f2a21c28 100644 --- a/src/perlin/pattern.cpp +++ b/src/perlin/pattern.cpp @@ -54,9 +54,9 @@ uint32_t Pattern::translateHue (int32_t hue) case 5: r = 0xff, g = 0xff-lo, b = 0; break; } //printf("hue=%d=%d,%d: %d,%d,%d\n", hue, hi, lo, r, g, b); - r = gammaLut[r] << 3; - g = gammaLut[g] << 3; - b = gammaLut[b] << 3; + //r = gammaLut[r] << 3; + //g = gammaLut[g] << 3; + //b = gammaLut[b] << 3; #else b = hue; r = 0; @@ -98,9 +98,9 @@ uint32_t Pattern::translateHueValue (int32_t hue, float value) g = ((float)g + 0.5) * value; b = ((float)b + 0.5) * value; - r = gammaLut[r] << 4; - g = gammaLut[g] << 4; - b = gammaLut[b] << 4; + //r = gammaLut[r] << 4; + //g = gammaLut[g] << 4; + //b = gammaLut[b] << 4; return MAKE_COLOR (r,g,b); } diff --git a/src/perlin/perlin-ledscape.cpp b/src/perlin/perlin-ledscape.cpp index b0818657..f3503ed6 100644 --- a/src/perlin/perlin-ledscape.cpp +++ b/src/perlin/perlin-ledscape.cpp @@ -92,8 +92,8 @@ int main (int argc, char *argv[]) DISPLAY_WIDTH, DISPLAY_HEIGHT, 2, // mode - 3.0/64.0, // size of blobs: smaller value == larger blob - 1.0/64.0, // speed + 1.0/64.0, // size of blobs: smaller value == larger blob + 1/64.0, // speed 256.0, hue_options ); From 21565bbfd7c7be357a77f09fbbe8724a094e9fc0 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 1 Jan 2000 00:21:05 +0000 Subject: [PATCH 137/332] run at boot on angstrom --- bin/ledscape.service | 8 +++++++- bin/run-ledscape | 8 +++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/bin/ledscape.service b/bin/ledscape.service index 8a91526f..a3a5f944 100755 --- a/bin/ledscape.service +++ b/bin/ledscape.service @@ -1,9 +1,15 @@ +# +# Copy this file to /etc/systemd/system/ and run: +# systemctl enable ledscape.service +# to enable LEDscape to start on each boot. +# + [Unit] Description=BeagleBone LED matrix driver [Service] WorkingDirectory=/home/root/LEDscape/ -ExecStart=/home/root/LEDscape/run-ledscape +ExecStart=/home/root/LEDscape/bin/run-ledscape KillMode=process [Install] diff --git a/bin/run-ledscape b/bin/run-ledscape index e311b61c..95b97f99 100755 --- a/bin/run-ledscape +++ b/bin/run-ledscape @@ -1,6 +1,8 @@ #!/bin/sh DIRNAME="`dirname "$0"`" -cd "$DIRNAME" +cd "$DIRNAME/.." -modprobe uio_pruss -exec ./matrix-test +echo CAPE-BONE-OCTO > /sys/devices/bone_capemgr.8/slots +sleep 4 + +exec ./bin/matrix-test From c17e2cab5fff15e0723e570ba72ac219068d52b7 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 1 Jan 2000 00:21:18 +0000 Subject: [PATCH 138/332] include all dep files --- Makefile.common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.common b/Makefile.common index d52a2816..b593402c 100644 --- a/Makefile.common +++ b/Makefile.common @@ -119,7 +119,7 @@ $(foreach O,$(LIB-y),\ .PHONY: clean # Include all of the generated dependency files --include .*.o.d +-include $(OBJDIR)/.*.o.d clean: rm -rf \ From 85a3d4c64042d7717086e23d53b193df76649487 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 31 Dec 1999 19:24:10 -0500 Subject: [PATCH 139/332] fix fire drawing on the entire image --- fire.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fire.c b/fire.c index 0a9c24f7..f602df23 100644 --- a/fire.c +++ b/fire.c @@ -91,7 +91,7 @@ fire_draw( uint32_t * const frame ) { - memset(frame, 0, w*16*sizeof(*frame)); + memset(frame, 0, w*h*sizeof(*frame)); angle = angle + 0.05; @@ -123,8 +123,7 @@ fire_draw( if (((c >> 0) & 0xFF) == 128) fire[x][y] = 128; - if (y > 1 && y < 2 + 16) - frame[counter++] = c; + frame[counter++] = c; } } } From 19b3dee519bf8075d1c41066b05c971ad3ac934d Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 31 Dec 1999 21:26:23 -0500 Subject: [PATCH 140/332] double buffer the display --- ledscape.c | 51 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/ledscape.c b/ledscape.c index fc99c97c..e461f636 100644 --- a/ledscape.c +++ b/ledscape.c @@ -90,8 +90,9 @@ struct ledscape { ws281x_command_t * ws281x; pru_t * pru; - unsigned width;; - unsigned height;; + unsigned width; + unsigned height; + unsigned frame_size; led_matrix_config_t * matrix; }; @@ -112,6 +113,15 @@ ledscape_frame( #endif +static uint8_t +bright_map( + uint8_t val +) +{ + return val; +} + + /** Translate the RGBA buffer to the correct output type and * initiate the transfer of a frame to the LED strips. * @@ -123,9 +133,9 @@ ledscape_draw( const void * const buffer ) { - unsigned int frame = 0; + static unsigned frame = 0; const uint32_t * const in = buffer; - uint8_t * const out = leds->pru->ddr; // + leds->frame_size * frame; + uint8_t * const out = leds->pru->ddr + leds->frame_size * frame; #if 1 // matrix packed is: @@ -147,9 +157,9 @@ ledscape_draw( { const uint8_t * const rgb = (const void*) &in_row[x + m->x_offset]; uint8_t * const out_rgb = &out_row[(i + x * NUM_MATRIX)*3]; - out_rgb[0] = rgb[0]; - out_rgb[1] = rgb[1]; - out_rgb[2] = rgb[2]; + out_rgb[0] = bright_map(rgb[0]); + out_rgb[1] = bright_map(rgb[1]); + out_rgb[2] = bright_map(rgb[2]); } } } @@ -161,7 +171,8 @@ ledscape_draw( out[6] = 0x00; out[7] = 0x00; out[8] = 0x80; #endif - leds->ws281x->pixels_dma = leds->pru->ddr_addr; // + leds->frame_size * frame; + leds->ws281x->pixels_dma = leds->pru->ddr_addr + leds->frame_size * frame; + frame = (frame + 1) & 1; #if 0 // Wait for any current command to have been acknowledged while (leds->ws281x->command) @@ -199,9 +210,9 @@ ledscape_init( ) { pru_t * const pru = pru_init(0); -#if 0 - const size_t frame_size = num_pixels * 16 * 3; //LEDSCAPE_NUM_STRIPS * 4; + const size_t frame_size = 16 * 8 * width * 3; //LEDSCAPE_NUM_STRIPS * 4; +#if 0 if (2 *frame_size > pru->ddr_size) die("Pixel data needs at least 2 * %zu, only %zu in DDR\n", frame_size, @@ -216,6 +227,7 @@ ledscape_init( .width = width, .height = height, .ws281x = pru->data_ram, + .frame_size = frame_size, .matrix = calloc(sizeof(*leds->matrix), 1), }; @@ -223,6 +235,7 @@ ledscape_init( .matrix_width = 128, .matrix_height = 8, .matrix = { +#if 1 { 0, 0 }, { 0, 8 }, { 0, 16 }, @@ -239,6 +252,24 @@ ledscape_init( { 128, 40 }, { 128, 48 }, { 128, 56 }, +#else + { 0, 0 }, + { 0, 8 }, + { 0, 0 }, + { 0, 8 }, + { 0, 0 }, + { 0, 8 }, + { 0, 0 }, + { 0, 8 }, + { 0, 0 }, + { 0, 8 }, + { 0, 0 }, + { 0, 8 }, + { 0, 0 }, + { 0, 8 }, + { 0, 0 }, + { 0, 8 }, +#endif }, }; From 8f42181ec82e95ef09018a0cc8bf673628187166 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 31 Dec 1999 21:27:02 -0500 Subject: [PATCH 141/332] change scan order to fully draw one row at all brightnesses before moving to the next --- matrix.p | 95 ++++++++++++++++++++++++++------------------------------ 1 file changed, 44 insertions(+), 51 deletions(-) diff --git a/matrix.p b/matrix.p index 30f7d2f4..34f4096e 100644 --- a/matrix.p +++ b/matrix.p @@ -191,7 +191,7 @@ #define gpio3_base r19 #define pixel_data r20 // the next 12 registers, too -#define BRIGHT_STEP 32 +#define BRIGHT_STEP 16 #define CLOCK_LO \ SBBO clock_pin, gpio1_base, GPIO_SETDATAOUT, 4; \ @@ -208,13 +208,11 @@ SBBO out_clr, gpio1_base, GPIO_CLRDATAOUT, 4; \ #define DISPLAY_OFF \ - MOV out_set, 0; \ - SET out_set, gpio1_oe; \ + MOV out_set, 1 << gpio1_oe; \ SBBO out_set, gpio1_base, GPIO_SETDATAOUT, 4; \ #define DISPLAY_ON \ - MOV out_set, 0; \ - SET out_set, gpio1_oe; \ + MOV out_set, 1 << gpio1_oe; \ SBBO out_set, gpio1_base, GPIO_CLRDATAOUT, 4; \ @@ -250,8 +248,6 @@ START: // handles the exit case if an invalid value is written to the start // start position. - MOV bright, #0 - MOV gpio0_base, GPIO0 MOV gpio1_base, GPIO1 MOV gpio2_base, GPIO2 @@ -321,13 +317,13 @@ START: MOV clock_pin, 1 << gpio1_clock -PWM_LOOP: +READ_LOOP: // Load the pointer to the buffer from PRU DRAM into r0 and the // length (in pixels) into r1. LBCO data_addr, CONST_PRUDRAM, 0, 8 // Wait for a non-zero command - QBEQ PWM_LOOP, data_addr, #0 + QBEQ READ_LOOP, data_addr, #0 // Command of 0xFF is the signal to exit QBEQ EXIT, data_addr, #0xFF @@ -342,17 +338,35 @@ PWM_LOOP: MOV row, 0 - ROW_LOOP: +NEW_ROW_LOOP: + // Disable output while we set the address + DISPLAY_OFF + + // set address; select pins in gpio1 are sequential + // xor with the select bit mask to set which ones should + LSL out_set, row, gpio1_sel0 + MOV out_clr, GPIO1_SEL_MASK + AND out_set, out_set, out_clr // ensure no extra bits + XOR out_clr, out_clr, out_set // complement the bits into clr + SBBO out_clr, gpio1_base, GPIO_CLRDATAOUT, 8 // set both + + MOV bright, 0x100 + ROW_LOOP: + // Re-start reading at the same row MOV offset, 0 + // Reset the latch pin; will be toggled at the end of the row + LATCH_LO + // compute where we are in the image PIXEL_LOOP: - CLOCK_HI - // Load the sixteen RGB outputs into // consecutive registers, starting at pixel_data. // This takes about 250 ns LBBO pixel_data, data_addr, offset, 3*16 + + CLOCK_HI + MOV gpio0_set, 0 MOV gpio1_set, 0 MOV gpio2_set, 0 @@ -413,16 +427,15 @@ PWM_LOOP: CLOCK_LO +#if 1 // If the brightness is less than the pixel, turn off // but keep in mind that this is the brightness of // the previous row, not this one. - // \todo: Test turning OE on and off every other, - // every fourth, every eigth, etc pixel based on - // the current brightness. -#if 1 - LSR out_set, offset, 1 + LSR out_set, offset, 0 + ADD out_clr, bright, 10 + LSL out_clr, out_clr, 4 - QBLT no_blank, bright, out_set + QBLT no_blank, out_clr, out_set DISPLAY_OFF no_blank: #endif @@ -430,44 +443,24 @@ PWM_LOOP: ADD offset, offset, 3*16 QBNE PIXEL_LOOP, offset, width - // Disable output before we latch and set the address - // Unless we've just done a full image, in which case - // we treat this as a dummy row and go back to the top - DISPLAY_OFF - QBEQ LAST_ROW, row, 8 + // Full data has been clocked out; latch it LATCH_HI - - // set address; select pins in gpio1 are sequential - // xor with the select bit mask to set which ones should - LSL out_set, row, gpio1_sel0 - MOV out_clr, GPIO1_SEL_MASK - AND out_set, out_set, out_clr // ensure no extra bits - XOR out_clr, out_clr, out_set // complement the bits into clr - SBBO out_clr, gpio1_base, GPIO_CLRDATAOUT, 8 // set both - - // We have clocked out all of the pixels for - // this row and the one eigth rows later. - // Latch the display register and then turn the display on - LATCH_LO DISPLAY_ON - ADD row, row, 1 - //QBEQ LAST_ROW, row, 8 + // Update the brightness, and then give the row another scan + SUB bright, bright, BRIGHT_STEP + QBLT ROW_LOOP, bright, 0 - // Before going to the next row, increment our data_offset - // to the next row and reset our offset + // We have just done all eight brightness levels for this + // row. Time to move to the new row + + // Increment our data_offset to point to the next row ADD data_addr, data_addr, offset - MOV offset, 0 - QBA ROW_LOOP - -LAST_ROW: - // We have clocked out this row to all of the panels. - // Celebrate and go back to the PWM loop - // Limit brightness to 0..MAX_BRIGHT - ADD bright, bright, BRIGHT_STEP - AND bright, bright, 0xFF - - QBA PWM_LOOP + + ADD row, row, 1 + QBEQ READ_LOOP, row, 8 + + QBA NEW_ROW_LOOP EXIT: #ifdef AM33XX From 1b8fd7a2a147fd93d44570ec1e7094e123f77f9f Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 31 Dec 1999 21:27:22 -0500 Subject: [PATCH 142/332] more test to demonstate various ghosting bugs --- matrix-test.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/matrix-test.c b/matrix-test.c index 591bd1ab..9af09343 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -101,7 +101,7 @@ rainbow( for (unsigned x=0; x < width; x++) { for (unsigned y=0; y < height; y++) { - const int index = (color + x + y*phaseShift/2) % 180; + const int index = (color + x + y*phaseShift/4) % 180; const uint32_t in = rainbowColors[index]; uint8_t * const out = &pixels[x + y*width]; #if 1 @@ -134,11 +134,17 @@ gradient( for (unsigned x=0; x < width; x++) { for (unsigned y=0; y < height; y++) { uint8_t * const out = &pixels[x + y*width]; +#if 0 //out[0] = ((x+cycle) % 32) * 8; //out[1] = ((y+cycle) % 16) * 16; - out[0] = ((x+y+cycle) % 32) * 8; - out[1] = ((x+y+cycle) % 32) * 8; - out[2] = ((x+y+cycle) % 32) * 8; + uint8_t b = 0xFF; + out[1] = b * ((((x + y + cycle) >> 5) ) & 1); +#else + uint8_t b = ((x+y+cycle) % 32) * 8; + out[0] = b * ((((x + y + cycle) >> 5) % 3) & 1); + out[1] = b * ((((x + y + cycle) >> 5) % 5) & 1); + out[2] = b * ((((x + y + cycle) >> 5) % 7) & 1); +#endif } } } From 36297c4853474a2795f08dbbc6392f37eb35da43 Mon Sep 17 00:00:00 2001 From: vmpn Date: Fri, 18 Oct 2013 00:36:44 -0400 Subject: [PATCH 143/332] Use ns parameter in WAITNS macro I think you meant to use "ns" where you used "lab" --- ws281x.p | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ws281x.p b/ws281x.p index 90672edb..175a29a0 100644 --- a/ws281x.p +++ b/ws281x.p @@ -191,9 +191,9 @@ lab: LBBO r9, r8, 0xC, 4 // read the cycle counter SUB r9, r9, sleep_counter #ifdef CONFIG_WS2812 - QBGT lab, r9, 2*(lab)/5 + QBGT lab, r9, 2*(ns)/5 #else - QBGT lab, r9, (lab)/5 + QBGT lab, r9, (ns)/5 #endif .endm From d7a81579fc9207e4920690d3d48d9874090a07cc Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 1 Jan 2000 00:40:14 +0000 Subject: [PATCH 144/332] adapt to work with LED strips again --- ledscape.c | 68 ++++++++++++++++++++++++++------------------------- matrix-test.c | 4 +-- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/ledscape.c b/ledscape.c index e461f636..1fa20805 100644 --- a/ledscape.c +++ b/ledscape.c @@ -12,6 +12,8 @@ #include "ledscape.h" #include "pru.h" +#undef CONFIG_LED_MATRIX + /** GPIO pins used by the LEDscape. * @@ -137,7 +139,7 @@ ledscape_draw( const uint32_t * const in = buffer; uint8_t * const out = leds->pru->ddr + leds->frame_size * frame; -#if 1 +#ifdef CONFIG_LED_MATRIX // matrix packed is: // p(0,0)p(0,8)p(64,0)p(64,8).... // this way the PRU can read all sixteen output pixels in @@ -163,21 +165,29 @@ ledscape_draw( } } } -#else - static int i = 0; - memset(out, i++, leds->width *leds->height * 3); - out[0] = 0x80; out[1] = 0x00; out[2] = 0x00; - out[3] = 0x00; out[4] = 0x80; out[5] = 0x00; - out[6] = 0x00; out[7] = 0x00; out[8] = 0x80; -#endif - leds->ws281x->pixels_dma = leds->pru->ddr_addr + leds->frame_size * frame; frame = (frame + 1) & 1; -#if 0 +#else + // Translate the RGBA frame into RGBA + // only 32 outputs currentl supported + for (unsigned y = 0 ; y < 32 ; y++) + { + const uint32_t * const row_in = &in[y*leds->width]; + for (unsigned x = 0 ; x < leds->width ; x++) + { + uint32_t * const row_out = (uint32_t*) &out[x*32*4]; + row_out[y] = in[x]; + } + } + // Wait for any current command to have been acknowledged while (leds->ws281x->command) ; + // Update the pixel data and send the start + leds->ws281x->pixels_dma = leds->pru->ddr_addr + leds->frame_size * frame; + frame = (frame + 1) & 1; + // Send the start command leds->ws281x->command = 1; #endif @@ -231,11 +241,11 @@ ledscape_init( .matrix = calloc(sizeof(*leds->matrix), 1), }; +#ifdef CONFIG_LED_MATRIX *(leds->matrix) = (led_matrix_config_t) { .matrix_width = 128, .matrix_height = 8, .matrix = { -#if 1 { 0, 0 }, { 0, 8 }, { 0, 16 }, @@ -252,24 +262,6 @@ ledscape_init( { 128, 40 }, { 128, 48 }, { 128, 56 }, -#else - { 0, 0 }, - { 0, 8 }, - { 0, 0 }, - { 0, 8 }, - { 0, 0 }, - { 0, 8 }, - { 0, 0 }, - { 0, 8 }, - { 0, 0 }, - { 0, 8 }, - { 0, 0 }, - { 0, 8 }, - { 0, 0 }, - { 0, 8 }, - { 0, 0 }, - { 0, 8 }, -#endif }, }; @@ -279,6 +271,15 @@ ledscape_init( .command = 0, .response = 0, }; +#else + // LED strips, not matrix output + *(leds->ws281x) = (ws281x_command_t) { + .pixels_dma = 0, // will be set in draw routine + .num_pixels = width, + .command = 0, + .response = 0, + }; +#endif printf("%d\n", leds->ws281x->num_pixels); @@ -294,10 +295,11 @@ ledscape_init( pru_gpio(3, gpios3[i], 1, 0); // Initiate the PRU program - if (1) - pru_exec(pru, "./matrix.bin"); - else - pru_exec(pru, "./ws281x.bin"); +#ifdef CONFIG_LED_MATRIX + pru_exec(pru, "./matrix.bin"); +#else + pru_exec(pru, "./ws281x.bin"); +#endif // Watch for a done response that indicates a proper startup // \todo timeout if it fails diff --git a/matrix-test.c b/matrix-test.c index 9af09343..3ee8d53b 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -152,8 +152,8 @@ gradient( int main(void) { - const int width = 256; - const int height = 64; + const int width = 64; + const int height = 32; ledscape_t * const leds = ledscape_init(width, height); printf("init done\n"); time_t last_time = time(NULL); From 8613f2bff4e009cf29efa72fad2be5b3aa9fe32d Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 1 Jan 2000 00:38:34 +0000 Subject: [PATCH 145/332] 48 outputs of ws281x using the same slicing technique as the matrix code --- ledscape.c | 14 +- matrix-test.c | 2 +- ws281x.p | 382 ++++++++++++++++++++++++++++++-------------------- 3 files changed, 237 insertions(+), 161 deletions(-) diff --git a/ledscape.c b/ledscape.c index 1fa20805..70fe9584 100644 --- a/ledscape.c +++ b/ledscape.c @@ -168,15 +168,19 @@ ledscape_draw( leds->ws281x->pixels_dma = leds->pru->ddr_addr + leds->frame_size * frame; frame = (frame + 1) & 1; #else - // Translate the RGBA frame into RGBA - // only 32 outputs currentl supported - for (unsigned y = 0 ; y < 32 ; y++) + // Translate the RGBA frame into G R B, sliced by color + // only 48 outputs currently supported + const unsigned height = 48; + for (unsigned y = 0 ; y < height ; y++) { const uint32_t * const row_in = &in[y*leds->width]; for (unsigned x = 0 ; x < leds->width ; x++) { - uint32_t * const row_out = (uint32_t*) &out[x*32*4]; - row_out[y] = in[x]; + uint8_t * const row_out = &out[x*height*3 + y]; + const uint32_t p = row_in[x]; + row_out[0*height] = (p >> 8) & 0xFF; // green + row_out[1*height] = (p >> 0) & 0xFF; // red + row_out[2*height] = (p >> 16) & 0xFF; // blue } } diff --git a/matrix-test.c b/matrix-test.c index 3ee8d53b..72bbc15e 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -153,7 +153,7 @@ int main(void) { const int width = 64; - const int height = 32; + const int height = 48; ledscape_t * const leds = ledscape_init(width, height); printf("init done\n"); time_t last_time = time(NULL); diff --git a/ws281x.p b/ws281x.p index 175a29a0..85260a3e 100644 --- a/ws281x.p +++ b/ws281x.p @@ -45,98 +45,118 @@ //* //*/ -// Pins available in GPIO0 -#define gpio0_bit0 2 -#define gpio0_bit1 3 -#define gpio0_bit2 4 -#define gpio0_bit3 5 -#define gpio0_bit4 7 -#define gpio0_bit5 12 -#define gpio0_bit6 13 -#define gpio0_bit7 14 -#define gpio0_bit8 15 -#define gpio0_bit9 20 -#define gpio0_bit10 22 -#define gpio0_bit11 23 -#define gpio0_bit12 26 -#define gpio0_bit13 27 -#define gpio0_bit14 30 -#define gpio0_bit15 31 - -// Pins available in GPIO1 -#define gpio1_bit0 12 -#define gpio1_bit1 13 -#define gpio1_bit2 14 -#define gpio1_bit3 15 -#define gpio1_bit4 16 -#define gpio1_bit5 17 -#define gpio1_bit6 18 -#define gpio1_bit7 19 -#define gpio1_bit8 28 -#define gpio1_bit9 29 - -// Pins in GPIO2 -#define gpio2_bit0 1 -#define gpio2_bit1 2 -#define gpio2_bit2 3 -#define gpio2_bit3 4 -#define gpio2_bit4 5 - -// And the paltry pins in GPIO3 to give us 32 -#define gpio3_bit0 16 -#define gpio3_bit1 19 - -/** Generate a bitmask of which pins in GPIO0-3 are used. - * - * This is used to bring all the pins up for the start of - * the bit, and then back down at the end of the 1 bits. - * - * \todo wtf "parameter too long": only 128 chars allowed? - */ -#define GPIO0_LED_MASK (0\ -|(1< Date: Sat, 1 Jan 2000 00:50:31 +0000 Subject: [PATCH 146/332] receiver code works with ws281x --- matrix-udp-rx.c | 4 ++-- python-test | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/matrix-udp-rx.c b/matrix-udp-rx.c index 5f328f1e..b00c1303 100644 --- a/matrix-udp-rx.c +++ b/matrix-udp-rx.c @@ -59,7 +59,7 @@ main( die("socket port %d failed: %s\n", port, strerror(errno)); const unsigned width = 256; - const unsigned height = 64; + const unsigned height = 48; const size_t image_size = width * height * 3; // largest possible UDP packet @@ -76,7 +76,7 @@ main( unsigned long delta_sum = 0; unsigned frames = 0; - uint32_t * const fb = calloc(width*128,4); + uint32_t * const fb = calloc(width*height,4); while (1) { diff --git a/python-test b/python-test index b6d2d2cc..44f63201 100755 --- a/python-test +++ b/python-test @@ -18,8 +18,9 @@ font_sm = ImageFont.truetype("pf_tempesta_seven.ttf", 8) i = 0 width = 256 -disp = Image.new("RGB", (256,16), "black") -im = Image.new("RGB", (width,16), "black") +height = 48 +disp = Image.new("RGB", (width,height), "black") +im = Image.new("RGB", (width,height), "black") im_draw = ImageDraw.Draw(im) disp_draw = ImageDraw.Draw(disp) @@ -29,7 +30,7 @@ def rainbow(i): while True: - im.paste("black", (0,0,width,16)) + im.paste("black", (0,0,width,height)) now = datetime.datetime.now() d = now.strftime("%a %d %b %Y") t = now.strftime("%H:%M") @@ -38,8 +39,8 @@ while True: im_draw.text((0, -2), d, font=font, fill=rainbow(i)) # Make it scroll - disp.paste(im.crop((0,0,i,16)), (256-i,0)) - disp.paste(im.crop((i+1,0,255,16)), (0,0)) + disp.paste(im.crop((0,0,i,height)), (width-i,0)) + disp.paste(im.crop((i+1,0,width-1,height)), (0,0)) # draw the time on each face for x in range(0,7): From ab4f2353c34a6f9178c904b6c5971bab60f153d3 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 16 Mar 2014 01:53:43 +0000 Subject: [PATCH 147/332] fix r30/r31 overwrite bug --- matrix.p | 73 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/matrix.p b/matrix.p index 34a0203e..318af735 100644 --- a/matrix.p +++ b/matrix.p @@ -16,6 +16,13 @@ * To pause the redraw loop, write a NULL to the buffer pointer. * To shut down the PRU, write -1 to the buffer pointer. */ +#if 1 +#define MATRIX_HEIGHT 8 // 32x16 matrices +#else +#define MATRIX_HEIGHT 16 // 32x32 matrices +#endif + + #define r11_gpio 2 #define r11_pin 2 #define g11_gpio 2 @@ -65,8 +72,13 @@ #define b41_gpio 1 #define b41_pin 17 -#define r42_gpio 3 +#if 0 +#define r42_gpio 1 // if we want to use PRU r30 output on clock +#define r42_pin 19 +#else +#define r42_gpio 3 // if we use the boards as built #define r42_pin 21 +#endif #define g42_gpio 3 #define g42_pin 19 #define b42_gpio 0 @@ -185,21 +197,25 @@ #define gpio2_led_mask r13 #define gpio3_led_mask r14 #define bright_thresh r15 + +// the gpio2/3_base registers must be re-written after every +// read loop since the data is loaded into the 12 registers starting at r18 +// don't overwrite r30/r31! #define gpio0_base r16 #define gpio1_base r17 #define gpio2_base r18 #define gpio3_base r19 -#define pixel_data r20 // the next 12 registers, too - -#define BRIGHT_STEP 16 +#define pixel_data r18 // the next 12 registers, too; #define CLOCK_LO \ - MOV out_set, 1 << gpio1_clock; \ - SBBO out_set, gpio1_base, GPIO_SETDATAOUT, 4; \ + MOV out_clr, 1 << gpio1_clock; \ + SBBO out_clr, gpio1_base, GPIO_SETDATAOUT, 4; \ + //CLR r30,7 #define CLOCK_HI \ - MOV out_set, 1 << gpio1_clock; \ - SBBO out_set, gpio1_base, GPIO_CLRDATAOUT, 4; \ + MOV out_clr, 1 << gpio1_clock; \ + SBBO out_clr, gpio1_base, GPIO_CLRDATAOUT, 4; \ + //SET r30,7 #define LATCH_HI \ MOV out_set, 1 << gpio1_latch; \ @@ -368,6 +384,7 @@ NEW_ROW_LOOP: // This takes about 250 ns LBBO pixel_data, data_addr, offset, 3*16 + // toggle the clock CLOCK_HI MOV gpio0_set, 0 @@ -386,26 +403,31 @@ NEW_ROW_LOOP: SET GPIO(b##N##_gpio), b##N##_pin; \ skip_b##N: \ - OUTPUT_ROW(11, r20.b0, r20.b1, r20.b2) - OUTPUT_ROW(12, r20.b3, r21.b0, r21.b1) + OUTPUT_ROW(11, r18.b0, r18.b1, r18.b2) + OUTPUT_ROW(12, r18.b3, r19.b0, r19.b1) + + OUTPUT_ROW(21, r19.b2, r19.b3, r20.b0) + OUTPUT_ROW(22, r20.b1, r20.b2, r20.b3) - OUTPUT_ROW(21, r21.b2, r21.b3, r22.b0) - OUTPUT_ROW(22, r22.b1, r22.b2, r22.b3) + OUTPUT_ROW(31, r21.b0, r21.b1, r21.b2) + OUTPUT_ROW(32, r21.b3, r22.b0, r22.b1) + OUTPUT_ROW(41, r22.b2, r22.b3, r23.b0) + OUTPUT_ROW(42, r23.b1, r23.b2, r23.b3) - OUTPUT_ROW(31, r23.b0, r23.b1, r23.b2) - OUTPUT_ROW(32, r23.b3, r24.b0, r24.b1) - OUTPUT_ROW(41, r24.b2, r24.b3, r25.b0) - OUTPUT_ROW(42, r25.b1, r25.b2, r25.b3) + OUTPUT_ROW(51, r24.b0, r24.b1, r24.b2) + OUTPUT_ROW(52, r24.b3, r25.b0, r25.b1) + OUTPUT_ROW(61, r25.b2, r25.b3, r26.b0) + OUTPUT_ROW(62, r26.b1, r26.b2, r26.b3) - OUTPUT_ROW(51, r26.b0, r26.b1, r26.b2) - OUTPUT_ROW(52, r26.b3, r27.b0, r27.b1) - OUTPUT_ROW(61, r27.b2, r27.b3, r28.b0) - OUTPUT_ROW(62, r28.b1, r28.b2, r28.b3) + OUTPUT_ROW(71, r27.b0, r27.b1, r27.b2) + OUTPUT_ROW(72, r27.b3, r28.b0, r28.b1) + OUTPUT_ROW(81, r28.b2, r28.b3, r29.b0) + OUTPUT_ROW(82, r29.b1, r29.b2, r29.b3) - OUTPUT_ROW(71, r29.b0, r29.b1, r29.b2) - OUTPUT_ROW(72, r29.b3, r30.b0, r30.b1) - OUTPUT_ROW(81, r30.b2, r30.b3, r31.b0) - OUTPUT_ROW(82, r31.b1, r31.b2, r31.b3) + // reload the gpio*_base registers + // since we have overwritten them with our pixel data + MOV gpio2_base, GPIO2 + MOV gpio3_base, GPIO3 // All bits are configured; // the non-set ones will be cleared @@ -459,7 +481,6 @@ NEW_ROW_LOOP: DISPLAY_ON // Update the brightness, and then give the row another scan - //SUB bright, bright, BRIGHT_STEP SUB bright, bright, 1 LSR bright_thresh, bright_thresh, 1 QBLT ROW_LOOP, bright, 0 @@ -471,7 +492,7 @@ NEW_ROW_LOOP: ADD data_addr, data_addr, offset ADD row, row, 1 - QBEQ READ_LOOP, row, 16 + QBEQ READ_LOOP, row, MATRIX_HEIGHT QBA NEW_ROW_LOOP From 39810d5b72397ef38f6398f994f77b7d2e8b4d9b Mon Sep 17 00:00:00 2001 From: root Date: Sun, 16 Mar 2014 01:54:04 +0000 Subject: [PATCH 148/332] Fix gpio lines, switch back to 32x16 matrices --- ledscape.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/ledscape.c b/ledscape.c index 6a7985c3..c2b74df9 100644 --- a/ledscape.c +++ b/ledscape.c @@ -31,7 +31,7 @@ * \todo: Find a way to unify this with the defines in the .p file */ static const uint8_t gpios0[] = { - 23, 27, 22, 10, 9, 8, 26, 11, 30, 31, 5, 3, 20, 4, 2, 14, 7 + 23, 27, 22, 10, 9, 8, 26, 11, 30, 31, 5, 3, 20, 4, 2, 14, 7, 15 }; static const uint8_t gpios1[] = { @@ -293,29 +293,32 @@ ledscape_init( #ifdef CONFIG_LED_MATRIX *(leds->matrix) = (led_matrix_config_t) { - .matrix_width = 64, - .matrix_height = 16, + .matrix_width = 128, + .matrix_height = 8, .matrix = { { 0, 0 }, + { 0, 8 }, + { 0, 16 }, + { 0, 24 }, { 0, 32 }, + { 0, 40 }, + { 0, 48 }, + { 0, 56 }, { 0, 64 }, + { 0, 72 }, + { 0, 80 }, + { 0, 88 }, { 0, 96 }, - { 0, 112 }, + { 0, 104 }, - { 0, 0 }, - { 0, 8 }, - { 0, 16 }, - { 0, 24 }, - { 0, 32 }, - { 0, 40 }, - { 0, 48 }, - { 0, 56 }, + { 0, 112 }, + { 0, 120 }, }, }; From 1ca5a1a94641a95a6fbee0014ac0c89af428ebe4 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 16 Mar 2014 01:54:26 +0000 Subject: [PATCH 149/332] test pwm hardware in dts; not used yet --- cape-bone-octo.dts | 157 ++++++++++++++++++++++++++++++++------------- 1 file changed, 111 insertions(+), 46 deletions(-) diff --git a/cape-bone-octo.dts b/cape-bone-octo.dts index fcf36556..d8db6b59 100644 --- a/cape-bone-octo.dts +++ b/cape-bone-octo.dts @@ -1,5 +1,5 @@ -/* -* pru dts file BB-BONE-PRU-00A0.dts +/* +* pru dts file BB-BONE-PRU-00A0.dts * * Available outputs on pru 0 and their r30 pins: * p9.31: 0 @@ -16,18 +16,18 @@ gpio 1: 13, 15, 12, 14, 29, 16, 17, 28, 18, 19, gpio 2: 2, 5, 22, 23, 14, 12, 10, 8, 6, 3, 4, 1, 24, 25, 17, 16, 15, 13, 11, 9, 7, gpio 3: 21, 19, 15, 14, 17, 16 -*/ -/dts-v1/; -/plugin/; - -/ { - compatible = "ti,beaglebone", "ti,beaglebone-black"; - - /* identification */ - part-number = "BB-BONE-OCTO"; - version = "00A0"; - - exclusive-use = +*/ +/dts-v1/; +/plugin/; + +/ { + compatible = "ti,beaglebone", "ti,beaglebone-black"; + + /* identification */ + part-number = "BB-BONE-OCTO"; + version = "00A0"; + + exclusive-use = //gpio 0: 23, 27, 22, 10, 9, 8, 26, 11, 30, 31, 5, 3, 20, 4, 2, 14, 7 "P9.11", "P9.12", "P9.13", "P9.14", "P9.15", "P9.16", "P9.17", "P9.18", @@ -42,20 +42,23 @@ gpio 3: 21, 19, 15, 14, 17, 16 "P8.26", "P8.27", "P8.28", "P8.29", "P8.30", "P8.31", "P8.32", "P8.33", "P8.34", "P8.35", "P8.36", "P8.37", "P8.38", "P8.39", - "P8.40", "P8.41", "P8.42", "P8.43", "P8.44", "P8.45", "P8.46"; - - fragment@0 { - target = <&am33xx_pinmux>; - __overlay__ { + "P8.40", "P8.41", "P8.42", "P8.43", "P8.44", "P8.45", "P8.46", + + "pruss", + "ehrpwm1B"; + + fragment@0 { + target = <&am33xx_pinmux>; + __overlay__ { mygpio: pinmux_mygpio { - pinctrl-single,pins = < + pinctrl-single,pins = < // p9.11-18 0x070 0x7 0x078 0x7 0x074 0x7 0x048 0x7 0x040 0x7 - 0x04c 0x7 + 0x04c 0x7 // P9.16 could be PWM for output enable 0x15c 0x7 0x158 0x7 @@ -64,7 +67,8 @@ gpio 3: 21, 19, 15, 14, 17, 16 0x150 0x7 0x044 0x7 0x184 0x7 - 0x1AC 0x7 + //0x1AC 0x5 // PRU0 r30.7 for the clock line + 0x1AC 0x7 // GPIO 0x180 0x7 0x1A4 0x7 0x19C 0x7 @@ -115,27 +119,88 @@ gpio 3: 21, 19, 15, 14, 17, 16 0x0ac 0x7 0x0a0 0x7 0x0a4 0x7 - >; - }; - }; - }; - - fragment@1 { - target = <&ocp>; - __overlay__ { - test_helper: helper { - compatible = "bone-pinmux-helper"; - pinctrl-names = "default"; - pinctrl-0 = <&mygpio>; - status = "okay"; - }; - }; - }; - - fragment@2{ - target = <&pruss>; - __overlay__ { - status = "okay"; - }; - }; -}; + >; + }; + }; + }; + + fragment@1 { + target = <&ocp>; + __overlay__ { + test_helper: helper { + compatible = "bone-pinmux-helper"; + pinctrl-names = "default"; + pinctrl-0 = <&mygpio>; + status = "okay"; + }; + }; + }; + + fragment@2{ + target = <&pruss>; + __overlay__ { + status = "okay"; + }; + }; + +/* + // import of am335x_pwm-00A0.dts + // but pru can't write to pwm? + + fragment@3 { + target = <&epwmss0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@4 { + target = <&ehrpwm0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@5 { + target = <&ecap0>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@6 { + target = <&epwmss1>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@7 { + target = <&ehrpwm1>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@8 { + target = <&epwmss2>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@9 { + target = <&ehrpwm2>; + __overlay__ { + status = "okay"; + }; + }; + + fragment@10 { + target = <&ecap2>; + __overlay__ { + status = "okay"; + }; + }; +*/ +}; From fa61fcd1ffa5fd438296c58b0009f5bd054ec4c8 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 1 Jan 2000 01:31:56 +0000 Subject: [PATCH 150/332] a few more characters --- fonts/json2bmp | 35 +++++++++++++++++++++++++++++++++++ fonts/mta-sign.json | 6 +++++- 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100755 fonts/json2bmp diff --git a/fonts/json2bmp b/fonts/json2bmp new file mode 100755 index 00000000..a20e7fe0 --- /dev/null +++ b/fonts/json2bmp @@ -0,0 +1,35 @@ +#!/usr/bin/perl +use warnings; +use strict; + +local $/; +local $_ = <>; + +print <<""; +/** \file + * Generated font from json file output by + * http://www.pentacom.jp/pentacom/bitfontmaker2/ + */ +const uint16_t font[][16] = { + +while (m/"(\d+)":\[([\d,]+)\]/msgx) +{ + my $ord = $1; + my @bits = split /,/, $2; + + my $c = chr($ord); + $c = '\\\\' if $c eq '\\'; + printf "['%s'] = {\n", $c; + + for (@bits) + { + printf "\t0x%04x,\n", $_; + } + + print "},\n"; +} + +print <<""; +}; + +__END__ diff --git a/fonts/mta-sign.json b/fonts/mta-sign.json index f3996959..0dd4fd29 100644 --- a/fonts/mta-sign.json +++ b/fonts/mta-sign.json @@ -2,6 +2,7 @@ "35":[1920,8160,16368,30840,29496,62460,63740,62460,29496,30840,16368,8160,1920,0,0,0], "36":[1920,8160,16368,31224,30968,63868,63932,61500,31224,31224,16368,8160,1920,0,0,0], "37":[1920,8160,16368,28728,32568,65340,61500,62460,29496,30840,16368,8160,1920,0,0,0], +"42":[256,896,1984,3168,6960,16184,31804,14648,6448,3168,1984,896,256,0,0,0], "45":[0,0,0,0,0,0,0,124,0,0,0,0,0,0,0,0], "46":[0,0,0,0,0,0,0,0,0,0,12,12,0,0,0,0], "47":[0,0,0,504,496,480,496,440,284,12,0,0,0,0,0,0], @@ -31,9 +32,12 @@ "78":[0,396,412,444,508,492,492,460,396,396,396,396,0,0,0,0], "79":[0,240,504,408,780,780,780,780,780,408,504,240,0,0,0,0], "80":[0,124,252,204,204,252,124,12,12,12,12,12,0,0,0,0], -"81":[0,248,508,396,396,396,396,396,396,236,1020,888,0,0,0,0], +"81":[0,248,508,396,396,396,396,396,428,204,508,888,512,0,0,1], +"82":[0,252,508,396,396,508,252,204,396,396,396,396,0,0,0,0], "83":[0,248,508,396,396,60,248,448,396,396,508,248,0,0,0,0], +"84":[0,1020,1020,96,96,96,96,96,96,96,96,96,0,0,0,0], "85":[0,792,792,792,792,792,792,792,792,792,1016,496,0,0,0,0], +"86":[0,1548,1548,792,792,792,432,432,432,224,224,224,0,0,0,0], "87":[0,780,780,780,780,780,780,876,1020,1020,924,780,0,0,0,0], "92":[0,0,0,252,124,60,124,236,452,384,0,0,0,0,0,0], "94":[1920,8160,16368,30840,32568,65340,63548,62268,29496,30840,16368,8160,1920,0,0,0], From 7a414c1a5682e70f4bf054083c483684bd0a64f3 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 1 Jan 2000 01:40:55 +0000 Subject: [PATCH 151/332] started on a mta display program --- mta-font.c | 1212 ++++++++++++++++++++++++++++++++++++++++++++++++++++ mta-sign.c | 132 ++++++ 2 files changed, 1344 insertions(+) create mode 100644 mta-font.c create mode 100644 mta-sign.c diff --git a/mta-font.c b/mta-font.c new file mode 100644 index 00000000..cb466a17 --- /dev/null +++ b/mta-font.c @@ -0,0 +1,1212 @@ +/** ile + * Generated font from json file output by + * http://www.pentacom.jp/pentacom/bitfontmaker2/ + */ +const uint16_t font[][16] = { +['!'] = { + 0x0780, + 0x1fe0, + 0x3ff0, + 0x7cf8, + 0x7c78, + 0xfcfc, + 0xfcfc, + 0xfcfc, + 0x7cf8, + 0x7cf8, + 0x3ff0, + 0x1fe0, + 0x0780, + 0x0000, + 0x0000, + 0x0000, +}, +['#'] = { + 0x0780, + 0x1fe0, + 0x3ff0, + 0x7878, + 0x7338, + 0xf3fc, + 0xf8fc, + 0xf3fc, + 0x7338, + 0x7878, + 0x3ff0, + 0x1fe0, + 0x0780, + 0x0000, + 0x0000, + 0x0000, +}, +['$'] = { + 0x0780, + 0x1fe0, + 0x3ff0, + 0x79f8, + 0x78f8, + 0xf97c, + 0xf9bc, + 0xf03c, + 0x79f8, + 0x79f8, + 0x3ff0, + 0x1fe0, + 0x0780, + 0x0000, + 0x0000, + 0x0000, +}, +['%'] = { + 0x0780, + 0x1fe0, + 0x3ff0, + 0x7038, + 0x7f38, + 0xff3c, + 0xf03c, + 0xf3fc, + 0x7338, + 0x7878, + 0x3ff0, + 0x1fe0, + 0x0780, + 0x0000, + 0x0000, + 0x0000, +}, +['*'] = { + 0x0100, + 0x0380, + 0x07c0, + 0x0c60, + 0x1b30, + 0x3f38, + 0x7c3c, + 0x3938, + 0x1930, + 0x0c60, + 0x07c0, + 0x0380, + 0x0100, + 0x0000, + 0x0000, + 0x0000, +}, +['-'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x007c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['.'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x000c, + 0x000c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['/'] = { + 0x0000, + 0x0000, + 0x0000, + 0x01f8, + 0x01f0, + 0x01e0, + 0x01f0, + 0x01b8, + 0x011c, + 0x000c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['0'] = { + 0x0000, + 0x0078, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x0078, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['1'] = { + 0x0000, + 0x00e0, + 0x00f0, + 0x00d8, + 0x00cc, + 0x00c0, + 0x00c0, + 0x00c0, + 0x00c0, + 0x00c0, + 0x00c0, + 0x00c0, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['2'] = { + 0x0000, + 0x0078, + 0x00fc, + 0x00cc, + 0x00c0, + 0x00c0, + 0x0060, + 0x0070, + 0x0038, + 0x001c, + 0x00fc, + 0x00fc, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['3'] = { + 0x0000, + 0x0078, + 0x00fc, + 0x00cc, + 0x00c0, + 0x0070, + 0x0070, + 0x00c0, + 0x00c0, + 0x00cc, + 0x00fc, + 0x0078, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['4'] = { + 0x0000, + 0x0080, + 0x00c0, + 0x00e0, + 0x00f0, + 0x00d8, + 0x00cc, + 0x00fc, + 0x00fc, + 0x00c0, + 0x00c0, + 0x00c0, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['5'] = { + 0x0000, + 0x00fc, + 0x00fc, + 0x000c, + 0x000c, + 0x007c, + 0x00fc, + 0x00c0, + 0x00c0, + 0x00c0, + 0x00fc, + 0x007c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['6'] = { + 0x0000, + 0x0078, + 0x00fc, + 0x00cc, + 0x000c, + 0x007c, + 0x00fc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00fc, + 0x0078, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['7'] = { + 0x0000, + 0x00fc, + 0x00fc, + 0x00c0, + 0x0060, + 0x0060, + 0x0030, + 0x0030, + 0x0018, + 0x0018, + 0x000c, + 0x000c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['8'] = { + 0x0000, + 0x0078, + 0x00fc, + 0x00cc, + 0x00cc, + 0x0078, + 0x0078, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00fc, + 0x0078, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['9'] = { + 0x0000, + 0x0078, + 0x00fc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00fc, + 0x00f8, + 0x00c0, + 0x00cc, + 0x00fc, + 0x0078, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['<'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0020, + 0x0030, + 0x03f8, + 0x03fc, + 0x03f8, + 0x0030, + 0x0020, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['>'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0040, + 0x00c0, + 0x01fc, + 0x03fc, + 0x01fc, + 0x00c0, + 0x0040, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['@'] = { + 0x0780, + 0x1fe0, + 0x3ff0, + 0x7878, + 0x7338, + 0xf3fc, + 0xf9fc, + 0xfcfc, + 0x7e78, + 0x7038, + 0x3ff0, + 0x1fe0, + 0x0780, + 0x0000, + 0x0000, + 0x0000, +}, +['A'] = { + 0x0000, + 0x00e0, + 0x00e0, + 0x00e0, + 0x01b0, + 0x01b0, + 0x01b0, + 0x0318, + 0x03f8, + 0x03f8, + 0x060c, + 0x060c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['B'] = { + 0x0000, + 0x007c, + 0x00fc, + 0x00cc, + 0x00cc, + 0x007c, + 0x007c, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00fc, + 0x007c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['C'] = { + 0x0000, + 0x00f0, + 0x01f8, + 0x0398, + 0x010c, + 0x000c, + 0x000c, + 0x000c, + 0x010c, + 0x0398, + 0x01f8, + 0x00f0, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['D'] = { + 0x0000, + 0x007c, + 0x00fc, + 0x01cc, + 0x018c, + 0x018c, + 0x018c, + 0x018c, + 0x018c, + 0x01cc, + 0x00fc, + 0x007c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['E'] = { + 0x0000, + 0x01fc, + 0x01fc, + 0x000c, + 0x000c, + 0x01fc, + 0x01fc, + 0x000c, + 0x000c, + 0x000c, + 0x01fc, + 0x01fc, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['F'] = { + 0x0000, + 0x00fc, + 0x00fc, + 0x000c, + 0x000c, + 0x007c, + 0x007c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['G'] = { + 0x0000, + 0x00f0, + 0x01f8, + 0x0398, + 0x010c, + 0x000c, + 0x000c, + 0x03cc, + 0x03cc, + 0x0198, + 0x01f8, + 0x00f0, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['H'] = { + 0x0000, + 0x018c, + 0x018c, + 0x018c, + 0x018c, + 0x01fc, + 0x01fc, + 0x018c, + 0x018c, + 0x018c, + 0x018c, + 0x018c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['I'] = { + 0x0000, + 0x00fc, + 0x00fc, + 0x0030, + 0x0030, + 0x0030, + 0x0030, + 0x0030, + 0x0030, + 0x0030, + 0x00fc, + 0x00fc, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['L'] = { + 0x0000, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x03fc, + 0x03fc, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['N'] = { + 0x0000, + 0x018c, + 0x019c, + 0x01bc, + 0x01fc, + 0x01ec, + 0x01ec, + 0x01cc, + 0x018c, + 0x018c, + 0x018c, + 0x018c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['O'] = { + 0x0000, + 0x00f0, + 0x01f8, + 0x0198, + 0x030c, + 0x030c, + 0x030c, + 0x030c, + 0x030c, + 0x0198, + 0x01f8, + 0x00f0, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['P'] = { + 0x0000, + 0x007c, + 0x00fc, + 0x00cc, + 0x00cc, + 0x00fc, + 0x007c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['Q'] = { + 0x0000, + 0x00f8, + 0x01fc, + 0x018c, + 0x018c, + 0x018c, + 0x018c, + 0x018c, + 0x01ac, + 0x00cc, + 0x01fc, + 0x0378, + 0x0200, + 0x0000, + 0x0000, + 0x0001, +}, +['R'] = { + 0x0000, + 0x00fc, + 0x01fc, + 0x018c, + 0x018c, + 0x01fc, + 0x00fc, + 0x00cc, + 0x018c, + 0x018c, + 0x018c, + 0x018c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['S'] = { + 0x0000, + 0x00f8, + 0x01fc, + 0x018c, + 0x018c, + 0x003c, + 0x00f8, + 0x01c0, + 0x018c, + 0x018c, + 0x01fc, + 0x00f8, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['T'] = { + 0x0000, + 0x03fc, + 0x03fc, + 0x0060, + 0x0060, + 0x0060, + 0x0060, + 0x0060, + 0x0060, + 0x0060, + 0x0060, + 0x0060, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['U'] = { + 0x0000, + 0x0318, + 0x0318, + 0x0318, + 0x0318, + 0x0318, + 0x0318, + 0x0318, + 0x0318, + 0x0318, + 0x03f8, + 0x01f0, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['V'] = { + 0x0000, + 0x060c, + 0x060c, + 0x0318, + 0x0318, + 0x0318, + 0x01b0, + 0x01b0, + 0x01b0, + 0x00e0, + 0x00e0, + 0x00e0, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['W'] = { + 0x0000, + 0x030c, + 0x030c, + 0x030c, + 0x030c, + 0x030c, + 0x030c, + 0x036c, + 0x03fc, + 0x03fc, + 0x039c, + 0x030c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['\\'] = { + 0x0000, + 0x0000, + 0x0000, + 0x00fc, + 0x007c, + 0x003c, + 0x007c, + 0x00ec, + 0x01c4, + 0x0180, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['^'] = { + 0x0780, + 0x1fe0, + 0x3ff0, + 0x7878, + 0x7f38, + 0xff3c, + 0xf83c, + 0xf33c, + 0x7338, + 0x7878, + 0x3ff0, + 0x1fe0, + 0x0780, + 0x0000, + 0x0000, + 0x0000, +}, +['a'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0078, + 0x00fc, + 0x00cc, + 0x00f0, + 0x00fc, + 0x00cc, + 0x00fc, + 0x00d8, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['b'] = { + 0x0000, + 0x000c, + 0x000c, + 0x000c, + 0x007c, + 0x00fc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00fc, + 0x007c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['c'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0070, + 0x00f8, + 0x00cc, + 0x000c, + 0x000c, + 0x00cc, + 0x00f8, + 0x0070, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['d'] = { + 0x0000, + 0x00c0, + 0x00c0, + 0x00c0, + 0x00f8, + 0x00fc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00fc, + 0x00f8, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['e'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0078, + 0x00fc, + 0x00cc, + 0x00fc, + 0x000c, + 0x00cc, + 0x00fc, + 0x0078, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['f'] = { + 0x0000, + 0x0030, + 0x0038, + 0x0018, + 0x003c, + 0x003c, + 0x0018, + 0x0018, + 0x0018, + 0x0018, + 0x0018, + 0x0018, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['g'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x00d8, + 0x00fc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00fc, + 0x00d8, + 0x00c0, + 0x00cc, + 0x0078, + 0x0000, +}, +['h'] = { + 0x0000, + 0x000c, + 0x000c, + 0x000c, + 0x006c, + 0x00fc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['i'] = { + 0x0000, + 0x0018, + 0x0018, + 0x0000, + 0x0018, + 0x0018, + 0x0018, + 0x0018, + 0x0018, + 0x0018, + 0x003c, + 0x003c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['k'] = { + 0x0000, + 0x000c, + 0x000c, + 0x000c, + 0x00cc, + 0x006c, + 0x003c, + 0x007c, + 0x006c, + 0x006c, + 0x00cc, + 0x00cc, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['l'] = { + 0x0000, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['m'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x077c, + 0x0ffc, + 0x0ccc, + 0x0ccc, + 0x0ccc, + 0x0ccc, + 0x0ccc, + 0x0ccc, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['n'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x007c, + 0x00fc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['o'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0078, + 0x00fc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00fc, + 0x0078, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['p'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x003c, + 0x007c, + 0x006c, + 0x006c, + 0x006c, + 0x006c, + 0x007c, + 0x003c, + 0x000c, + 0x000c, + 0x000c, + 0x0000, +}, +['r'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0038, + 0x007c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x000c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['s'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0078, + 0x00fc, + 0x000c, + 0x007c, + 0x00f8, + 0x00c0, + 0x00fc, + 0x007c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['t'] = { + 0x0000, + 0x0018, + 0x0018, + 0x003c, + 0x003c, + 0x0018, + 0x0018, + 0x0018, + 0x0018, + 0x0018, + 0x0038, + 0x0038, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['u'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00cc, + 0x00fc, + 0x00f8, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['v'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x030c, + 0x030c, + 0x030c, + 0x0198, + 0x01f8, + 0x00f0, + 0x0060, + 0x0060, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['w'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x180c, + 0x180c, + 0x19cc, + 0x19cc, + 0x0b68, + 0x0f78, + 0x0e38, + 0x0e38, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['x'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x018c, + 0x018c, + 0x00d8, + 0x0070, + 0x0070, + 0x00d8, + 0x018c, + 0x018c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +['y'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x030c, + 0x030c, + 0x0198, + 0x0198, + 0x00f0, + 0x00f0, + 0x0060, + 0x0060, + 0x0078, + 0x0038, + 0x0000, + 0x0000, +}, +['z'] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x00fc, + 0x00fc, + 0x00e0, + 0x0070, + 0x0038, + 0x001c, + 0x00fc, + 0x00fc, + 0x0000, + 0x0000, + 0x0000, + 0x0000, +}, +}; diff --git a/mta-sign.c b/mta-sign.c new file mode 100644 index 00000000..8a1d4c47 --- /dev/null +++ b/mta-sign.c @@ -0,0 +1,132 @@ +/** \file + * Test the matrix LCD PRU firmware with a multi-hue rainbow. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "ledscape.h" +#include "mta-font.c" + +const int width = 128; +const int height = 128; + + +static int +font_write( + uint32_t * const buf, + const uint32_t color, + const int x0, + const int y0, + const char * s +) +{ + int x = x0; + int y = y0; + + while (1) + { + char c = *s++; + if (!c) + break; + + if (c == '\n') + { + x = x0; + y += 16 * width; + continue; + } + + const uint16_t * ch = font[(uint8_t) c]; + int max_width = 0; + + if (c == ' ' || c == '.') + max_width = 3; + else + for (int h = 0 ; h < 16 ; h++) + { + int width = 0; + uint16_t row = ch[h] >> 2; + while (row) + { + row >>= 1; + width++; + } + + if (width > max_width) + max_width = width; + } + + // add space after the character + max_width++; + + for (int h = 0 ; h < 16 ; h++) + { + uint16_t row = ch[h] >> 2; + for (int j = 0 ; j < max_width ; j++, row >>= 1) + { + uint32_t pixel_color = (row & 1) ? color : 0; + if (x + j >= width || x + j < 0) + continue; + if (y + h >= height || y + h < 0) + continue; + + uint8_t * pix = (uint8_t*) &buf[(y+h)*width + x + j]; + pix[0] = pixel_color >> 16; + pix[1] = pixel_color >> 8; + pix[2] = pixel_color >> 0; + } + } + + x += max_width; + } + + return x; +} + + +int +main( + int argc, + char ** argv +) +{ + ledscape_t * const leds = ledscape_init(width, height); + + + printf("init done\n"); + time_t last_time = time(NULL); + unsigned last_i = 0; + + unsigned i = 0; + uint32_t * const p = calloc(width*height,4); + + while (1) + { + font_write(p, 0xFF0000, 0, 0, "1.!Nyc resistor"); + font_write(p, 0x00FF00, 0, 16, argc > 1 ? argv[1] : ""); + ledscape_draw(leds, p); + usleep(20000); + + // wait for the previous frame to finish; + //const uint32_t response = ledscape_wait(leds); + const uint32_t response = 0; + time_t now = time(NULL); + if (now != last_time) + { + printf("%d fps. starting %d previous %"PRIx32"\n", + i - last_i, i, response); + last_i = i; + last_time = now; + } + + } + + ledscape_close(leds); + + return EXIT_SUCCESS; +} From 6c8b62c226152e494130e9e991bc04936c6de9f4 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 1 Jan 2000 01:41:21 +0000 Subject: [PATCH 152/332] extend clock pulse slightly --- matrix.p | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/matrix.p b/matrix.p index 318af735..da7fbe16 100644 --- a/matrix.p +++ b/matrix.p @@ -451,8 +451,6 @@ NEW_ROW_LOOP: XOR out_clr, out_set, gpio3_led_mask SBBO out_clr, gpio3_base, GPIO_CLRDATAOUT, 8 - CLOCK_LO - #if 1 // If the brightness is less than the pixel, turn off // but keep in mind that this is the brightness of @@ -473,6 +471,8 @@ NEW_ROW_LOOP: no_blank: #endif + CLOCK_LO + ADD offset, offset, 3*16 QBNE PIXEL_LOOP, offset, width From b83e84b67e0cc248ebd467000a3930d7da7a8eae Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 1 Jan 2000 01:45:30 +0000 Subject: [PATCH 153/332] remove old comment --- ws281x.p | 3 --- 1 file changed, 3 deletions(-) diff --git a/ws281x.p b/ws281x.p index 85260a3e..51d51523 100644 --- a/ws281x.p +++ b/ws281x.p @@ -419,9 +419,6 @@ WORD_LOOP: MOV r13, GPIO3 | GPIO_SETDATAOUT // Wait for 650 ns to have passed - // \todo: Move some of the other work to the other - // cycles. I think this might have already been exhausted - // with the addition of GPIO3 banked LEDs WAITNS 650, wait_start_time // Send all the start bits From 37ed6bb109f900f227b5795e688c247156318e0b Mon Sep 17 00:00:00 2001 From: root Date: Sat, 1 Jan 2000 02:08:48 +0000 Subject: [PATCH 154/332] a few chars --- fonts/mta-sign.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fonts/mta-sign.json b/fonts/mta-sign.json index 0dd4fd29..b3cb9ee6 100644 --- a/fonts/mta-sign.json +++ b/fonts/mta-sign.json @@ -3,6 +3,7 @@ "36":[1920,8160,16368,31224,30968,63868,63932,61500,31224,31224,16368,8160,1920,0,0,0], "37":[1920,8160,16368,28728,32568,65340,61500,62460,29496,30840,16368,8160,1920,0,0,0], "42":[256,896,1984,3168,6960,16184,31804,14648,6448,3168,1984,896,256,0,0,0], +"44":[0,0,0,0,0,0,0,0,0,0,12,12,8,4,0,0], "45":[0,0,0,0,0,0,0,124,0,0,0,0,0,0,0,0], "46":[0,0,0,0,0,0,0,0,0,0,12,12,0,0,0,0], "47":[0,0,0,504,496,480,496,440,284,12,0,0,0,0,0,0], @@ -29,7 +30,8 @@ "72":[0,396,396,396,396,508,508,396,396,396,396,396,0,0,0,0], "73":[0,252,252,48,48,48,48,48,48,48,252,252,0,0,0,0], "76":[0,12,12,12,12,12,12,12,12,12,1020,1020,0,0,0,0], -"78":[0,396,412,444,508,492,492,460,396,396,396,396,0,0,0,0], +"77":[0,1548,1820,1980,2044,1772,1612,1548,1548,1548,1548,1548,0,0,0,1], +"78":[0,396,412,444,508,492,460,396,396,396,396,396,0,0,0,0], "79":[0,240,504,408,780,780,780,780,780,408,504,240,0,0,0,0], "80":[0,124,252,204,204,252,124,12,12,12,12,12,0,0,0,0], "81":[0,248,508,396,396,396,396,396,428,204,508,888,512,0,0,1], @@ -39,6 +41,9 @@ "85":[0,792,792,792,792,792,792,792,792,792,1016,496,0,0,0,0], "86":[0,1548,1548,792,792,792,432,432,432,224,224,224,0,0,0,0], "87":[0,780,780,780,780,780,780,876,1020,1020,924,780,0,0,0,0], +"88":[0,780,780,408,408,240,96,240,408,408,780,780,0,0,0,1], +"89":[0,780,780,408,408,240,240,96,96,96,96,96,0,0,0,1], +"90":[0,508,508,192,96,96,48,48,24,24,508,508,0,0,0,1], "92":[0,0,0,252,124,60,124,236,452,384,0,0,0,0,0,0], "94":[1920,8160,16368,30840,32568,65340,63548,62268,29496,30840,16368,8160,1920,0,0,0], "97":[0,0,0,0,120,252,204,240,252,204,252,216,0,0,0,0], From 7686f42b57e099405f53da0ad223450a044111e6 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 1 Jan 2000 02:15:46 +0000 Subject: [PATCH 155/332] MTA sign scrolling works --- Makefile | 3 +- mta-font.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++- mta-sign.c | 14 +++++++-- 3 files changed, 104 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index b9942a67..52884981 100755 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ TARGETS += matrix-udp-rx TARGETS += opc-rx TARGETS += cube-life TARGETS += cube-image +TARGETS += mta-sign LEDSCAPE_OBJS = ledscape.o pru.o bitslice.o util.o LEDSCAPE_LIB := libledscape.a @@ -105,7 +106,7 @@ clean: # The correct way to reserve the GPIO pins on the BBB is with the # capemgr and a Device Tree file. But it doesn't work. # -SLOT_FILE=/sys/devices/bone_capemgr.9/slots +SLOT_FILE=/sys/devices/bone_capemgr.8/slots DTS=CAPE-BONE-OCTO DTB=/lib/firmware/$(DTS)-00A0.dtbo diff --git a/mta-font.c b/mta-font.c index cb466a17..7d66aabf 100644 --- a/mta-font.c +++ b/mta-font.c @@ -93,6 +93,24 @@ const uint16_t font[][16] = { 0x0000, 0x0000, }, +[','] = { + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x000c, + 0x000c, + 0x0008, + 0x0004, + 0x0000, + 0x0000, +}, ['-'] = { 0x0000, 0x0000, @@ -561,6 +579,24 @@ const uint16_t font[][16] = { 0x0000, 0x0000, }, +['M'] = { + 0x0000, + 0x060c, + 0x071c, + 0x07bc, + 0x07fc, + 0x06ec, + 0x064c, + 0x060c, + 0x060c, + 0x060c, + 0x060c, + 0x060c, + 0x0000, + 0x0000, + 0x0000, + 0x0001, +}, ['N'] = { 0x0000, 0x018c, @@ -568,12 +604,12 @@ const uint16_t font[][16] = { 0x01bc, 0x01fc, 0x01ec, - 0x01ec, 0x01cc, 0x018c, 0x018c, 0x018c, 0x018c, + 0x018c, 0x0000, 0x0000, 0x0000, @@ -741,6 +777,60 @@ const uint16_t font[][16] = { 0x0000, 0x0000, }, +['X'] = { + 0x0000, + 0x030c, + 0x030c, + 0x0198, + 0x0198, + 0x00f0, + 0x0060, + 0x00f0, + 0x0198, + 0x0198, + 0x030c, + 0x030c, + 0x0000, + 0x0000, + 0x0000, + 0x0001, +}, +['Y'] = { + 0x0000, + 0x030c, + 0x030c, + 0x0198, + 0x0198, + 0x00f0, + 0x00f0, + 0x0060, + 0x0060, + 0x0060, + 0x0060, + 0x0060, + 0x0000, + 0x0000, + 0x0000, + 0x0001, +}, +['Z'] = { + 0x0000, + 0x01fc, + 0x01fc, + 0x00c0, + 0x0060, + 0x0060, + 0x0030, + 0x0030, + 0x0018, + 0x0018, + 0x01fc, + 0x01fc, + 0x0000, + 0x0000, + 0x0000, + 0x0001, +}, ['\\'] = { 0x0000, 0x0000, diff --git a/mta-sign.c b/mta-sign.c index 8a1d4c47..39c0b7a9 100644 --- a/mta-sign.c +++ b/mta-sign.c @@ -104,13 +104,21 @@ main( unsigned i = 0; uint32_t * const p = calloc(width*height,4); + int scroll_x = 128; while (1) { - font_write(p, 0xFF0000, 0, 0, "1.!Nyc resistor"); - font_write(p, 0x00FF00, 0, 16, argc > 1 ? argv[1] : ""); + font_write(p, 0xFF0000, 0, 0, "1!NYCResistor"); + font_write(p, 0x00FF00, 100, 0, "8min"); + + int end_x = font_write(p, 0xFF4000, scroll_x, 16, argc > 1 ? argv[1] : ""); + if (end_x <= 0) + scroll_x = 128; + else + scroll_x--; + ledscape_draw(leds, p); - usleep(20000); + usleep(30000); // wait for the previous frame to finish; //const uint32_t response = ledscape_wait(leds); From 960ccad3d86bae39b09a4e5ee723f05b1c62e4ca Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 1 Jan 2000 03:10:01 +0000 Subject: [PATCH 156/332] OPC receiver --- Makefile | 1 + opc-rx.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 opc-rx.c diff --git a/Makefile b/Makefile index c4ca86cf..e4afca8f 100755 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ TARGETS += matrix-test TARGETS += fire TARGETS += matrix-udp-rx TARGETS += udp-rx +TARGETS += opc-rx LEDSCAPE_OBJS = ledscape.o pru.o bitslice.o util.o LEDSCAPE_LIB := libledscape.a diff --git a/opc-rx.c b/opc-rx.c new file mode 100644 index 00000000..a67ebeee --- /dev/null +++ b/opc-rx.c @@ -0,0 +1,158 @@ +/** \file + * OPC image packet receiver. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "bitslice.h" +#include "ledscape.h" + +typedef struct +{ + uint8_t channel; + uint8_t command; + uint8_t len_hi; + uint8_t len_lo; +} opc_cmd_t; + +static int +tcp_socket( + const int port +) +{ + const int sock = socket(AF_INET, SOCK_STREAM, 0); + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_port = htons(port), + .sin_addr.s_addr = INADDR_ANY, + }; + + if (sock < 0) + return -1; + if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr)) < 0) + return -1; + if (listen(sock, 5) == -1) + return -1; + + return sock; +} + + +int +main( + int argc, + char ** argv +) +{ + const int port = 7890; + const int sock = tcp_socket(port); + if (sock < 0) + die("socket port %d failed: %s\n", port, strerror(errno)); + + const unsigned width = 32; + const unsigned height = 8; + const size_t image_size = width * height * 3; + + // largest possible UDP packet + uint8_t buf[65536]; + if (sizeof(buf) < image_size + 1) + die("%u x %u too large for UDP\n", width, height); + + fprintf(stderr, "%u x %u, TCP port %u\n", width, height, port); + + ledscape_t * const leds = ledscape_init(width, height); + + const unsigned report_interval = 10; + unsigned last_report = 0; + unsigned long delta_sum = 0; + unsigned frames = 0; + + uint32_t * const fb = calloc(width*height,4); + + int fd; + while ((fd = accept(sock, NULL, NULL)) >= 0) + { + while(1) + { + opc_cmd_t cmd; + ssize_t rlen = read(fd, &cmd, sizeof(cmd)); + if (rlen < 0) + die("recv failed: %s\n", strerror(errno)); + if (rlen == 0) + { + close(fd); + break; + } + + const size_t cmd_len = cmd.len_hi << 8 | cmd.len_lo; + warn("received %zu bytes: %d %zu\n", rlen, cmd.command, cmd_len); + + size_t offset = 0; + while (offset < cmd_len) + { + rlen = read(fd, buf + offset, cmd_len - offset); + if (rlen < 0) + die("recv failed: %s\n", strerror(errno)); + if (rlen == 0) + break; + offset += rlen; + } + + if (cmd.command != 0) + continue; + + struct timeval start_tv, stop_tv, delta_tv; + gettimeofday(&start_tv, NULL); + + const unsigned frame_num = 0; + + for (unsigned y = 0 ; y < height ; y++) + { + for (unsigned x = 0 ; x < width ; x++) + { + uint8_t * const out = (void*) &fb[x + y*width]; + const uint8_t * const in = &buf[3*(x + y*width)]; + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + } + } + + ledscape_draw(leds, fb); + + gettimeofday(&stop_tv, NULL); + timersub(&stop_tv, &start_tv, &delta_tv); + + frames++; + delta_sum += delta_tv.tv_usec; + if (stop_tv.tv_sec - last_report < report_interval) + continue; + last_report = stop_tv.tv_sec; + + const unsigned delta_avg = delta_sum / frames; + printf("%6u usec avg, max %.2f fps, actual %.2f fps (over %u frames)\n", + delta_avg, + report_interval * 1.0e6 / delta_avg, + frames * 1.0 / report_interval, + frames + ); + + frames = delta_sum = 0; + } + } + + return 0; +} From 7749dde49e964d6bb6daa3966c1a2aadcc4ec4c0 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 1 Jan 2000 03:10:17 +0000 Subject: [PATCH 157/332] dim mode --- matrix-test.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/matrix-test.c b/matrix-test.c index 72bbc15e..4c875a33 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -98,6 +98,7 @@ rainbow( ) { const unsigned color = cycle % 180; + const unsigned dim = 8; for (unsigned x=0; x < width; x++) { for (unsigned y=0; y < height; y++) { @@ -105,9 +106,9 @@ rainbow( const uint32_t in = rainbowColors[index]; uint8_t * const out = &pixels[x + y*width]; #if 1 - out[0] = ((in >> 0) & 0xFF); // * y / 16; - out[1] = ((in >> 8) & 0xFF); // * y / 16; - out[2] = ((in >> 16) & 0xFF); // * y / 16; + out[0] = ((in >> 0) & 0xFF) * dim / 128; // * y / 16; + out[1] = ((in >> 8) & 0xFF) * dim / 128; // * y / 16; + out[2] = ((in >> 16) & 0xFF) * dim / 128; // * y / 16; #else //out[0] = ((in >> 0) & 0xFF); //out[1] = ((in >> 8) & 0xFF); @@ -152,7 +153,7 @@ gradient( int main(void) { - const int width = 64; + const int width = 128; const int height = 48; ledscape_t * const leds = ledscape_init(width, height); printf("init done\n"); From b6e53312822dc8c28053602af60fe045b8c1fbc0 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 1 Jan 2000 03:10:31 +0000 Subject: [PATCH 158/332] zig zag panels --- ledscape.c | 67 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 12 deletions(-) diff --git a/ledscape.c b/ledscape.c index 70fe9584..3d6503dd 100644 --- a/ledscape.c +++ b/ledscape.c @@ -124,6 +124,45 @@ bright_map( } +static uint8_t * +ledscape_remap( + ledscape_t * const leds, + uint8_t * const frame, + unsigned x, + unsigned y +) +{ +#define CONFIG_ZIGZAG +#ifdef CONFIG_ZIGZAG + (void) leds; + + // each panel is 16x8 + // vertical panel number is y % 8 (which output line) + // horizontal panel number is y % (16*8) + // if y % 2 == 1, map backwards + const unsigned panel_width = 16; + const unsigned panel_height = 8; + unsigned panel_num = x / panel_width; + unsigned output_line = y / panel_height; + unsigned panel_x = x % panel_width; + unsigned panel_y = y % panel_height; + unsigned panel_offset = panel_y * panel_width; + + // the even lines are forwards, the odd lines go backwards + if (panel_y % 2 == 0) + { + panel_offset += panel_x; + } else { + panel_offset += panel_width - panel_x - 1; + } + + return &frame[(panel_num*128 + panel_offset)*48*3 + output_line]; +#else + return &frame[x*48*3 + y]; +#endif +} + + /** Translate the RGBA buffer to the correct output type and * initiate the transfer of a frame to the LED strips. * @@ -141,7 +180,6 @@ ledscape_draw( #ifdef CONFIG_LED_MATRIX // matrix packed is: - // p(0,0)p(0,8)p(64,0)p(64,8).... // this way the PRU can read all sixteen output pixels in // one LBBO and clock them out. // there is an array of NUM_MATRIX output coordinates (one for each of @@ -152,8 +190,10 @@ ledscape_draw( for (uint32_t y = 0 ; y < leds->matrix->matrix_height ; y++) { - const uint32_t * const in_row = &in[(y+m->y_offset) * leds->width]; - uint8_t * const out_row = &out[y * leds->matrix->matrix_width * 3 * NUM_MATRIX]; + const uint32_t * const in_row + = &in[(y+m->y_offset) * leds->width]; + uint8_t * const out_row + = &out[y * leds->matrix->matrix_width * 3 * NUM_MATRIX]; for (uint32_t x = 0 ; x < leds->matrix->matrix_width ; x++) { @@ -170,17 +210,18 @@ ledscape_draw( #else // Translate the RGBA frame into G R B, sliced by color // only 48 outputs currently supported - const unsigned height = 48; - for (unsigned y = 0 ; y < height ; y++) + const unsigned pru_stride = 48; + for (unsigned y = 0 ; y < leds->height ; y++) { const uint32_t * const row_in = &in[y*leds->width]; for (unsigned x = 0 ; x < leds->width ; x++) { - uint8_t * const row_out = &out[x*height*3 + y]; + uint8_t * const row_out + = ledscape_remap(leds, out, x, y); const uint32_t p = row_in[x]; - row_out[0*height] = (p >> 8) & 0xFF; // green - row_out[1*height] = (p >> 0) & 0xFF; // red - row_out[2*height] = (p >> 16) & 0xFF; // blue + row_out[0*pru_stride] = (p >> 8) & 0xFF; // green + row_out[1*pru_stride] = (p >> 0) & 0xFF; // red + row_out[2*pru_stride] = (p >> 16) & 0xFF; // blue } } @@ -189,7 +230,8 @@ ledscape_draw( ; // Update the pixel data and send the start - leds->ws281x->pixels_dma = leds->pru->ddr_addr + leds->frame_size * frame; + leds->ws281x->pixels_dma + = leds->pru->ddr_addr + leds->frame_size * frame; frame = (frame + 1) & 1; // Send the start command @@ -224,7 +266,8 @@ ledscape_init( ) { pru_t * const pru = pru_init(0); - const size_t frame_size = 16 * 8 * width * 3; //LEDSCAPE_NUM_STRIPS * 4; + //const size_t frame_size = 16 * 8 * width * 3; //LEDSCAPE_NUM_STRIPS * 4; + const size_t frame_size = 48 * width * 8 * 3; #if 0 if (2 *frame_size > pru->ddr_size) @@ -279,7 +322,7 @@ ledscape_init( // LED strips, not matrix output *(leds->ws281x) = (ws281x_command_t) { .pixels_dma = 0, // will be set in draw routine - .num_pixels = width, + .num_pixels = width * 8, // panel height .command = 0, .response = 0, }; From f3961a742b14710854b87a6952aa501627119d54 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 1 Jan 2000 03:38:30 +0000 Subject: [PATCH 159/332] fix for matrix --- ledscape.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ledscape.c b/ledscape.c index 3d6503dd..603bf1b4 100644 --- a/ledscape.c +++ b/ledscape.c @@ -12,7 +12,7 @@ #include "ledscape.h" #include "pru.h" -#undef CONFIG_LED_MATRIX +#define CONFIG_LED_MATRIX /** GPIO pins used by the LEDscape. @@ -266,8 +266,11 @@ ledscape_init( ) { pru_t * const pru = pru_init(0); - //const size_t frame_size = 16 * 8 * width * 3; //LEDSCAPE_NUM_STRIPS * 4; +#ifdef CONFIG_LED_MATRIX + const size_t frame_size = 16 * 8 * width * 3; //LEDSCAPE_NUM_STRIPS * 4; +#else const size_t frame_size = 48 * width * 8 * 3; +#endif #if 0 if (2 *frame_size > pru->ddr_size) From 014b0193a686c8527e2c9f46c1b671650cd327d0 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 1 Jan 2000 03:40:34 +0000 Subject: [PATCH 160/332] size for matrix --- opc-rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opc-rx.c b/opc-rx.c index a67ebeee..c6a46794 100644 --- a/opc-rx.c +++ b/opc-rx.c @@ -63,7 +63,7 @@ main( die("socket port %d failed: %s\n", port, strerror(errno)); const unsigned width = 32; - const unsigned height = 8; + const unsigned height = 16; const size_t image_size = width * height * 3; // largest possible UDP packet From eecbf1b1c4ce9222df7beae77531a7e6d6a03722 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 1 Jan 2000 03:46:33 +0000 Subject: [PATCH 161/332] two color first row --- mta-sign.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mta-sign.c b/mta-sign.c index 39c0b7a9..6dc8b74c 100644 --- a/mta-sign.c +++ b/mta-sign.c @@ -108,9 +108,10 @@ main( while (1) { - font_write(p, 0xFF0000, 0, 0, "1!NYCResistor"); + font_write(p, 0x00FF00, 0, 0, "1!NYCResistor"); + font_write(p, 0xFF0000, 7, 0, "!"); font_write(p, 0x00FF00, 100, 0, "8min"); - + int end_x = font_write(p, 0xFF4000, scroll_x, 16, argc > 1 ? argv[1] : ""); if (end_x <= 0) scroll_x = 128; From 5aba434d1dd38f1f424278714139ca7e833d461f Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 22 Nov 2013 13:01:15 -0500 Subject: [PATCH 162/332] Move images around --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 06017217..fc88e6d8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Testing LEDscape](http://farm4.staticflickr.com/3834/9378678019_b706c55635_z.jpg) +![Octoscroller Interface board](http://farm6.staticflickr.com/5349/10218235983_c55d247088.jpg) DANGER! ======= @@ -115,5 +115,7 @@ dma address or number of pixels. LED Strips ========== +![Testing LEDscape](http://farm4.staticflickr.com/3834/9378678019_b706c55635_z.jpg) + * http://www.adafruit.com/products/1138 * http://www.adafruit.com/datasheets/WS2811.pdf From 93dcf97cf86346664399079bd7cd8c5687160098 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 22 Nov 2013 13:01:48 -0500 Subject: [PATCH 163/332] Remove targets that curently don't build --- Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile b/Makefile index e4afca8f..67d8c367 100755 --- a/Makefile +++ b/Makefile @@ -3,11 +3,9 @@ # The top level targets link in the two .o files for now. # TARGETS += teensy-udp-rx -TARGETS += rgb-test TARGETS += matrix-test TARGETS += fire TARGETS += matrix-udp-rx -TARGETS += udp-rx TARGETS += opc-rx LEDSCAPE_OBJS = ledscape.o pru.o bitslice.o util.o From ba34cbba43cdd87fb06a16b4204c968b8198a176 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Tue, 7 Jan 2014 19:43:51 -0500 Subject: [PATCH 164/332] reworked slightly to adjust position of connectors; ordered via oshpark --- pcb/octoscroller.brd | 878 ++++++++++++++++++++++--------------------- 1 file changed, 456 insertions(+), 422 deletions(-) diff --git a/pcb/octoscroller.brd b/pcb/octoscroller.brd index ab56442c..8871cee0 100644 --- a/pcb/octoscroller.brd +++ b/pcb/octoscroller.brd @@ -123,9 +123,9 @@ -Octoscroller^2 -http://trmm.net/Octoscroller -2013-09-30 +Octoscroller^2 +http://trmm.net/Octoscroller +2014-01-07 @@ -984,10 +984,10 @@ design rules under a new name. - - - - + + + + @@ -1038,10 +1038,9 @@ design rules under a new name. - - - - + + + @@ -1076,35 +1075,36 @@ design rules under a new name. - - + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1118,7 +1118,8 @@ design rules under a new name. - + + @@ -1126,40 +1127,39 @@ design rules under a new name. - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1181,37 +1181,36 @@ design rules under a new name. - - - + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - + + + @@ -1224,42 +1223,41 @@ design rules under a new name. - - - + + + - - + + - - - - - + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - + @@ -1281,43 +1279,36 @@ design rules under a new name. - - - + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + @@ -1330,9 +1321,9 @@ design rules under a new name. - - - + + + @@ -1343,33 +1334,32 @@ design rules under a new name. - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1389,111 +1379,123 @@ design rules under a new name. - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + - + - - - - - + + + + + + + - + - - - - + + + + + - + - - - - + + + + + + - + - - - - - - - - - - - + + + + + + + + - - + + @@ -1506,35 +1508,36 @@ design rules under a new name. - - - + + + + + - + - + - - - - + + + - - - - + + + + @@ -1543,46 +1546,60 @@ design rules under a new name. - - - - - + + + + + - - - - + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + @@ -1591,16 +1608,19 @@ design rules under a new name. - - - - + + + + + - - + + + + @@ -1633,10 +1653,9 @@ design rules under a new name. - - - - + + + @@ -1652,60 +1671,69 @@ design rules under a new name. - - - - - - - - - + + + + + + - - - - - - + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + - - - - - - - - + + + + + + + + - - - - + + + + + + + + + @@ -1715,49 +1743,46 @@ design rules under a new name. - - - - - + + + - - - - - - - - - - + + + + + + + + - - - - - - - - - - + + + + + + + + + - - - - + + + + + + @@ -1765,74 +1790,80 @@ design rules under a new name. - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - + + + + - - + + + + + + - - - - - - - - - + + + - - - - - - + + + + + + + + + - - - - - - - + + + + + + + + + + @@ -1978,14 +2009,15 @@ design rules under a new name. - - - - - - + + + + + + + - + @@ -1993,11 +2025,13 @@ design rules under a new name. - - - - - + + + + + + + From 74126d46e40e4e8a28ae72bbb879dcb6885ce1c4 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 18 Dec 2013 01:33:31 +0000 Subject: [PATCH 165/332] ubuntu on bbb --- dts/ubuntu-3.8.13-bone32.dts | 1324 ++++++++++++++++++++++++++++++++++ 1 file changed, 1324 insertions(+) create mode 100644 dts/ubuntu-3.8.13-bone32.dts diff --git a/dts/ubuntu-3.8.13-bone32.dts b/dts/ubuntu-3.8.13-bone32.dts new file mode 100644 index 00000000..810dc85e --- /dev/null +++ b/dts/ubuntu-3.8.13-bone32.dts @@ -0,0 +1,1324 @@ +/dts-v1/; + +/ { + #address-cells = <0x1>; + #size-cells = <0x1>; + compatible = "ti,am335x-bone", "ti,am33xx"; + interrupt-parent = <0x1>; + model = "TI AM335x BeagleBone"; + + chosen { + }; + + aliases { + serial0 = "/ocp/serial@44e09000"; + serial1 = "/ocp/serial@48022000"; + serial2 = "/ocp/serial@48024000"; + serial3 = "/ocp/serial@481a6000"; + serial4 = "/ocp/serial@481a8000"; + serial5 = "/ocp/serial@481aa000"; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x10000000>; + }; + + cpus { + + cpu@0 { + compatible = "arm,cortex-a8"; + operating-points = <0xf4240 0x149970 0xc3500 0x13d620 0x927c0 0x10f7c0 0x493e0 0xec928>; + voltage-tolerance = <0x2>; + clock-latency = <0x493e0>; + cpu0-supply = <0x2>; + linux,phandle = <0x13>; + phandle = <0x13>; + }; + }; + + pmu { + compatible = "arm,cortex-a8-pmu"; + interrupts = <0x3>; + }; + + soc { + compatible = "ti,omap-infra"; + + mpu { + compatible = "ti,omap3-mpu"; + ti,hwmods = "mpu"; + }; + }; + + pinmux@44e10800 { + compatible = "pinctrl-single"; + reg = <0x44e10800 0x238>; + #address-cells = <0x1>; + #size-cells = <0x0>; + pinctrl-single,register-width = <0x20>; + pinctrl-single,function-mask = <0x7f>; + pinctrl-names = "default"; + pinctrl-0 = <0x3>; + linux,phandle = <0x14>; + phandle = <0x14>; + + pinmux_userled_pins { + pinctrl-single,pins = <0x54 0x7 0x58 0x17 0x5c 0x7 0x60 0x17>; + linux,phandle = <0x3>; + phandle = <0x3>; + }; + + pinmux_i2c0_pins { + pinctrl-single,pins = <0x188 0x70 0x18c 0x70>; + linux,phandle = <0x6>; + phandle = <0x6>; + }; + + pinmux_i2c2_pins { + pinctrl-single,pins = <0x178 0x73 0x17c 0x73>; + linux,phandle = <0x7>; + phandle = <0x7>; + }; + + pinmux_mmc1_pins { + pinctrl-single,pins = <0x160 0x2f>; + linux,phandle = <0x9>; + phandle = <0x9>; + }; + + pinmux_rstctl_pins { + pinctrl-single,pins = <0x50 0x17>; + linux,phandle = <0x4>; + phandle = <0x4>; + }; + }; + + ocp { + compatible = "simple-bus"; + #address-cells = <0x1>; + #size-cells = <0x1>; + ranges; + ti,hwmods = "l3_main"; + linux,phandle = <0x15>; + phandle = <0x15>; + + interrupt-controller@48200000 { + compatible = "ti,omap2-intc"; + interrupt-controller; + #interrupt-cells = <0x1>; + ti,intc-size = <0x80>; + reg = <0x48200000 0x1000>; + linux,phandle = <0x1>; + phandle = <0x1>; + }; + + edma@49000000 { + compatible = "ti,edma3"; + ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2"; + reg = <0x49000000 0x10000 0x44e10f90 0x40>; + interrupt-parent = <0x1>; + interrupts = <0xc 0xd 0xe>; + #dma-cells = <0x1>; + dma-channels = <0x40>; + ti,edma-regions = <0x4>; + ti,edma-slots = <0x100>; + ti,edma-queue-tc-map = <0x0 0x0 0x1 0x1 0x2 0x2>; + ti,edma-queue-priority-map = <0x0 0x0 0x1 0x1 0x2 0x2>; + ti,edma-default-queue = <0x1>; + ti,edma-xbar-event-map = <0x20 0xc 0x1e 0x14>; + linux,phandle = <0x8>; + phandle = <0x8>; + }; + + gpio@44e07000 { + compatible = "ti,omap4-gpio"; + ti,hwmods = "gpio1"; + gpio-controller; + #gpio-cells = <0x2>; + interrupt-controller; + #interrupt-cells = <0x1>; + reg = <0x44e07000 0x1000>; + interrupts = <0x60>; + linux,phandle = <0xa>; + phandle = <0xa>; + }; + + gpio@4804c000 { + compatible = "ti,omap4-gpio"; + ti,hwmods = "gpio2"; + gpio-controller; + #gpio-cells = <0x2>; + interrupt-controller; + #interrupt-cells = <0x1>; + reg = <0x4804c000 0x1000>; + interrupts = <0x62>; + linux,phandle = <0x5>; + phandle = <0x5>; + }; + + gpio@481ac000 { + compatible = "ti,omap4-gpio"; + ti,hwmods = "gpio3"; + gpio-controller; + #gpio-cells = <0x2>; + interrupt-controller; + #interrupt-cells = <0x1>; + reg = <0x481ac000 0x1000>; + interrupts = <0x20>; + linux,phandle = <0x16>; + phandle = <0x16>; + }; + + gpio@481ae000 { + compatible = "ti,omap4-gpio"; + ti,hwmods = "gpio4"; + gpio-controller; + #gpio-cells = <0x2>; + interrupt-controller; + #interrupt-cells = <0x1>; + reg = <0x481ae000 0x1000>; + interrupts = <0x3e>; + linux,phandle = <0x17>; + phandle = <0x17>; + }; + + rstctl@0 { + status = "okay"; + compatible = "gpio-rctrl"; + pinctrl-names = "default"; + pinctrl-0 = <0x4>; + #reset-cells = <0x2>; + gpios = <0x5 0x14 0x0>; + gpio-names = "eMMC_RSTn"; + linux,phandle = <0xc>; + phandle = <0xc>; + }; + + serial@44e09000 { + compatible = "ti,omap3-uart"; + ti,hwmods = "uart1"; + clock-frequency = <0x2dc6c00>; + reg = <0x44e09000 0x2000>; + interrupts = <0x48>; + status = "okay"; + linux,phandle = <0x18>; + phandle = <0x18>; + }; + + serial@48022000 { + compatible = "ti,omap3-uart"; + ti,hwmods = "uart2"; + clock-frequency = <0x2dc6c00>; + reg = <0x48022000 0x2000>; + interrupts = <0x49>; + status = "disabled"; + linux,phandle = <0x19>; + phandle = <0x19>; + }; + + serial@48024000 { + compatible = "ti,omap3-uart"; + ti,hwmods = "uart3"; + clock-frequency = <0x2dc6c00>; + reg = <0x48024000 0x2000>; + interrupts = <0x4a>; + status = "disabled"; + linux,phandle = <0x1a>; + phandle = <0x1a>; + }; + + serial@481a6000 { + compatible = "ti,omap3-uart"; + ti,hwmods = "uart4"; + clock-frequency = <0x2dc6c00>; + reg = <0x481a6000 0x2000>; + interrupts = <0x2c>; + status = "disabled"; + linux,phandle = <0x1b>; + phandle = <0x1b>; + }; + + serial@481a8000 { + compatible = "ti,omap3-uart"; + ti,hwmods = "uart5"; + clock-frequency = <0x2dc6c00>; + reg = <0x481a8000 0x2000>; + interrupts = <0x2d>; + status = "disabled"; + linux,phandle = <0x1c>; + phandle = <0x1c>; + }; + + serial@481aa000 { + compatible = "ti,omap3-uart"; + ti,hwmods = "uart6"; + clock-frequency = <0x2dc6c00>; + reg = <0x481aa000 0x2000>; + interrupts = <0x2e>; + status = "disabled"; + linux,phandle = <0x1d>; + phandle = <0x1d>; + }; + + i2c@44e0b000 { + compatible = "ti,omap4-i2c"; + #address-cells = <0x1>; + #size-cells = <0x0>; + ti,hwmods = "i2c1"; + reg = <0x44e0b000 0x1000>; + interrupts = <0x46>; + status = "okay"; + clock-frequency = <0x61a80>; + pinctrl-names = "default"; + pinctrl-0 = <0x6>; + linux,phandle = <0x1e>; + phandle = <0x1e>; + + tps@24 { + reg = <0x24>; + compatible = "ti,tps65217"; + ti,pmic-shutdown-controller; + interrupt-parent = <0x1>; + interrupts = <0x7>; + linux,phandle = <0x1f>; + phandle = <0x1f>; + + regulators { + #address-cells = <0x1>; + #size-cells = <0x0>; + + regulator@0 { + reg = <0x0>; + regulator-compatible = "dcdc1"; + regulator-always-on; + linux,phandle = <0x20>; + phandle = <0x20>; + }; + + regulator@1 { + reg = <0x1>; + regulator-compatible = "dcdc2"; + regulator-name = "vdd_mpu"; + regulator-min-microvolt = <0xe1d48>; + regulator-max-microvolt = <0x1437c8>; + regulator-boot-on; + regulator-always-on; + linux,phandle = <0x2>; + phandle = <0x2>; + }; + + regulator@2 { + reg = <0x2>; + regulator-compatible = "dcdc3"; + regulator-name = "vdd_core"; + regulator-min-microvolt = <0xe1d48>; + regulator-max-microvolt = <0x118c30>; + regulator-boot-on; + regulator-always-on; + linux,phandle = <0x21>; + phandle = <0x21>; + }; + + regulator@3 { + reg = <0x3>; + regulator-compatible = "ldo1"; + regulator-always-on; + linux,phandle = <0x22>; + phandle = <0x22>; + }; + + regulator@4 { + reg = <0x4>; + regulator-compatible = "ldo2"; + regulator-always-on; + linux,phandle = <0x23>; + phandle = <0x23>; + }; + + regulator@5 { + reg = <0x5>; + regulator-compatible = "ldo3"; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-always-on; + linux,phandle = <0x24>; + phandle = <0x24>; + }; + + regulator@6 { + reg = <0x6>; + regulator-compatible = "ldo4"; + regulator-always-on; + linux,phandle = <0x25>; + phandle = <0x25>; + }; + }; + }; + + baseboard_eeprom@50 { + compatible = "at,24c256"; + reg = <0x50>; + linux,phandle = <0xe>; + phandle = <0xe>; + }; + }; + + i2c@4802a000 { + compatible = "ti,omap4-i2c"; + #address-cells = <0x1>; + #size-cells = <0x0>; + ti,hwmods = "i2c2"; + reg = <0x4802a000 0x1000>; + interrupts = <0x47>; + status = "disabled"; + linux,phandle = <0x26>; + phandle = <0x26>; + }; + + i2c@4819c000 { + compatible = "ti,omap4-i2c"; + #address-cells = <0x1>; + #size-cells = <0x0>; + ti,hwmods = "i2c3"; + reg = <0x4819c000 0x1000>; + interrupts = <0x1e>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0x7>; + clock-frequency = <0x186a0>; + linux,phandle = <0x27>; + phandle = <0x27>; + + cape_eeprom0@54 { + compatible = "at,24c256"; + reg = <0x54>; + linux,phandle = <0xf>; + phandle = <0xf>; + }; + + cape_eeprom1@55 { + compatible = "at,24c256"; + reg = <0x55>; + linux,phandle = <0x10>; + phandle = <0x10>; + }; + + cape_eeprom2@56 { + compatible = "at,24c256"; + reg = <0x56>; + linux,phandle = <0x11>; + phandle = <0x11>; + }; + + cape_eeprom3@57 { + compatible = "at,24c256"; + reg = <0x57>; + linux,phandle = <0x12>; + phandle = <0x12>; + }; + }; + + mmc@48060000 { + compatible = "ti,omap3-hsmmc"; + ti,hwmods = "mmc1"; + ti,dual-volt; + ti,needs-special-reset; + ti,needs-special-hs-handling; + dmas = <0x8 0x18 0x8 0x19>; + dma-names = "tx", "rx"; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0x9>; + bus-width = <0x4>; + cd-gpios = <0xa 0x6 0x0>; + cd-inverted; + vmmc-supply = <0xb>; + ti,vcc-aux-disable-is-sleep; + linux,phandle = <0x28>; + phandle = <0x28>; + }; + + mmc@481d8000 { + compatible = "ti,omap3-hsmmc"; + ti,hwmods = "mmc2"; + ti,needs-special-reset; + ti,needs-special-hs-handling; + dmas = <0x8 0x2 0x8 0x3>; + dma-names = "tx", "rx"; + status = "disabled"; + vmmc-supply = <0xb>; + bus-width = <0x8>; + ti,non-removable; + reset = <0xc 0x0 0x0>; + reset-names = "eMMC_RSTn-CONSUMER"; + linux,phandle = <0x29>; + phandle = <0x29>; + }; + + mmc@47810000 { + compatible = "ti,omap3-hsmmc"; + ti,hwmods = "mmc3"; + ti,needs-special-reset; + ti,needs-special-hs-handling; + status = "disabled"; + linux,phandle = <0x2a>; + phandle = <0x2a>; + }; + + wdt@44e35000 { + compatible = "ti,omap3-wdt"; + ti,hwmods = "wd_timer2"; + reg = <0x44e35000 0x1000>; + interrupts = <0x5b>; + linux,phandle = <0x2b>; + phandle = <0x2b>; + }; + + d_can@481cc000 { + compatible = "bosch,d_can"; + ti,hwmods = "d_can0"; + reg = <0x481cc000 0x2000>; + interrupts = <0x34>; + status = "disabled"; + linux,phandle = <0x2c>; + phandle = <0x2c>; + }; + + d_can@481d0000 { + compatible = "bosch,d_can"; + ti,hwmods = "d_can1"; + reg = <0x481d0000 0x2000>; + interrupts = <0x37>; + status = "disabled"; + linux,phandle = <0x2d>; + phandle = <0x2d>; + }; + + timer@44e31000 { + compatible = "ti,omap2-timer"; + reg = <0x44e31000 0x400>; + interrupts = <0x43>; + ti,hwmods = "timer1"; + ti,timer-alwon; + linux,phandle = <0x2e>; + phandle = <0x2e>; + }; + + timer@48040000 { + compatible = "ti,omap2-timer"; + reg = <0x48040000 0x400>; + interrupts = <0x44>; + ti,hwmods = "timer2"; + linux,phandle = <0x2f>; + phandle = <0x2f>; + }; + + timer@48042000 { + compatible = "ti,omap2-timer"; + reg = <0x48042000 0x400>; + interrupts = <0x45>; + ti,hwmods = "timer3"; + linux,phandle = <0x30>; + phandle = <0x30>; + }; + + timer@48044000 { + compatible = "ti,omap2-timer"; + reg = <0x48044000 0x400>; + interrupts = <0x5c>; + ti,hwmods = "timer4"; + ti,timer-pwm; + linux,phandle = <0x31>; + phandle = <0x31>; + }; + + timer@48046000 { + compatible = "ti,omap2-timer"; + reg = <0x48046000 0x400>; + interrupts = <0x5d>; + ti,hwmods = "timer5"; + ti,timer-pwm; + linux,phandle = <0x32>; + phandle = <0x32>; + }; + + timer@48048000 { + compatible = "ti,omap2-timer"; + reg = <0x48048000 0x400>; + interrupts = <0x5e>; + ti,hwmods = "timer6"; + ti,timer-pwm; + linux,phandle = <0x33>; + phandle = <0x33>; + }; + + timer@4804a000 { + compatible = "ti,omap2-timer"; + reg = <0x4804a000 0x400>; + interrupts = <0x5f>; + ti,hwmods = "timer7"; + ti,timer-pwm; + linux,phandle = <0x34>; + phandle = <0x34>; + }; + + pruss@4a300000 { + compatible = "ti,pruss-v2"; + ti,hwmods = "pruss"; + ti,deassert-hard-reset = "pruss", "pruss"; + reg = <0x4a300000 0x80000>; + ti,pintc-offset = <0x20000>; + interrupt-parent = <0x1>; + status = "disabled"; + interrupts = <0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b>; + linux,phandle = <0x35>; + phandle = <0x35>; + }; + + rtc@44e3e000 { + compatible = "ti,da830-rtc"; + reg = <0x44e3e000 0x1000>; + interrupts = <0x4b 0x4c>; + ti,hwmods = "rtc"; + ti,system-power-controller; + }; + + spi@48030000 { + compatible = "ti,omap4-mcspi"; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x48030000 0x400>; + interrupt = <0x41>; + ti,spi-num-cs = <0x2>; + ti,hwmods = "spi0"; + dmas = <0x8 0x10 0x8 0x11 0x8 0x12 0x8 0x13>; + dma-names = "tx0", "rx0", "tx1", "rx1"; + status = "disabled"; + linux,phandle = <0x36>; + phandle = <0x36>; + }; + + spi@481a0000 { + compatible = "ti,omap4-mcspi"; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x481a0000 0x400>; + interrupt = <0x7d>; + ti,spi-num-cs = <0x2>; + ti,hwmods = "spi1"; + dmas = <0x8 0x2a 0x8 0x2b 0x8 0x2c 0x8 0x2d>; + dma-names = "tx0", "rx0", "tx1", "rx1"; + status = "disabled"; + linux,phandle = <0x37>; + phandle = <0x37>; + }; + + gpmc@50000000 { + compatible = "ti,am3352-gpmc"; + ti,hwmods = "gpmc"; + reg = <0x50000000 0x1000000>; + interrupts = <0x64>; + gpmc,num-cs = <0x7>; + gpmc,num-waitpins = <0x2>; + #address-cells = <0x2>; + #size-cells = <0x1>; + status = "disabled"; + linux,phandle = <0x38>; + phandle = <0x38>; + }; + + nop-phy@0 { + compatible = "nop-xceiv-usb"; + }; + + nop-phy@1 { + compatible = "nop-xceiv-usb"; + }; + + usb@47400000 { + compatible = "ti,musb-am33xx"; + reg = <0x47400000 0x1000 0x47401000 0x800 0x47401800 0x800>; + interrupts = <0x11 0x12 0x13>; + multipoint = <0x1>; + num-eps = <0x10>; + ram-bits = <0xc>; + port0-mode = <0x3>; + port1-mode = <0x1>; + power = <0xfa>; + ti,hwmods = "usb_otg_hs"; + status = "okay"; + interface_type = <0x1>; + linux,phandle = <0x39>; + phandle = <0x39>; + }; + + ethernet@4a100000 { + compatible = "ti,cpsw"; + ti,hwmods = "cpgmac0"; + cpdma_channels = <0x8>; + ale_entries = <0x400>; + bd_ram_size = <0x2000>; + no_bd_ram = <0x0>; + rx_descs = <0x40>; + mac_control = <0x20>; + slaves = <0x2>; + cpts_active_slave = <0x0>; + cpts_clock_mult = <0x80000000>; + cpts_clock_shift = <0x1d>; + reg = <0x4a100000 0x800 0x4a101200 0x100>; + #address-cells = <0x1>; + #size-cells = <0x1>; + interrupt-parent = <0x1>; + interrupts = <0x28 0x29 0x2a 0x2b>; + ranges; + disable-napi; + linux,phandle = <0x3a>; + phandle = <0x3a>; + + mdio@4a101000 { + compatible = "ti,davinci_mdio"; + #address-cells = <0x1>; + #size-cells = <0x0>; + ti,hwmods = "davinci_mdio"; + bus_freq = <0xf4240>; + reg = <0x4a101000 0x100>; + linux,phandle = <0xd>; + phandle = <0xd>; + }; + + slave@4a100200 { + mac-address = [00 00 00 00 00 00]; + phy_id = <0xd 0x0>; + linux,phandle = <0x3b>; + phandle = <0x3b>; + }; + + slave@4a100300 { + mac-address = [00 00 00 00 00 00]; + phy_id = <0xd 0x1>; + linux,phandle = <0x3c>; + phandle = <0x3c>; + }; + }; + + tscadc@44e0d000 { + compatible = "ti,ti-tscadc"; + reg = <0x44e0d000 0x1000>; + interrupt-parent = <0x1>; + interrupts = <0x10>; + ti,hwmods = "adc_tsc"; + status = "disabled"; + linux,phandle = <0x3d>; + phandle = <0x3d>; + }; + + lcdc@4830e000 { + compatible = "ti,am3352-lcdc", "ti,da830-lcdc"; + reg = <0x4830e000 0x1000>; + interrupts = <0x24>; + status = "disabled"; + ti,hwmods = "lcdc"; + linux,phandle = <0x3e>; + phandle = <0x3e>; + }; + + epwmss@48300000 { + compatible = "ti,am33xx-pwmss"; + reg = <0x48300000 0x10>; + ti,hwmods = "epwmss0"; + #address-cells = <0x1>; + #size-cells = <0x1>; + status = "disabled"; + ranges = <0x48300100 0x48300100 0x80 0x48300180 0x48300180 0x80 0x48300200 0x48300200 0x80>; + linux,phandle = <0x3f>; + phandle = <0x3f>; + + ecap@48300100 { + compatible = "ti,am33xx-ecap"; + #pwm-cells = <0x3>; + reg = <0x48300100 0x80>; + ti,hwmods = "ecap0"; + status = "disabled"; + linux,phandle = <0x40>; + phandle = <0x40>; + }; + + ehrpwm@48300200 { + compatible = "ti,am33xx-ehrpwm"; + #pwm-cells = <0x3>; + reg = <0x48300200 0x80>; + ti,hwmods = "ehrpwm0"; + status = "disabled"; + linux,phandle = <0x41>; + phandle = <0x41>; + }; + }; + + epwmss@48302000 { + compatible = "ti,am33xx-pwmss"; + reg = <0x48302000 0x10>; + ti,hwmods = "epwmss1"; + #address-cells = <0x1>; + #size-cells = <0x1>; + status = "disabled"; + ranges = <0x48302100 0x48302100 0x80 0x48302180 0x48302180 0x80 0x48302200 0x48302200 0x80>; + linux,phandle = <0x42>; + phandle = <0x42>; + + ecap@48302100 { + compatible = "ti,am33xx-ecap"; + #pwm-cells = <0x3>; + reg = <0x48302100 0x80>; + ti,hwmods = "ecap1"; + status = "disabled"; + linux,phandle = <0x43>; + phandle = <0x43>; + }; + + ehrpwm@48302200 { + compatible = "ti,am33xx-ehrpwm"; + #pwm-cells = <0x3>; + reg = <0x48302200 0x80>; + ti,hwmods = "ehrpwm1"; + status = "disabled"; + linux,phandle = <0x44>; + phandle = <0x44>; + }; + }; + + epwmss@48304000 { + compatible = "ti,am33xx-pwmss"; + reg = <0x48304000 0x10>; + ti,hwmods = "epwmss2"; + #address-cells = <0x1>; + #size-cells = <0x1>; + status = "disabled"; + ranges = <0x48304100 0x48304100 0x80 0x48304180 0x48304180 0x80 0x48304200 0x48304200 0x80>; + linux,phandle = <0x45>; + phandle = <0x45>; + + ecap@48304100 { + compatible = "ti,am33xx-ecap"; + #pwm-cells = <0x3>; + reg = <0x48304100 0x80>; + ti,hwmods = "ecap2"; + status = "disabled"; + linux,phandle = <0x46>; + phandle = <0x46>; + }; + + ehrpwm@48304200 { + compatible = "ti,am33xx-ehrpwm"; + #pwm-cells = <0x3>; + reg = <0x48304200 0x80>; + ti,hwmods = "ehrpwm2"; + status = "disabled"; + linux,phandle = <0x47>; + phandle = <0x47>; + }; + }; + + sham@53100000 { + compatible = "ti,omap4-sham"; + ti,hwmods = "sham"; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x53100000 0x200>; + interrupt-parent = <0x1>; + interrupts = <0x6d>; + dmas = <0x8 0x24>; + dma-names = "rx"; + status = "okay"; + linux,phandle = <0x48>; + phandle = <0x48>; + }; + + aes@53500000 { + compatible = "ti,omap4-aes"; + ti,hwmods = "aes"; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x53500000 0xa0>; + interrupt-parent = <0x1>; + interrupts = <0x66>; + dmas = <0x8 0x6 0x8 0x5>; + dma-names = "tx", "rx"; + status = "okay"; + linux,phandle = <0x49>; + phandle = <0x49>; + }; + + mcasp@48038000 { + compatible = "ti,omap2-mcasp-audio"; + #address-cells = <0x1>; + #size-cells = <0x0>; + ti,hwmods = "mcasp0"; + reg = <0x48038000 0x2000>; + interrupts = <0x50 0x51>; + status = "disabled"; + asp-chan-q = <0x2>; + tx-dma-offset = <0x46000000>; + rx-dma-offset = <0x46000000>; + dmas = <0x8 0x8 0x8 0x9>; + dma-names = "tx", "rx"; + linux,phandle = <0x4a>; + phandle = <0x4a>; + }; + + mcasp@4803C000 { + compatible = "ti,omap2-mcasp-audio"; + #address-cells = <0x1>; + #size-cells = <0x0>; + ti,hwmods = "mcasp1"; + reg = <0x4803c000 0x2000>; + interrupts = <0x52 0x53>; + status = "disabled"; + asp-chan-q = <0x2>; + tx-dma-offset = <0x46400000>; + rx-dma-offset = <0x46400000>; + dmas = <0x8 0xa 0x8 0xb>; + dma-names = "tx", "rx"; + linux,phandle = <0x4b>; + phandle = <0x4b>; + }; + + bandgap@44e10448 { + compatible = "ti,am335x-bandgap"; + reg = <0x44e10448 0x8>; + }; + + gpio-leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <0x3>; + + led0 { + label = "beaglebone:green:usr0"; + gpios = <0x5 0x15 0x0>; + linux,default-trigger = "heartbeat"; + default-state = "off"; + }; + + led1 { + label = "beaglebone:green:usr1"; + gpios = <0x5 0x16 0x0>; + linux,default-trigger = "mmc0"; + default-state = "off"; + }; + + led2 { + label = "beaglebone:green:usr2"; + gpios = <0x5 0x17 0x0>; + linux,default-trigger = "cpu0"; + default-state = "off"; + }; + + led3 { + label = "beaglebone:green:usr3"; + gpios = <0x5 0x18 0x0>; + default-state = "off"; + linux,default-trigger = "mmc1"; + }; + }; + }; + + bone_capemgr { + compatible = "ti,bone-capemgr"; + status = "okay"; + eeprom = <0xe>; + + baseboardmaps { + + board@0 { + board-name = "A335BONE"; + compatible-name = "ti,beaglebone"; + linux,phandle = <0x4c>; + phandle = <0x4c>; + }; + + board@1 { + board-name = "A335BNLT"; + compatible-name = "ti,beaglebone-black"; + linux,phandle = <0x4d>; + phandle = <0x4d>; + }; + }; + + slots { + + slot@0 { + eeprom = <0xf>; + }; + + slot@1 { + eeprom = <0x10>; + }; + + slot@2 { + eeprom = <0x11>; + }; + + slot@3 { + eeprom = <0x12>; + }; + + slot@5 { + ti,cape-override; + compatible = "kernel-command-line", "runtime"; + board-name = "Bone-Geiger"; + version = "00A0"; + manufacturer = "Geiger Inc."; + part-number = "BB-BONE-GEIGER"; + }; + + slot@7 { + ti,cape-override; + compatible = "kernel-command-line", "runtime"; + board-name = "Bone-Nixie"; + version = "00A0"; + manufacturer = "Ranostay Industries"; + part-number = "BB-BONE-NIXIE"; + }; + + slot@8 { + ti,cape-override; + compatible = "kernel-command-line", "runtime"; + board-name = "Bone-TFT"; + version = "00A0"; + manufacturer = "Adafruit"; + part-number = "BB-BONE-TFT-01"; + }; + + slot@9 { + ti,cape-override; + compatible = "kernel-command-line", "runtime"; + board-name = "Bone-RTC"; + version = "00A0"; + manufacturer = "Adafruit"; + part-number = "BB-BONE-RTC-01"; + }; + + slot@10 { + ti,cape-override; + compatible = "kernel-command-line", "runtime"; + board-name = "Bone-Hexy"; + version = "00A0"; + manufacturer = "Koen Kooi"; + part-number = "BB-BONE-HEXY-01"; + }; + + slot@11 { + ti,cape-override; + compatible = "kernel-command-line", "runtime"; + board-name = "Bone-MRF24J40"; + version = "00A0"; + manufacturer = "Signal 11 Software"; + part-number = "BB-BONE-MRF24J40"; + }; + + slot@12 { + ti,cape-override; + compatible = "kernel-command-line", "runtime"; + board-name = "BB-BONE-RS232"; + version = "00A0"; + manufacturer = "Adafruit"; + part-number = "BB-BONE-RS232-01"; + }; + + slot@13 { + compatible = "kernel-command-line", "runtime"; + board-name = "BB-BONE-GPS"; + version = "00A0"; + manufacturer = "Adafruit"; + part-number = "BB-BONE-GPS-01"; + }; + + slot@100 { + ti,cape-override; + priority = <0x1>; + compatible = "ti,beaglebone-black"; + board-name = "Bone-LT-eMMC-2G"; + version = "00A0"; + manufacturer = "Texas Instruments"; + part-number = "BB-BONE-EMMC-2G"; + }; + + slot@101 { + ti,cape-override; + priority = <0x1>; + compatible = "ti,beaglebone-black"; + board-name = "Bone-Black-HDMI"; + version = "00A0"; + manufacturer = "Texas Instruments"; + part-number = "BB-BONELT-HDMI"; + }; + + slot@102 { + ti,cape-override; + priority = <0x2>; + compatible = "ti,beaglebone-black"; + board-name = "Bone-Black-HDMIN"; + version = "00A0"; + manufacturer = "Texas Instruments"; + part-number = "BB-BONELT-HDMIN"; + }; + }; + + capemaps { + + cape@0 { + part-number = "BB-BONE-DVID-01"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-dvi-00A0.dtbo"; + }; + + version@00A1 { + version = "00A1", "01"; + dtbo = "cape-bone-dvi-00A1.dtbo"; + }; + + version@00A2 { + version = "00A2", "A2"; + dtbo = "cape-bone-dvi-00A2.dtbo"; + }; + + version@00A3 { + version = "00A3"; + dtbo = "cape-bone-dvi-00A2.dtbo"; + }; + }; + + cape@1 { + part-number = "BB-BONE-EMMC-2G"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-2g-emmc1.dtbo"; + }; + }; + + cape@2 { + part-number = "BB-BONE-GEIGER"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-geiger-00A0.dtbo"; + }; + }; + + cape@3 { + part-number = "BB-BONE-LCD3-01"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-lcd3-00A0.dtbo"; + }; + + version@00A2 { + version = "00A2"; + dtbo = "cape-bone-lcd3-00A2.dtbo"; + }; + }; + + cape@4 { + part-number = "BB-BONE-WTHR-01"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-weather-00A0.dtbo"; + }; + }; + + cape@5 { + part-number = "BB-BONELT-HDMI"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-boneblack-hdmi-00A0.dtbo"; + }; + }; + + cape@6 { + part-number = "BB-BONE-NIXIE"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-nixie-00A0.dtbo"; + }; + }; + + cape@7 { + part-number = "BB-BONE-TFT-01"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-adafruit-lcd-00A0.dtbo"; + }; + }; + + cape@8 { + part-number = "BB-BONE-RTC-01"; + + version@00A0 { + version = "00A0"; + dtbo = "BB-BONE-RTC-00A0.dtbo"; + }; + }; + + cape@9 { + part-number = "BB-BONE-HEXY-01"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-hexy-00A0.dtbo"; + }; + }; + + cape@10 { + part-number = "BB-BONE-MRF24J40"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-mrf24j40-00A0.dtbo"; + }; + }; + + cape@11 { + part-number = "BB-BONE-EXPTEST"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-exptest-00A0.dtbo"; + }; + }; + + cape@12 { + part-number = "BB-BONE-RS232-01"; + + version@00A0 { + version = "00A0"; + dtbo = "BB-BONE-RS232-00A0.dtbo"; + }; + }; + + cape@13 { + part-number = "BB-BONE-GPS-01"; + + version@00A0 { + version = "00A0"; + dtbo = "BB-BONE-GPS-00A0.dtbo"; + }; + }; + + cape@14 { + part-number = "BB-BONELT-HDMIN"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-boneblack-hdmin-00A0.dtbo"; + }; + }; + + cape@15 { + part-number = "2191"; + + version@R2 { + version = "R2"; + dtbo = "cape-bebopr-R2.dtbo"; + }; + }; + }; + }; + + fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "vmmcsd_fixed"; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + linux,phandle = <0xb>; + phandle = <0xb>; + }; + + __symbols__ { + cpu = "/cpus/cpu@0"; + am33xx_pinmux = "/pinmux@44e10800"; + userled_pins = "/pinmux@44e10800/pinmux_userled_pins"; + i2c0_pins = "/pinmux@44e10800/pinmux_i2c0_pins"; + i2c2_pins = "/pinmux@44e10800/pinmux_i2c2_pins"; + mmc1_pins = "/pinmux@44e10800/pinmux_mmc1_pins"; + rstctl_pins = "/pinmux@44e10800/pinmux_rstctl_pins"; + ocp = "/ocp"; + intc = "/ocp/interrupt-controller@48200000"; + edma = "/ocp/edma@49000000"; + gpio1 = "/ocp/gpio@44e07000"; + gpio2 = "/ocp/gpio@4804c000"; + gpio3 = "/ocp/gpio@481ac000"; + gpio4 = "/ocp/gpio@481ae000"; + rstctl = "/ocp/rstctl@0"; + uart1 = "/ocp/serial@44e09000"; + uart2 = "/ocp/serial@48022000"; + uart3 = "/ocp/serial@48024000"; + uart4 = "/ocp/serial@481a6000"; + uart5 = "/ocp/serial@481a8000"; + uart6 = "/ocp/serial@481aa000"; + i2c0 = "/ocp/i2c@44e0b000"; + tps = "/ocp/i2c@44e0b000/tps@24"; + dcdc1_reg = "/ocp/i2c@44e0b000/tps@24/regulators/regulator@0"; + dcdc2_reg = "/ocp/i2c@44e0b000/tps@24/regulators/regulator@1"; + dcdc3_reg = "/ocp/i2c@44e0b000/tps@24/regulators/regulator@2"; + ldo1_reg = "/ocp/i2c@44e0b000/tps@24/regulators/regulator@3"; + ldo2_reg = "/ocp/i2c@44e0b000/tps@24/regulators/regulator@4"; + ldo3_reg = "/ocp/i2c@44e0b000/tps@24/regulators/regulator@5"; + ldo4_reg = "/ocp/i2c@44e0b000/tps@24/regulators/regulator@6"; + baseboard_eeprom = "/ocp/i2c@44e0b000/baseboard_eeprom@50"; + i2c1 = "/ocp/i2c@4802a000"; + i2c2 = "/ocp/i2c@4819c000"; + cape_eeprom0 = "/ocp/i2c@4819c000/cape_eeprom0@54"; + cape_eeprom1 = "/ocp/i2c@4819c000/cape_eeprom1@55"; + cape_eeprom2 = "/ocp/i2c@4819c000/cape_eeprom2@56"; + cape_eeprom3 = "/ocp/i2c@4819c000/cape_eeprom3@57"; + mmc1 = "/ocp/mmc@48060000"; + mmc2 = "/ocp/mmc@481d8000"; + mmc3 = "/ocp/mmc@47810000"; + wdt2 = "/ocp/wdt@44e35000"; + dcan0 = "/ocp/d_can@481cc000"; + dcan1 = "/ocp/d_can@481d0000"; + timer1 = "/ocp/timer@44e31000"; + timer2 = "/ocp/timer@48040000"; + timer3 = "/ocp/timer@48042000"; + timer4 = "/ocp/timer@48044000"; + timer5 = "/ocp/timer@48046000"; + timer6 = "/ocp/timer@48048000"; + timer7 = "/ocp/timer@4804a000"; + pruss = "/ocp/pruss@4a300000"; + spi0 = "/ocp/spi@48030000"; + spi1 = "/ocp/spi@481a0000"; + gpmc = "/ocp/gpmc@50000000"; + usb_otg_hs = "/ocp/usb@47400000"; + mac = "/ocp/ethernet@4a100000"; + davinci_mdio = "/ocp/ethernet@4a100000/mdio@4a101000"; + cpsw_emac0 = "/ocp/ethernet@4a100000/slave@4a100200"; + cpsw_emac1 = "/ocp/ethernet@4a100000/slave@4a100300"; + tscadc = "/ocp/tscadc@44e0d000"; + lcdc = "/ocp/lcdc@4830e000"; + epwmss0 = "/ocp/epwmss@48300000"; + ecap0 = "/ocp/epwmss@48300000/ecap@48300100"; + ehrpwm0 = "/ocp/epwmss@48300000/ehrpwm@48300200"; + epwmss1 = "/ocp/epwmss@48302000"; + ecap1 = "/ocp/epwmss@48302000/ecap@48302100"; + ehrpwm1 = "/ocp/epwmss@48302000/ehrpwm@48302200"; + epwmss2 = "/ocp/epwmss@48304000"; + ecap2 = "/ocp/epwmss@48304000/ecap@48304100"; + ehrpwm2 = "/ocp/epwmss@48304000/ehrpwm@48304200"; + sham = "/ocp/sham@53100000"; + aes = "/ocp/aes@53500000"; + mcasp0 = "/ocp/mcasp@48038000"; + mcasp1 = "/ocp/mcasp@4803C000"; + baseboard_beaglebone = "/bone_capemgr/baseboardmaps/board@0"; + baseboard_beaglebone_black = "/bone_capemgr/baseboardmaps/board@1"; + vmmcsd_fixed = "/fixedregulator@0"; + }; +}; From 56b93ef6b376c687203e58f72898513600ead62b Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 18 Dec 2013 06:17:10 +0000 Subject: [PATCH 166/332] use binary coded pwm to improve smooth colors --- matrix.p | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/matrix.p b/matrix.p index 34f4096e..798b69ce 100644 --- a/matrix.p +++ b/matrix.p @@ -184,7 +184,7 @@ #define gpio1_led_mask r11 #define gpio2_led_mask r13 #define gpio3_led_mask r14 -#define clock_pin r15 +#define bright_thresh r15 #define gpio0_base r16 #define gpio1_base r17 #define gpio2_base r18 @@ -194,10 +194,12 @@ #define BRIGHT_STEP 16 #define CLOCK_LO \ - SBBO clock_pin, gpio1_base, GPIO_SETDATAOUT, 4; \ + MOV out_set, 1 << gpio1_clock; \ + SBBO out_set, gpio1_base, GPIO_SETDATAOUT, 4; \ #define CLOCK_HI \ - SBBO clock_pin, gpio1_base, GPIO_CLRDATAOUT, 4; \ + MOV out_set, 1 << gpio1_clock; \ + SBBO out_set, gpio1_base, GPIO_CLRDATAOUT, 4; \ #define LATCH_HI \ MOV out_set, 1 << gpio1_latch; \ @@ -315,7 +317,7 @@ START: SET GPIO_MASK(g82_gpio), g82_pin SET GPIO_MASK(b82_gpio), b82_pin - MOV clock_pin, 1 << gpio1_clock + //MOV clock_pin, 1 << gpio1_clock READ_LOOP: // Load the pointer to the buffer from PRU DRAM into r0 and the @@ -350,7 +352,8 @@ NEW_ROW_LOOP: XOR out_clr, out_clr, out_set // complement the bits into clr SBBO out_clr, gpio1_base, GPIO_CLRDATAOUT, 8 // set both - MOV bright, 0x100 + MOV bright, 7 + MOV bright_thresh, 255 ROW_LOOP: // Re-start reading at the same row MOV offset, 0 @@ -373,18 +376,19 @@ NEW_ROW_LOOP: MOV gpio3_set, 0 #define GPIO(R) CAT3(gpio,R,_set) #define OUTPUT_ROW(N,reg_r,reg_g,reg_b) \ - QBGE skip_r##N, reg_r, bright; \ + QBBC skip_r##N, reg_r, bright; \ SET GPIO(r##N##_gpio), r##N##_pin; \ skip_r##N: \ - QBGE skip_g##N, reg_g, bright; \ + QBBC skip_g##N, reg_g, bright; \ SET GPIO(g##N##_gpio), g##N##_pin; \ skip_g##N: \ - QBGE skip_b##N, reg_b, bright; \ + QBBC skip_b##N, reg_b, bright; \ SET GPIO(b##N##_gpio), b##N##_pin; \ skip_b##N: \ OUTPUT_ROW(11, r20.b0, r20.b1, r20.b2) OUTPUT_ROW(12, r20.b3, r21.b0, r21.b1) + OUTPUT_ROW(21, r21.b2, r21.b3, r22.b0) OUTPUT_ROW(22, r22.b1, r22.b2, r22.b3) @@ -431,11 +435,14 @@ NEW_ROW_LOOP: // If the brightness is less than the pixel, turn off // but keep in mind that this is the brightness of // the previous row, not this one. - LSR out_set, offset, 0 - ADD out_clr, bright, 10 - LSL out_clr, out_clr, 4 - - QBLT no_blank, out_clr, out_set + LSL out_set, offset, 0 + //LSL out_clr, 1, bright + //LSL out_clr, out_clr, 1 + //MOV out_clr, 2048 + LSL out_clr, bright_thresh, 5 + + //QBBS no_blank, out_set, bright + QBGT no_blank, out_set, out_clr DISPLAY_OFF no_blank: #endif @@ -448,7 +455,9 @@ NEW_ROW_LOOP: DISPLAY_ON // Update the brightness, and then give the row another scan - SUB bright, bright, BRIGHT_STEP + //SUB bright, bright, BRIGHT_STEP + SUB bright, bright, 1 + LSR bright_thresh, bright_thresh, 1 QBLT ROW_LOOP, bright, 0 // We have just done all eight brightness levels for this From c5f0228ce0d1cc52ec74b23ef1cfd8fcad4186ee Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 18 Dec 2013 06:18:32 +0000 Subject: [PATCH 167/332] steeper steps to show more gradation --- matrix-test.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/matrix-test.c b/matrix-test.c index 4c875a33..6582989f 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -98,7 +98,7 @@ rainbow( ) { const unsigned color = cycle % 180; - const unsigned dim = 8; + const unsigned dim = 128; for (unsigned x=0; x < width; x++) { for (unsigned y=0; y < height; y++) { @@ -141,10 +141,10 @@ gradient( uint8_t b = 0xFF; out[1] = b * ((((x + y + cycle) >> 5) ) & 1); #else - uint8_t b = ((x+y+cycle) % 32) * 8; - out[0] = b * ((((x + y + cycle) >> 5) % 3) & 1); - out[1] = b * ((((x + y + cycle) >> 5) % 5) & 1); - out[2] = b * ((((x + y + cycle) >> 5) % 7) & 1); + uint8_t b = ((x+2*y+cycle)) * 4; + out[0] = b; + out[1] = b; + out[2] = b; #endif } } From f9f334e0ebd1ae79fbd93db1de9a3e6cc9f28fd6 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 18 Dec 2013 06:22:58 +0000 Subject: [PATCH 168/332] rename angstrom dtb --- am335x-boneblack.dtb => dts/angstrom.dtb | Bin dts/angstrom.dts | 1276 ++++++++++++++++++++++ 2 files changed, 1276 insertions(+) rename am335x-boneblack.dtb => dts/angstrom.dtb (100%) create mode 100644 dts/angstrom.dts diff --git a/am335x-boneblack.dtb b/dts/angstrom.dtb similarity index 100% rename from am335x-boneblack.dtb rename to dts/angstrom.dtb diff --git a/dts/angstrom.dts b/dts/angstrom.dts new file mode 100644 index 00000000..f3c6f511 --- /dev/null +++ b/dts/angstrom.dts @@ -0,0 +1,1276 @@ +/dts-v1/; + +/ { + #address-cells = <0x1>; + #size-cells = <0x1>; + compatible = "ti,am335x-bone", "ti,am33xx"; + interrupt-parent = <0x1>; + model = "TI AM335x BeagleBone"; + + chosen { + }; + + aliases { + serial0 = "/ocp/serial@44e09000"; + serial1 = "/ocp/serial@48022000"; + serial2 = "/ocp/serial@48024000"; + serial3 = "/ocp/serial@481a6000"; + serial4 = "/ocp/serial@481a8000"; + serial5 = "/ocp/serial@481aa000"; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x10000000>; + }; + + cpus { + + cpu@0 { + compatible = "arm,cortex-a8"; + operating-points = <0xf4240 0x149970 0xc3500 0x13d620 0x927c0 0x10f7c0 0x493e0 0xec928>; + voltage-tolerance = <0x2>; + clock-latency = <0x493e0>; + cpu0-supply = <0x2>; + linux,phandle = <0x11>; + phandle = <0x11>; + }; + }; + + soc { + compatible = "ti,omap-infra"; + + mpu { + compatible = "ti,omap3-mpu"; + ti,hwmods = "mpu"; + }; + }; + + pinmux@44e10800 { + compatible = "pinctrl-single"; + reg = <0x44e10800 0x238>; + #address-cells = <0x1>; + #size-cells = <0x0>; + pinctrl-single,register-width = <0x20>; + pinctrl-single,function-mask = <0x7f>; + pinctrl-names = "default"; + pinctrl-0 = <0x3>; + linux,phandle = <0x12>; + phandle = <0x12>; + + pinmux_userled_pins { + pinctrl-single,pins = <0x54 0x7 0x58 0x17 0x5c 0x7 0x60 0x17>; + linux,phandle = <0x3>; + phandle = <0x3>; + }; + + pinmux_i2c0_pins { + pinctrl-single,pins = <0x188 0x70 0x18c 0x70>; + linux,phandle = <0x6>; + phandle = <0x6>; + }; + + pinmux_i2c2_pins { + pinctrl-single,pins = <0x178 0x73 0x17c 0x73>; + linux,phandle = <0x7>; + phandle = <0x7>; + }; + + pinmux_rstctl_pins { + pinctrl-single,pins = <0x50 0x17>; + linux,phandle = <0x4>; + phandle = <0x4>; + }; + }; + + ocp { + compatible = "simple-bus"; + #address-cells = <0x1>; + #size-cells = <0x1>; + ranges; + ti,hwmods = "l3_main"; + linux,phandle = <0x13>; + phandle = <0x13>; + + interrupt-controller@48200000 { + compatible = "ti,omap2-intc"; + interrupt-controller; + #interrupt-cells = <0x1>; + ti,intc-size = <0x80>; + reg = <0x48200000 0x1000>; + linux,phandle = <0x1>; + phandle = <0x1>; + }; + + edma@49000000 { + compatible = "ti,edma3"; + ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2"; + reg = <0x49000000 0x10000 0x44e10f90 0x40>; + interrupt-parent = <0x1>; + interrupts = <0xc 0xd 0xe>; + #dma-cells = <0x1>; + dma-channels = <0x40>; + ti,edma-regions = <0x4>; + ti,edma-slots = <0x100>; + ti,edma-queue-tc-map = <0x0 0x0 0x1 0x1 0x2 0x2>; + ti,edma-queue-priority-map = <0x0 0x0 0x1 0x1 0x2 0x2>; + ti,edma-default-queue = <0x1>; + ti,edma-xbar-event-map = <0x20 0xc 0x1e 0x14>; + linux,phandle = <0x8>; + phandle = <0x8>; + }; + + gpio@44e07000 { + compatible = "ti,omap4-gpio"; + ti,hwmods = "gpio1"; + gpio-controller; + #gpio-cells = <0x2>; + interrupt-controller; + #interrupt-cells = <0x1>; + reg = <0x44e07000 0x1000>; + interrupts = <0x60>; + linux,phandle = <0x14>; + phandle = <0x14>; + }; + + gpio@4804c000 { + compatible = "ti,omap4-gpio"; + ti,hwmods = "gpio2"; + gpio-controller; + #gpio-cells = <0x2>; + interrupt-controller; + #interrupt-cells = <0x1>; + reg = <0x4804c000 0x1000>; + interrupts = <0x62>; + linux,phandle = <0x5>; + phandle = <0x5>; + }; + + gpio@481ac000 { + compatible = "ti,omap4-gpio"; + ti,hwmods = "gpio3"; + gpio-controller; + #gpio-cells = <0x2>; + interrupt-controller; + #interrupt-cells = <0x1>; + reg = <0x481ac000 0x1000>; + interrupts = <0x20>; + linux,phandle = <0x15>; + phandle = <0x15>; + }; + + gpio@481ae000 { + compatible = "ti,omap4-gpio"; + ti,hwmods = "gpio4"; + gpio-controller; + #gpio-cells = <0x2>; + interrupt-controller; + #interrupt-cells = <0x1>; + reg = <0x481ae000 0x1000>; + interrupts = <0x3e>; + linux,phandle = <0x16>; + phandle = <0x16>; + }; + + rstctl@0 { + status = "okay"; + compatible = "gpio-rctrl"; + pinctrl-names = "default"; + pinctrl-0 = <0x4>; + #reset-cells = <0x2>; + gpios = <0x5 0x14 0x0>; + gpio-names = "eMMC_RSTn"; + linux,phandle = <0xa>; + phandle = <0xa>; + }; + + serial@44e09000 { + compatible = "ti,omap3-uart"; + ti,hwmods = "uart1"; + clock-frequency = <0x2dc6c00>; + reg = <0x44e09000 0x2000>; + interrupts = <0x48>; + status = "okay"; + linux,phandle = <0x17>; + phandle = <0x17>; + }; + + serial@48022000 { + compatible = "ti,omap3-uart"; + ti,hwmods = "uart2"; + clock-frequency = <0x2dc6c00>; + reg = <0x48022000 0x2000>; + interrupts = <0x49>; + status = "disabled"; + linux,phandle = <0x18>; + phandle = <0x18>; + }; + + serial@48024000 { + compatible = "ti,omap3-uart"; + ti,hwmods = "uart3"; + clock-frequency = <0x2dc6c00>; + reg = <0x48024000 0x2000>; + interrupts = <0x4a>; + status = "disabled"; + linux,phandle = <0x19>; + phandle = <0x19>; + }; + + serial@481a6000 { + compatible = "ti,omap3-uart"; + ti,hwmods = "uart4"; + clock-frequency = <0x2dc6c00>; + reg = <0x481a6000 0x2000>; + interrupts = <0x2c>; + status = "disabled"; + linux,phandle = <0x1a>; + phandle = <0x1a>; + }; + + serial@481a8000 { + compatible = "ti,omap3-uart"; + ti,hwmods = "uart5"; + clock-frequency = <0x2dc6c00>; + reg = <0x481a8000 0x2000>; + interrupts = <0x2d>; + status = "disabled"; + linux,phandle = <0x1b>; + phandle = <0x1b>; + }; + + serial@481aa000 { + compatible = "ti,omap3-uart"; + ti,hwmods = "uart6"; + clock-frequency = <0x2dc6c00>; + reg = <0x481aa000 0x2000>; + interrupts = <0x2e>; + status = "disabled"; + linux,phandle = <0x1c>; + phandle = <0x1c>; + }; + + i2c@44e0b000 { + compatible = "ti,omap4-i2c"; + #address-cells = <0x1>; + #size-cells = <0x0>; + ti,hwmods = "i2c1"; + reg = <0x44e0b000 0x1000>; + interrupts = <0x46>; + status = "okay"; + clock-frequency = <0x61a80>; + pinctrl-names = "default"; + pinctrl-0 = <0x6>; + linux,phandle = <0x1d>; + phandle = <0x1d>; + + tps@24 { + reg = <0x24>; + compatible = "ti,tps65217"; + ti,pmic-shutdown-controller; + interrupt-parent = <0x1>; + interrupts = <0x7>; + linux,phandle = <0x1e>; + phandle = <0x1e>; + + regulators { + #address-cells = <0x1>; + #size-cells = <0x0>; + + regulator@0 { + reg = <0x0>; + regulator-compatible = "dcdc1"; + regulator-always-on; + linux,phandle = <0x1f>; + phandle = <0x1f>; + }; + + regulator@1 { + reg = <0x1>; + regulator-compatible = "dcdc2"; + regulator-name = "vdd_mpu"; + regulator-min-microvolt = <0xe1d48>; + regulator-max-microvolt = <0x1437c8>; + regulator-boot-on; + regulator-always-on; + linux,phandle = <0x2>; + phandle = <0x2>; + }; + + regulator@2 { + reg = <0x2>; + regulator-compatible = "dcdc3"; + regulator-name = "vdd_core"; + regulator-min-microvolt = <0xe1d48>; + regulator-max-microvolt = <0x118c30>; + regulator-boot-on; + regulator-always-on; + linux,phandle = <0x20>; + phandle = <0x20>; + }; + + regulator@3 { + reg = <0x3>; + regulator-compatible = "ldo1"; + regulator-always-on; + linux,phandle = <0x21>; + phandle = <0x21>; + }; + + regulator@4 { + reg = <0x4>; + regulator-compatible = "ldo2"; + regulator-always-on; + linux,phandle = <0x22>; + phandle = <0x22>; + }; + + regulator@5 { + reg = <0x5>; + regulator-compatible = "ldo3"; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + regulator-always-on; + linux,phandle = <0x23>; + phandle = <0x23>; + }; + + regulator@6 { + reg = <0x6>; + regulator-compatible = "ldo4"; + regulator-always-on; + linux,phandle = <0x24>; + phandle = <0x24>; + }; + }; + }; + + baseboard_eeprom@50 { + compatible = "at,24c256"; + reg = <0x50>; + linux,phandle = <0xc>; + phandle = <0xc>; + }; + }; + + i2c@4802a000 { + compatible = "ti,omap4-i2c"; + #address-cells = <0x1>; + #size-cells = <0x0>; + ti,hwmods = "i2c2"; + reg = <0x4802a000 0x1000>; + interrupts = <0x47>; + status = "disabled"; + linux,phandle = <0x25>; + phandle = <0x25>; + }; + + i2c@4819c000 { + compatible = "ti,omap4-i2c"; + #address-cells = <0x1>; + #size-cells = <0x0>; + ti,hwmods = "i2c3"; + reg = <0x4819c000 0x1000>; + interrupts = <0x1e>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0x7>; + clock-frequency = <0x186a0>; + linux,phandle = <0x26>; + phandle = <0x26>; + + cape_eeprom0@54 { + compatible = "at,24c256"; + reg = <0x54>; + linux,phandle = <0xd>; + phandle = <0xd>; + }; + + cape_eeprom1@55 { + compatible = "at,24c256"; + reg = <0x55>; + linux,phandle = <0xe>; + phandle = <0xe>; + }; + + cape_eeprom2@56 { + compatible = "at,24c256"; + reg = <0x56>; + linux,phandle = <0xf>; + phandle = <0xf>; + }; + + cape_eeprom3@57 { + compatible = "at,24c256"; + reg = <0x57>; + linux,phandle = <0x10>; + phandle = <0x10>; + }; + }; + + mmc@48060000 { + compatible = "ti,omap3-hsmmc"; + ti,hwmods = "mmc1"; + ti,dual-volt; + ti,needs-special-reset; + ti,needs-special-hs-handling; + dmas = <0x8 0x18 0x8 0x19>; + dma-names = "tx", "rx"; + status = "okay"; + vmmc-supply = <0x9>; + ti,vcc-aux-disable-is-sleep; + linux,phandle = <0x27>; + phandle = <0x27>; + }; + + mmc@481d8000 { + compatible = "ti,omap3-hsmmc"; + ti,hwmods = "mmc2"; + ti,needs-special-reset; + ti,needs-special-hs-handling; + dmas = <0x8 0x2 0x8 0x3>; + dma-names = "tx", "rx"; + status = "disabled"; + vmmc-supply = <0x9>; + bus-width = <0x8>; + ti,non-removable; + reset = <0xa 0x0 0x0>; + reset-names = "eMMC_RSTn-CONSUMER"; + linux,phandle = <0x28>; + phandle = <0x28>; + }; + + mmc@47810000 { + compatible = "ti,omap3-hsmmc"; + ti,hwmods = "mmc3"; + ti,needs-special-reset; + ti,needs-special-hs-handling; + status = "disabled"; + linux,phandle = <0x29>; + phandle = <0x29>; + }; + + wdt@44e35000 { + compatible = "ti,omap3-wdt"; + ti,hwmods = "wd_timer2"; + reg = <0x44e35000 0x1000>; + interrupts = <0x5b>; + linux,phandle = <0x2a>; + phandle = <0x2a>; + }; + + d_can@481cc000 { + compatible = "bosch,d_can"; + ti,hwmods = "d_can0"; + reg = <0x481cc000 0x2000>; + interrupts = <0x34>; + status = "disabled"; + linux,phandle = <0x2b>; + phandle = <0x2b>; + }; + + d_can@481d0000 { + compatible = "bosch,d_can"; + ti,hwmods = "d_can1"; + reg = <0x481d0000 0x2000>; + interrupts = <0x37>; + status = "disabled"; + linux,phandle = <0x2c>; + phandle = <0x2c>; + }; + + timer@44e31000 { + compatible = "ti,omap2-timer"; + reg = <0x44e31000 0x400>; + interrupts = <0x43>; + ti,hwmods = "timer1"; + ti,timer-alwon; + linux,phandle = <0x2d>; + phandle = <0x2d>; + }; + + timer@48040000 { + compatible = "ti,omap2-timer"; + reg = <0x48040000 0x400>; + interrupts = <0x44>; + ti,hwmods = "timer2"; + linux,phandle = <0x2e>; + phandle = <0x2e>; + }; + + timer@48042000 { + compatible = "ti,omap2-timer"; + reg = <0x48042000 0x400>; + interrupts = <0x45>; + ti,hwmods = "timer3"; + linux,phandle = <0x2f>; + phandle = <0x2f>; + }; + + timer@48044000 { + compatible = "ti,omap2-timer"; + reg = <0x48044000 0x400>; + interrupts = <0x5c>; + ti,hwmods = "timer4"; + ti,timer-pwm; + linux,phandle = <0x30>; + phandle = <0x30>; + }; + + timer@48046000 { + compatible = "ti,omap2-timer"; + reg = <0x48046000 0x400>; + interrupts = <0x5d>; + ti,hwmods = "timer5"; + ti,timer-pwm; + linux,phandle = <0x31>; + phandle = <0x31>; + }; + + timer@48048000 { + compatible = "ti,omap2-timer"; + reg = <0x48048000 0x400>; + interrupts = <0x5e>; + ti,hwmods = "timer6"; + ti,timer-pwm; + linux,phandle = <0x32>; + phandle = <0x32>; + }; + + timer@4804a000 { + compatible = "ti,omap2-timer"; + reg = <0x4804a000 0x400>; + interrupts = <0x5f>; + ti,hwmods = "timer7"; + ti,timer-pwm; + linux,phandle = <0x33>; + phandle = <0x33>; + }; + + pruss@4a300000 { + compatible = "ti,pruss-v2"; + ti,hwmods = "pruss"; + ti,deassert-hard-reset = "pruss", "pruss"; + reg = <0x4a300000 0x80000>; + ti,pintc-offset = <0x20000>; + interrupt-parent = <0x1>; + status = "okay"; + interrupts = <0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b>; + linux,phandle = <0x34>; + phandle = <0x34>; + }; + + rtc@44e3e000 { + compatible = "ti,da830-rtc"; + reg = <0x44e3e000 0x1000>; + interrupts = <0x4b 0x4c>; + ti,hwmods = "rtc"; + ti,system-power-controller; + }; + + spi@48030000 { + compatible = "ti,omap4-mcspi"; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x48030000 0x400>; + interrupt = <0x41>; + ti,spi-num-cs = <0x2>; + ti,hwmods = "spi0"; + dmas = <0x8 0x10 0x8 0x11 0x8 0x12 0x8 0x13>; + dma-names = "tx0", "rx0", "tx1", "rx1"; + status = "disabled"; + linux,phandle = <0x35>; + phandle = <0x35>; + }; + + spi@481a0000 { + compatible = "ti,omap4-mcspi"; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x481a0000 0x400>; + interrupt = <0x7d>; + ti,spi-num-cs = <0x2>; + ti,hwmods = "spi1"; + dmas = <0x8 0x2a 0x8 0x2b 0x8 0x2c 0x8 0x2d>; + dma-names = "tx0", "rx0", "tx1", "rx1"; + status = "disabled"; + linux,phandle = <0x36>; + phandle = <0x36>; + }; + + gpmc@50000000 { + compatible = "ti,am3352-gpmc"; + ti,hwmods = "gpmc"; + reg = <0x50000000 0x1000000>; + interrupts = <0x64>; + gpmc,num-cs = <0x7>; + gpmc,num-waitpins = <0x2>; + #address-cells = <0x2>; + #size-cells = <0x1>; + status = "disabled"; + linux,phandle = <0x37>; + phandle = <0x37>; + }; + + nop-phy@0 { + compatible = "nop-xceiv-usb"; + }; + + nop-phy@1 { + compatible = "nop-xceiv-usb"; + }; + + usb@47400000 { + compatible = "ti,musb-am33xx"; + reg = <0x47400000 0x1000 0x47401000 0x800 0x47401800 0x800>; + interrupts = <0x11 0x12 0x13>; + multipoint = <0x1>; + num-eps = <0x10>; + ram-bits = <0xc>; + port0-mode = <0x3>; + port1-mode = <0x1>; + power = <0xfa>; + ti,hwmods = "usb_otg_hs"; + status = "okay"; + interface_type = <0x1>; + linux,phandle = <0x38>; + phandle = <0x38>; + }; + + ethernet@4a100000 { + compatible = "ti,cpsw"; + ti,hwmods = "cpgmac0"; + cpdma_channels = <0x8>; + ale_entries = <0x400>; + bd_ram_size = <0x2000>; + no_bd_ram = <0x0>; + rx_descs = <0x40>; + mac_control = <0x20>; + slaves = <0x2>; + cpts_active_slave = <0x0>; + cpts_clock_mult = <0x80000000>; + cpts_clock_shift = <0x1d>; + reg = <0x4a100000 0x800 0x4a101200 0x100>; + #address-cells = <0x1>; + #size-cells = <0x1>; + interrupt-parent = <0x1>; + interrupts = <0x28 0x29 0x2a 0x2b>; + ranges; + disable-napi; + linux,phandle = <0x39>; + phandle = <0x39>; + + mdio@4a101000 { + compatible = "ti,davinci_mdio"; + #address-cells = <0x1>; + #size-cells = <0x0>; + ti,hwmods = "davinci_mdio"; + bus_freq = <0xf4240>; + reg = <0x4a101000 0x100>; + linux,phandle = <0xb>; + phandle = <0xb>; + }; + + slave@4a100200 { + mac-address = [00 00 00 00 00 00]; + phy_id = <0xb 0x0>; + linux,phandle = <0x3a>; + phandle = <0x3a>; + }; + + slave@4a100300 { + mac-address = [00 00 00 00 00 00]; + phy_id = <0xb 0x1>; + linux,phandle = <0x3b>; + phandle = <0x3b>; + }; + }; + + tscadc@44e0d000 { + compatible = "ti,ti-tscadc"; + reg = <0x44e0d000 0x1000>; + interrupt-parent = <0x1>; + interrupts = <0x10>; + ti,hwmods = "adc_tsc"; + status = "disabled"; + linux,phandle = <0x3c>; + phandle = <0x3c>; + }; + + lcdc@4830e000 { + compatible = "ti,am3352-lcdc", "ti,da830-lcdc"; + reg = <0x4830e000 0x1000>; + interrupts = <0x24>; + status = "disabled"; + ti,hwmods = "lcdc"; + linux,phandle = <0x3d>; + phandle = <0x3d>; + }; + + epwmss@48300000 { + compatible = "ti,am33xx-pwmss"; + reg = <0x48300000 0x10>; + ti,hwmods = "epwmss0"; + #address-cells = <0x1>; + #size-cells = <0x1>; + status = "disabled"; + ranges = <0x48300100 0x48300100 0x80 0x48300180 0x48300180 0x80 0x48300200 0x48300200 0x80>; + linux,phandle = <0x3e>; + phandle = <0x3e>; + + ecap@48300100 { + compatible = "ti,am33xx-ecap"; + #pwm-cells = <0x3>; + reg = <0x48300100 0x80>; + ti,hwmods = "ecap0"; + status = "disabled"; + linux,phandle = <0x3f>; + phandle = <0x3f>; + }; + + ehrpwm@48300200 { + compatible = "ti,am33xx-ehrpwm"; + #pwm-cells = <0x3>; + reg = <0x48300200 0x80>; + ti,hwmods = "ehrpwm0"; + status = "disabled"; + linux,phandle = <0x40>; + phandle = <0x40>; + }; + }; + + epwmss@48302000 { + compatible = "ti,am33xx-pwmss"; + reg = <0x48302000 0x10>; + ti,hwmods = "epwmss1"; + #address-cells = <0x1>; + #size-cells = <0x1>; + status = "disabled"; + ranges = <0x48302100 0x48302100 0x80 0x48302180 0x48302180 0x80 0x48302200 0x48302200 0x80>; + linux,phandle = <0x41>; + phandle = <0x41>; + + ecap@48302100 { + compatible = "ti,am33xx-ecap"; + #pwm-cells = <0x3>; + reg = <0x48302100 0x80>; + ti,hwmods = "ecap1"; + status = "disabled"; + linux,phandle = <0x42>; + phandle = <0x42>; + }; + + ehrpwm@48302200 { + compatible = "ti,am33xx-ehrpwm"; + #pwm-cells = <0x3>; + reg = <0x48302200 0x80>; + ti,hwmods = "ehrpwm1"; + status = "disabled"; + linux,phandle = <0x43>; + phandle = <0x43>; + }; + }; + + epwmss@48304000 { + compatible = "ti,am33xx-pwmss"; + reg = <0x48304000 0x10>; + ti,hwmods = "epwmss2"; + #address-cells = <0x1>; + #size-cells = <0x1>; + status = "disabled"; + ranges = <0x48304100 0x48304100 0x80 0x48304180 0x48304180 0x80 0x48304200 0x48304200 0x80>; + linux,phandle = <0x44>; + phandle = <0x44>; + + ecap@48304100 { + compatible = "ti,am33xx-ecap"; + #pwm-cells = <0x3>; + reg = <0x48304100 0x80>; + ti,hwmods = "ecap2"; + status = "disabled"; + linux,phandle = <0x45>; + phandle = <0x45>; + }; + + ehrpwm@48304200 { + compatible = "ti,am33xx-ehrpwm"; + #pwm-cells = <0x3>; + reg = <0x48304200 0x80>; + ti,hwmods = "ehrpwm2"; + status = "disabled"; + linux,phandle = <0x46>; + phandle = <0x46>; + }; + }; + + sham@53100000 { + compatible = "ti,omap4-sham"; + ti,hwmods = "sham"; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x53100000 0x200>; + interrupt-parent = <0x1>; + interrupts = <0x6d>; + dmas = <0x8 0x24>; + dma-names = "rx"; + status = "okay"; + linux,phandle = <0x47>; + phandle = <0x47>; + }; + + aes@53500000 { + compatible = "ti,omap4-aes"; + ti,hwmods = "aes"; + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x53500000 0xa0>; + interrupt-parent = <0x1>; + interrupts = <0x66>; + dmas = <0x8 0x6 0x8 0x5>; + dma-names = "tx", "rx"; + status = "okay"; + linux,phandle = <0x48>; + phandle = <0x48>; + }; + + mcasp@48038000 { + compatible = "ti,omap2-mcasp-audio"; + #address-cells = <0x1>; + #size-cells = <0x0>; + ti,hwmods = "mcasp0"; + reg = <0x48038000 0x2000>; + interrupts = <0x50 0x51>; + status = "disabled"; + asp-chan-q = <0x2>; + tx-dma-offset = <0x46000000>; + rx-dma-offset = <0x46000000>; + dmas = <0x8 0x8 0x8 0x9>; + dma-names = "tx", "rx"; + linux,phandle = <0x49>; + phandle = <0x49>; + }; + + mcasp@4803C000 { + compatible = "ti,omap2-mcasp-audio"; + #address-cells = <0x1>; + #size-cells = <0x0>; + ti,hwmods = "mcasp1"; + reg = <0x4803c000 0x2000>; + interrupts = <0x52 0x53>; + status = "disabled"; + asp-chan-q = <0x2>; + tx-dma-offset = <0x46400000>; + rx-dma-offset = <0x46400000>; + dmas = <0x8 0xa 0x8 0xb>; + dma-names = "tx", "rx"; + linux,phandle = <0x4a>; + phandle = <0x4a>; + }; + + gpio-leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <0x3>; + + led0 { + label = "beaglebone:green:usr0"; + gpios = <0x5 0x15 0x0>; + linux,default-trigger = "heartbeat"; + default-state = "off"; + }; + + led1 { + label = "beaglebone:green:usr1"; + gpios = <0x5 0x16 0x0>; + linux,default-trigger = "mmc0"; + default-state = "off"; + }; + + led2 { + label = "beaglebone:green:usr2"; + gpios = <0x5 0x17 0x0>; + linux,default-trigger = "cpu0"; + default-state = "off"; + }; + + led3 { + label = "beaglebone:green:usr3"; + gpios = <0x5 0x18 0x0>; + default-state = "off"; + linux,default-trigger = "mmc1"; + }; + }; + }; + + bone_capemgr { + compatible = "ti,bone-capemgr"; + status = "okay"; + eeprom = <0xc>; + + baseboardmaps { + + board@0 { + board-name = "A335BONE"; + compatible-name = "ti,beaglebone"; + linux,phandle = <0x4b>; + phandle = <0x4b>; + }; + + board@1 { + board-name = "A335BNLT"; + compatible-name = "ti,beaglebone-black"; + linux,phandle = <0x4c>; + phandle = <0x4c>; + }; + }; + + slots { + + slot@0 { + eeprom = <0xd>; + }; + + slot@1 { + eeprom = <0xe>; + }; + + slot@2 { + eeprom = <0xf>; + }; + + slot@3 { + eeprom = <0x10>; + }; + + slot@5 { + ti,cape-override; + compatible = "kernel-command-line", "runtime"; + board-name = "Bone-Geiger"; + version = "00A0"; + manufacturer = "Geiger Inc."; + part-number = "BB-BONE-GEIGER"; + }; + + slot@7 { + ti,cape-override; + compatible = "kernel-command-line", "runtime"; + board-name = "Bone-Nixie"; + version = "00A0"; + manufacturer = "Ranostay Industries"; + part-number = "BB-BONE-NIXIE"; + }; + + slot@8 { + ti,cape-override; + compatible = "kernel-command-line", "runtime"; + board-name = "Bone-TFT"; + version = "00A0"; + manufacturer = "Adafruit"; + part-number = "BB-BONE-TFT-01"; + }; + + slot@9 { + ti,cape-override; + compatible = "kernel-command-line", "runtime"; + board-name = "Bone-RTC"; + version = "00A0"; + manufacturer = "Adafruit"; + part-number = "BB-BONE-RTC-01"; + }; + + slot@10 { + ti,cape-override; + compatible = "kernel-command-line", "runtime"; + board-name = "Bone-Hexy"; + version = "00A0"; + manufacturer = "Koen Kooi"; + part-number = "BB-BONE-HEXY-01"; + }; + + slot@11 { + ti,cape-override; + compatible = "kernel-command-line", "runtime"; + board-name = "Bone-MRF24J40"; + version = "00A0"; + manufacturer = "Signal 11 Software"; + part-number = "BB-BONE-MRF24J40"; + }; + + slot@12 { + ti,cape-override; + compatible = "kernel-command-line", "runtime"; + board-name = "BB-BONE-RS232"; + version = "00A0"; + manufacturer = "Adafruit"; + part-number = "BB-BONE-RS232-01"; + }; + + slot@100 { + ti,cape-override; + priority = <0x1>; + compatible = "ti,beaglebone-black"; + board-name = "Bone-LT-eMMC-2G"; + version = "00A0"; + manufacturer = "Texas Instruments"; + part-number = "BB-BONE-EMMC-2G"; + }; + + slot@101 { + ti,cape-override; + priority = <0x1>; + compatible = "ti,beaglebone-black"; + board-name = "Bone-Black-HDMI"; + version = "00A0"; + manufacturer = "Texas Instruments"; + part-number = "BB-BONELT-HDMI"; + }; + + slot@102 { + ti,cape-override; + priority = <0x2>; + compatible = "ti,beaglebone-black"; + board-name = "Bone-Black-HDMIN"; + version = "00A0"; + manufacturer = "Texas Instruments"; + part-number = "BB-BONELT-HDMIN"; + }; + }; + + capemaps { + + cape@0 { + part-number = "BB-BONE-DVID-01"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-dvi-00A0.dtbo"; + }; + + version@00A1 { + version = "00A1", "01"; + dtbo = "cape-bone-dvi-00A1.dtbo"; + }; + + version@00A2 { + version = "00A2", "A2"; + dtbo = "cape-bone-dvi-00A2.dtbo"; + }; + + version@00A3 { + version = "00A3"; + dtbo = "cape-bone-dvi-00A2.dtbo"; + }; + }; + + cape@1 { + part-number = "BB-BONE-EMMC-2G"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-2g-emmc1.dtbo"; + }; + }; + + cape@2 { + part-number = "BB-BONE-GEIGER"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-geiger-00A0.dtbo"; + }; + }; + + cape@3 { + part-number = "BB-BONE-LCD3-01"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-lcd3-00A0.dtbo"; + }; + + version@00A2 { + version = "00A2"; + dtbo = "cape-bone-lcd3-00A2.dtbo"; + }; + }; + + cape@4 { + part-number = "BB-BONE-WTHR-01"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-weather-00A0.dtbo"; + }; + }; + + cape@5 { + part-number = "BB-BONELT-HDMI"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-boneblack-hdmi-00A0.dtbo"; + }; + }; + + cape@6 { + part-number = "BB-BONE-NIXIE"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-nixie-00A0.dtbo"; + }; + }; + + cape@7 { + part-number = "BB-BONE-TFT-01"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-adafruit-lcd-00A0.dtbo"; + }; + }; + + cape@8 { + part-number = "BB-BONE-RTC-01"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-adafruit-rtc-00A0.dtbo"; + }; + }; + + cape@9 { + part-number = "BB-BONE-HEXY-01"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-hexy-00A0.dtbo"; + }; + }; + + cape@10 { + part-number = "BB-BONE-MRF24J40"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-mrf24j40-00A0.dtbo"; + }; + }; + + cape@11 { + part-number = "BB-BONE-EXPTEST"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-bone-exptest-00A0.dtbo"; + }; + }; + + cape@12 { + part-number = "BB-BONE-RS232-01"; + + version@00A0 { + version = "00A0"; + dtbo = "BB-BONE-RS232-00A0.dtbo"; + }; + }; + + cape@13 { + part-number = "BB-BONELT-HDMIN"; + + version@00A0 { + version = "00A0"; + dtbo = "cape-boneblack-hdmin-00A0.dtbo"; + }; + }; + }; + }; + + fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "vmmcsd_fixed"; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + linux,phandle = <0x9>; + phandle = <0x9>; + }; + + __symbols__ { + cpu = "/cpus/cpu@0"; + am33xx_pinmux = "/pinmux@44e10800"; + userled_pins = "/pinmux@44e10800/pinmux_userled_pins"; + i2c0_pins = "/pinmux@44e10800/pinmux_i2c0_pins"; + i2c2_pins = "/pinmux@44e10800/pinmux_i2c2_pins"; + rstctl_pins = "/pinmux@44e10800/pinmux_rstctl_pins"; + ocp = "/ocp"; + intc = "/ocp/interrupt-controller@48200000"; + edma = "/ocp/edma@49000000"; + gpio1 = "/ocp/gpio@44e07000"; + gpio2 = "/ocp/gpio@4804c000"; + gpio3 = "/ocp/gpio@481ac000"; + gpio4 = "/ocp/gpio@481ae000"; + rstctl = "/ocp/rstctl@0"; + uart1 = "/ocp/serial@44e09000"; + uart2 = "/ocp/serial@48022000"; + uart3 = "/ocp/serial@48024000"; + uart4 = "/ocp/serial@481a6000"; + uart5 = "/ocp/serial@481a8000"; + uart6 = "/ocp/serial@481aa000"; + i2c0 = "/ocp/i2c@44e0b000"; + tps = "/ocp/i2c@44e0b000/tps@24"; + dcdc1_reg = "/ocp/i2c@44e0b000/tps@24/regulators/regulator@0"; + dcdc2_reg = "/ocp/i2c@44e0b000/tps@24/regulators/regulator@1"; + dcdc3_reg = "/ocp/i2c@44e0b000/tps@24/regulators/regulator@2"; + ldo1_reg = "/ocp/i2c@44e0b000/tps@24/regulators/regulator@3"; + ldo2_reg = "/ocp/i2c@44e0b000/tps@24/regulators/regulator@4"; + ldo3_reg = "/ocp/i2c@44e0b000/tps@24/regulators/regulator@5"; + ldo4_reg = "/ocp/i2c@44e0b000/tps@24/regulators/regulator@6"; + baseboard_eeprom = "/ocp/i2c@44e0b000/baseboard_eeprom@50"; + i2c1 = "/ocp/i2c@4802a000"; + i2c2 = "/ocp/i2c@4819c000"; + cape_eeprom0 = "/ocp/i2c@4819c000/cape_eeprom0@54"; + cape_eeprom1 = "/ocp/i2c@4819c000/cape_eeprom1@55"; + cape_eeprom2 = "/ocp/i2c@4819c000/cape_eeprom2@56"; + cape_eeprom3 = "/ocp/i2c@4819c000/cape_eeprom3@57"; + mmc1 = "/ocp/mmc@48060000"; + mmc2 = "/ocp/mmc@481d8000"; + mmc3 = "/ocp/mmc@47810000"; + wdt2 = "/ocp/wdt@44e35000"; + dcan0 = "/ocp/d_can@481cc000"; + dcan1 = "/ocp/d_can@481d0000"; + timer1 = "/ocp/timer@44e31000"; + timer2 = "/ocp/timer@48040000"; + timer3 = "/ocp/timer@48042000"; + timer4 = "/ocp/timer@48044000"; + timer5 = "/ocp/timer@48046000"; + timer6 = "/ocp/timer@48048000"; + timer7 = "/ocp/timer@4804a000"; + pruss = "/ocp/pruss@4a300000"; + spi0 = "/ocp/spi@48030000"; + spi1 = "/ocp/spi@481a0000"; + gpmc = "/ocp/gpmc@50000000"; + usb_otg_hs = "/ocp/usb@47400000"; + mac = "/ocp/ethernet@4a100000"; + davinci_mdio = "/ocp/ethernet@4a100000/mdio@4a101000"; + cpsw_emac0 = "/ocp/ethernet@4a100000/slave@4a100200"; + cpsw_emac1 = "/ocp/ethernet@4a100000/slave@4a100300"; + tscadc = "/ocp/tscadc@44e0d000"; + lcdc = "/ocp/lcdc@4830e000"; + epwmss0 = "/ocp/epwmss@48300000"; + ecap0 = "/ocp/epwmss@48300000/ecap@48300100"; + ehrpwm0 = "/ocp/epwmss@48300000/ehrpwm@48300200"; + epwmss1 = "/ocp/epwmss@48302000"; + ecap1 = "/ocp/epwmss@48302000/ecap@48302100"; + ehrpwm1 = "/ocp/epwmss@48302000/ehrpwm@48302200"; + epwmss2 = "/ocp/epwmss@48304000"; + ecap2 = "/ocp/epwmss@48304000/ecap@48304100"; + ehrpwm2 = "/ocp/epwmss@48304000/ehrpwm@48304200"; + sham = "/ocp/sham@53100000"; + aes = "/ocp/aes@53500000"; + mcasp0 = "/ocp/mcasp@48038000"; + mcasp1 = "/ocp/mcasp@4803C000"; + baseboard_beaglebone = "/bone_capemgr/baseboardmaps/board@0"; + baseboard_beaglebone_black = "/bone_capemgr/baseboardmaps/board@1"; + vmmcsd_fixed = "/fixedregulator@0"; + }; +}; From 22ee3aee17217a0b45929f2497209a7ea7d52c37 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 12 Jan 2014 03:10:29 +0000 Subject: [PATCH 169/332] enable pru --- dts/ubuntu-3.8.13-bone32.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/ubuntu-3.8.13-bone32.dts b/dts/ubuntu-3.8.13-bone32.dts index 810dc85e..921da884 100644 --- a/dts/ubuntu-3.8.13-bone32.dts +++ b/dts/ubuntu-3.8.13-bone32.dts @@ -570,7 +570,7 @@ reg = <0x4a300000 0x80000>; ti,pintc-offset = <0x20000>; interrupt-parent = <0x1>; - status = "disabled"; + status = "okay"; interrupts = <0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b>; linux,phandle = <0x35>; phandle = <0x35>; From 09dad16afbf6987a486a5c19dae1966d2fd0265a Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 12 Jan 2014 03:22:32 +0000 Subject: [PATCH 170/332] DTS files --- dts/README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 dts/README.md diff --git a/dts/README.md b/dts/README.md new file mode 100644 index 00000000..f73001fa --- /dev/null +++ b/dts/README.md @@ -0,0 +1,18 @@ +Generate DTS from DTB: + + dtc \ + -I dtb \ + -O dts \ + -o ubuntu-`uname -r`.dts \ + /boot/uboot/dtbs/am335x-boneblack.dtb + +Enable the PRU. Change status from "disabled" to "okay" + + +Generate DTB back from DTS: + + dtc \ + -O dtb \ + -I dts \ + -o /boot/uboot/dtbs/am335x-boneblack.dtb \ + ubuntu-`uname -r`.dts From bd20fbbfeb3a60a5a8e3fa6e4270027a5620e870 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 15 Jan 2014 13:17:54 -0500 Subject: [PATCH 171/332] Fix brightness so that it is visible on the matrix --- matrix-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-test.c b/matrix-test.c index 4c875a33..9a9cb39a 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -98,7 +98,7 @@ rainbow( ) { const unsigned color = cycle % 180; - const unsigned dim = 8; + const unsigned dim = 128; for (unsigned x=0; x < width; x++) { for (unsigned y=0; y < height; y++) { From eac1795f50b801301d913773e6f1e4cf01a384a3 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 24 Jan 2014 22:51:11 +0000 Subject: [PATCH 172/332] C++ fixes --- src/ledscape/ledscape.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ledscape/ledscape.h b/src/ledscape/ledscape.h index 5267bb36..da6234df 100644 --- a/src/ledscape/ledscape.h +++ b/src/ledscape/ledscape.h @@ -83,6 +83,10 @@ typedef struct { typedef struct ledscape ledscape_t; +#ifdef __cplusplus +extern "C" { +#endif + extern ledscape_config_t ledscape_matrix_default; extern ledscape_t * @@ -147,4 +151,8 @@ ledscape_config( const char * filename ); +#ifdef __cplusplus +}; +#endif + #endif From c6e5839773beb45a9cb76a6f5eb29baefadaa26a Mon Sep 17 00:00:00 2001 From: root Date: Fri, 24 Jan 2014 22:51:28 +0000 Subject: [PATCH 173/332] C++ fixes --- Makefile.common | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Makefile.common b/Makefile.common index 775d880b..d52a2816 100644 --- a/Makefile.common +++ b/Makefile.common @@ -29,9 +29,8 @@ else export CROSS_COMPILE?=arm-linux-gnueabi- endif -CFLAGS += \ +GENERIC_CFLAGS += \ -g \ - -std=c99 \ -W \ -Wall \ -D_BSD_SOURCE \ @@ -43,6 +42,13 @@ CFLAGS += \ -mtune=cortex-a8 \ -march=armv7-a \ +CFLAGS += \ + -std=c99 \ + $(GENERIC_CFLAGS) \ + +CPPFLAGS += \ + $(GENERIC_CFLAGS) \ + LDFLAGS += \ LDLIBS += \ @@ -51,12 +57,15 @@ LDLIBS += \ -lpthread \ -lm \ -COMPILE.o = $(CROSS_COMPILE)gcc $(CFLAGS) -c -o $@ $< +COMPILE.c-o = $(CROSS_COMPILE)gcc $(CFLAGS) -c -o $@ $< +COMPILE.cpp-o = $(CROSS_COMPILE)g++ $(CPPFLAGS) -c -o $@ $< COMPILE.a = $(CROSS_COMPILE)ar crv $@ $^ -COMPILE.link = $(CROSS_COMPILE)gcc $(LDFLAGS) -o $@ $^ $(LDLIBS) +COMPILE.link = $(CROSS_COMPILE)g++ $(LDFLAGS) -o $@ $^ $(LDLIBS) $(OBJDIR)/%.o: %.c - $(COMPILE.o) + $(COMPILE.c-o) +$(OBJDIR)/%.o: %.cpp + $(COMPILE.cpp-o) $(LIBDIR)/%.a: $(RM) $@ From 72647e0ede490bdc34a368569a813ac7f328d3ca Mon Sep 17 00:00:00 2001 From: root Date: Fri, 24 Jan 2014 22:52:28 +0000 Subject: [PATCH 174/332] import of GPLed perlin noise code and wrapper for ledscape --- src/perlin/Makefile | 28 ++++ src/perlin/gammalut.h | 46 ++++++ src/perlin/globals.h | 30 ++++ src/perlin/pattern.cpp | 96 ++++++++++++ src/perlin/pattern.h | 59 +++++++ src/perlin/pf2.cpp | 339 +++++++++++++++++++++++++++++++++++++++++ src/perlin/pf2.h | 135 ++++++++++++++++ 7 files changed, 733 insertions(+) create mode 100644 src/perlin/Makefile create mode 100644 src/perlin/gammalut.h create mode 100644 src/perlin/globals.h create mode 100644 src/perlin/pattern.cpp create mode 100644 src/perlin/pattern.h create mode 100644 src/perlin/pf2.cpp create mode 100644 src/perlin/pf2.h diff --git a/src/perlin/Makefile b/src/perlin/Makefile new file mode 100644 index 00000000..24fc037f --- /dev/null +++ b/src/perlin/Makefile @@ -0,0 +1,28 @@ +#============================================================================================== +# LED Matrix Animated Pattern Generator +# Copyright 2014 by Glen Akins. +# All rights reserved. +# +# Set editor width to 96 and tab stop to 4. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +#============================================================================================== + +BIN-y += perlin +perlin.srcs += \ + perlin-ledscape.cpp \ + pf2.cpp \ + pattern.cpp \ + +include ../../Makefile.common diff --git a/src/perlin/gammalut.h b/src/perlin/gammalut.h new file mode 100644 index 00000000..79a6346a --- /dev/null +++ b/src/perlin/gammalut.h @@ -0,0 +1,46 @@ +//============================================================================================= +// LED Matrix Animated Pattern Generator +// Adafruit LED Panel Gamma Lookup Table +// Modified by Glen Akins, Feb 2014 +// Table renamed to prevent conflicts with names of functions in math.h. +//============================================================================================= + +#ifndef __gammalut_h_ +#define __gammalut_h_ + +static const uint8_t gammaLut[] = { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02, + 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x03, + 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03, + 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, + 0x04,0x04,0x04,0x04,0x04,0x04,0x05,0x05, + 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05, + 0x05,0x05,0x05,0x06,0x06,0x06,0x06,0x06, + 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x07, + 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, + 0x07,0x07,0x08,0x08,0x08,0x08,0x08,0x08, + 0x08,0x08,0x08,0x08,0x09,0x09,0x09,0x09, + 0x09,0x09,0x09,0x09,0x09,0x0a,0x0a,0x0a, + 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0b,0x0b, + 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0c,0x0c, + 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0d,0x0d, + 0x0d,0x0d,0x0d,0x0d,0x0d,0x0e,0x0e,0x0e, + 0x0e,0x0e,0x0e,0x0e,0x0f,0x0f,0x0f,0x0f +}; + +#endif diff --git a/src/perlin/globals.h b/src/perlin/globals.h new file mode 100644 index 00000000..ab2e6133 --- /dev/null +++ b/src/perlin/globals.h @@ -0,0 +1,30 @@ +//============================================================================================= +// LED Matrix Animated Pattern Generator +// Copyright 2014 by Glen Akins. +// All rights reserved. +// +// Set editor width to 96 and tab stop to 4. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +//============================================================================================= + +#ifndef __globals_h_ +#define __globals_h_ + +#define DISPLAY_WIDTH 256 +#define DISPLAY_HEIGHT 128 + +extern uint16_t gLevels[DISPLAY_HEIGHT][DISPLAY_WIDTH]; + +#endif diff --git a/src/perlin/pattern.cpp b/src/perlin/pattern.cpp new file mode 100644 index 00000000..fa087e0f --- /dev/null +++ b/src/perlin/pattern.cpp @@ -0,0 +1,96 @@ +//============================================================================================= +// LED Matrix Animated Pattern Generator +// Copyright 2014 by Glen Akins. +// All rights reserved. +// +// Set editor width to 96 and tab stop to 4. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +//============================================================================================= + +#include +#include +#include + +#include "globals.h" +#include "gammalut.h" +#include "pattern.h" + +#define MAKE_COLOR(r,g,b) (((r)&0xf)<<8)+(((g)&0xf)<<4)+((b)&0xf) + +//--------------------------------------------------------------------------------------------- +// convert a hue from 0 to 95 to its 12-bit RGB color +// +// hue: 0 = red, 32 = blue, 64 = green +// + +uint16_t Pattern::translateHue (int32_t hue) +{ + uint8_t hi, lo; + uint8_t r, g, b; + + hi = hue >> 4; + lo = ((hue & 0xf) << 4) | (hue & 0xf); + + switch (hi) { + case 0: r = 0xff; g = 0; b = lo; break; + case 1: r = 0xff-lo, g = 0, b = 0xff; break; + case 2: r = 0, g = lo, b = 0xff; break; + case 3: r = 0, g = 0xff, b = 0xff-lo; break; + case 4: r = lo, g = 0xff, b = 0; break; + case 5: r = 0xff, g = 0xff-lo, b = 0; break; + } + + r = gammaLut[r]; + g = gammaLut[g]; + b = gammaLut[b]; + + return MAKE_COLOR (r,g,b); +} + + +//--------------------------------------------------------------------------------------------- +// convert a hue from 0 to 95 and a brightnewss from 0 to 1.0 to its 12-bit RGB color +// +// hue: 0 = red, 32 = blue, 64 = green +// value: 0 = off, 1.0 = 100% +// + +uint16_t Pattern::translateHueValue (int32_t hue, float value) +{ + uint8_t hi, lo; + uint8_t r, g, b; + + hi = hue >> 4; + lo = ((hue & 0xf) << 4) | (hue & 0xf); + + switch (hi) { + case 0: r = 0xff; g = 0; b = lo; break; + case 1: r = 0xff-lo, g = 0, b = 0xff; break; + case 2: r = 0, g = lo, b = 0xff; break; + case 3: r = 0, g = 0xff, b = 0xff-lo; break; + case 4: r = lo, g = 0xff, b = 0; break; + case 5: r = 0xff, g = 0xff-lo, b = 0; break; + } + + r = ((float)r + 0.5) * value; + g = ((float)g + 0.5) * value; + b = ((float)b + 0.5) * value; + + r = gammaLut[r]; + g = gammaLut[g]; + b = gammaLut[b]; + + return MAKE_COLOR (r,g,b); +} diff --git a/src/perlin/pattern.h b/src/perlin/pattern.h new file mode 100644 index 00000000..bc263d0d --- /dev/null +++ b/src/perlin/pattern.h @@ -0,0 +1,59 @@ +//============================================================================================= +// LED Matrix Animated Pattern Generator +// Copyright 2014 by Glen Akins. +// All rights reserved. +// +// Set editor width to 96 and tab stop to 4. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +//============================================================================================= + +#ifndef __pattern_h_ +#define __pattern_h_ + +extern const uint8_t gammaLut[]; + +class Pattern +{ + public: + + // constructor + Pattern (const int32_t width, const int32_t height) : + m_width(width), m_height(height) { } + + // destructor + ~Pattern (void) { } + + // reset to first frame in animation + virtual void init (void) = 0; + + // calculate next frame in the animation + virtual bool next (void) = 0; + + // get width and height + void getDimensions (int32_t &width, int32_t &height) { + width = m_width; height = m_height; + } + + uint16_t translateHue (int32_t hue); + uint16_t translateHueValue (int32_t hue, float value); + + protected: + const int32_t m_width; + const int32_t m_height; + + private: +}; + +#endif diff --git a/src/perlin/pf2.cpp b/src/perlin/pf2.cpp new file mode 100644 index 00000000..7bdb2e6c --- /dev/null +++ b/src/perlin/pf2.cpp @@ -0,0 +1,339 @@ +//============================================================================================= +// LED Matrix Animated Pattern Generator +// Copyright 2014 by Glen Akins. +// All rights reserved. +// +// Set editor width to 96 and tab stop to 4. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Major inspiration for the use of Perlin noise to generate pseudorandom RGB patterns comes +// from the TI RGB LED coffee table project and the following resources: +// +// TI RGB LED Coffee Table: +// +// http://e2e.ti.com/group/microcontrollerprojects/m/msp430microcontrollerprojects/447779.aspx +// https://github.com/bear24rw/rgb_table/tree/master/code/table_drivers/pytable +// +// Casey Duncan's Python C Noise Library: +// +// https://github.com/caseman/noise +// +// Ken Perlin's Original Source Code: +// +// http://www.mrl.nyu.edu/~perlin/doc/oscar.html +// +// Excellent explanation of Perlin noise and seamless looping and tiling here: +// +// http://webstaff.itn.liu.se/~stegu/TNM022-2005/perlinnoiselinks/perlin-noise-math-faq.html +// +//============================================================================================= + +#include +#include +#include +#include +#include + +#include "globals.h" +#include "pattern.h" +#include "pf2.h" + + +//--------------------------------------------------------------------------------------------- +// constructors +// + +Perlin::Perlin +( + const int32_t width, const int32_t height, const int32_t mode +) : + Pattern (width, height), + m_mode (mode), m_xy_scale(8.0/64.0*256.0), + m_z_step(0.0125), m_z_depth(512.0), + m_hue_options(0.005) +{ +} + + +Perlin::Perlin ( + const int32_t width, const int32_t height, + const int32_t mode, const float xy_scale, + const float z_step, const float z_depth, + const float hue_options +) : + Pattern (width, height), + m_mode (mode), m_xy_scale(xy_scale*256.0), + m_z_step(z_step), m_z_depth(z_depth), + m_hue_options(hue_options) +{ +} + + +//--------------------------------------------------------------------------------------------- +// destructor +// + +Perlin::~Perlin (void) +{ +} + + +//--------------------------------------------------------------------------------------------- +// init -- reset to first frame in animation +// + +void Perlin::init (void) +{ + // reset to z=0 plane + m_z_state = 0.0; + + // reset to red, only used for modes two and three + m_hue_state = 0.0; + + // reset normalization min and max + m_min = 1; + m_max = 1; +} + + +//--------------------------------------------------------------------------------------------- +// next -- calculate next frame in animation +// + +bool Perlin::next (void) +{ + int32_t x, y; + uint16_t sx, sy; + int32_t n1, n2; + float n; + int32_t hue; + + int16_t sz1 = (float)m_z_state * 256.0; + int16_t sz2 = (float)(m_z_state - m_z_depth) * 256.0; + + // row + for (y = 0; y < m_height; y++) { + + // scale y + sy = y * m_xy_scale; + + // column + for (x = 0; x < m_width; x++) { + + // scale x + sx = x * m_xy_scale; + + // generate noise at plane z_state + n1 = this->noise (sx, sy, sz1); + + // generate noise at plane z_state - z_depth + n2 = this->noise (sx, sy, sz2); + + // combine noises to make a seamless transition from plane + // at z = z_depth back to plane at z = 0 + n = ((m_z_depth - m_z_state) * (float)n1 + (m_z_state) * (float)n2) / m_z_depth; + + // normalize combined noises to a number between 0 and 1 + if (n > m_max) m_max = n; + if (n < m_min) m_min = n; + n = n + fabs (m_min); // make noise a positive value + n = n / (m_max + fabs (m_min)); // scale noise to between 0 and 1 + + // set hue and/or brightness based on mode + switch (m_mode) { + + // base hue fixed, varies based on noise + case 1: + hue = (m_hue_options + n)*96.0 + 0.5; + hue = hue % 96; + gLevels[y][x] = this->translateHue (hue); + break; + + // hue rotates at constant velocity, varies based on noise + case 2: + hue = (m_hue_state + n)*96.0 + 0.5; + hue = hue % 96; + gLevels[y][x] = this->translateHue (hue); + break; + + // hue rotates at constant velocity, brightness varies based on noise + case 3: + hue = (m_hue_state)*96.0 + 0.5; + hue = hue % 96; + gLevels[y][x] = this->translateHueValue (hue, n); + break; + + // undefined mode, blank display + default: + gLevels[x][y] = 0; + break; + + } + } + } + + // update state variables + m_z_state = fmod (m_z_state + m_z_step, m_z_depth); + m_hue_state = fmod (m_hue_state + m_hue_options, 1.0); + + return true; +} + + +//--------------------------------------------------------------------------------------------- +// noise +// + +#define lerp1(t, a, b) (((a)<<12) + (t) * ((b) - (a))) + +static const int8_t GRAD3[16][3] = { + {1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0}, + {1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1}, + {0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}, + {1,0,-1},{-1,0,-1},{0,-1,1},{0,1,1}}; + +static const uint8_t PERM[512] = { + 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, + 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, + 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, + 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, + 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, + 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, + 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, + 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, + 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, + 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, + 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, + 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, + 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, + 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, + 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, + 141, 128, 195, 78, 66, 215, 61, 156, 180, 151, 160, 137, 91, 90, 15, 131, + 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, + 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, + 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, + 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, + 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, + 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, + 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, + 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, + 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, + 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, + 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, + 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, + 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, + 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, + 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, + 180}; + +static const uint16_t easing_function_lut[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 3, 4, 6, 7, + 9, 10, 12, 14, 17, 19, 22, 25, 29, 32, 36, 40, 45, 49, 54, 60, + 65, 71, 77, 84, 91, 98, 105, 113, 121, 130, 139, 148, 158, 167, 178, 188, + 199, 211, 222, 234, 247, 259, 273, 286, 300, 314, 329, 344, 359, 374, 390, 407, + 424, 441, 458, 476, 494, 512, 531, 550, 570, 589, 609, 630, 651, 672, 693, 715, + 737, 759, 782, 805, 828, 851, 875, 899, 923, 948, 973, 998, 1023, 1049, 1074, 1100, + 1127, 1153, 1180, 1207, 1234, 1261, 1289, 1316, 1344, 1372, 1400, 1429, 1457, 1486, 1515, + 1543, 1572, 1602, 1631, 1660, 1690, 1719, 1749, 1778, 1808, 1838, 1868, 1898, 1928, 1958, + 1988, 2018, 2048, 2077, 2107, 2137, 2167, 2197, 2227, 2257, 2287, 2317, 2346, 2376, 2405, + 2435, 2464, 2493, 2523, 2552, 2580, 2609, 2638, 2666, 2695, 2723, 2751, 2779, 2806, 2834, + 2861, 2888, 2915, 2942, 2968, 2995, 3021, 3046, 3072, 3097, 3122, 3147, 3172, 3196, 3220, + 3244, 3267, 3290, 3313, 3336, 3358, 3380, 3402, 3423, 3444, 3465, 3486, 3506, 3525, 3545, + 3564, 3583, 3601, 3619, 3637, 3654, 3672, 3688, 3705, 3721, 3736, 3751, 3766, 3781, 3795, + 3809, 3822, 3836, 3848, 3861, 3873, 3884, 3896, 3907, 3917, 3928, 3937, 3947, 3956, 3965, + 3974, 3982, 3990, 3997, 4004, 4011, 4018, 4024, 4030, 4035, 4041, 4046, 4050, 4055, 4059, + 4063, 4066, 4070, 4073, 4076, 4078, 4081, 4083, 4085, 4086, 4088, 4089, 4091, 4092, 4092, + 4093, 4094, 4094, 4095, 4095, 4095, 4095, 4095, 4095, 4095 +}; + +static inline int16_t grad3(const uint8_t h, const int16_t x, const int16_t y, const int16_t z) +{ + return x * GRAD3[h][0] + y * GRAD3[h][1] + z * GRAD3[h][2]; +} + +int32_t Perlin::noise (uint16_t x, uint16_t y, uint16_t z) +{ + uint8_t i0, j0, k0; // integer part of (x, y, z) + uint8_t i1, j1, k1; // integer part plus one of (x, y, z) + uint8_t xx, yy, zz; // fractional part of (x, y, z) + uint16_t fx, fy, fz; // easing function result, add 4 LS bits + + // drop fractional part of each input + i0 = x >> 8; + j0 = y >> 8; + k0 = z >> 8; + + // integer part plus one, wrapped between 0x00 and 0xff + i1 = i0 + 1; + j1 = j0 + 1; + k1 = k0 + 1; + + // fractional part of each input + xx = x & 0xff; + yy = y & 0xff; + zz = z & 0xff; + + // apply easing function + fx = easing_function_lut[xx]; + fy = easing_function_lut[yy]; + fz = easing_function_lut[zz]; + + uint8_t A, AA, AB, B, BA, BB; + uint8_t CA, CB, CC, CD, CE, CF, CG, CH; + + // apply permutation functions + A = PERM[i0]; + AA = PERM[A + j0]; + AB = PERM[A + j1]; + B = PERM[i1]; + BA = PERM[B + j0]; + BB = PERM[B + j1]; + CA = PERM[AA + k0] & 0xf; + CB = PERM[BA + k0] & 0xf; + CC = PERM[AB + k0] & 0xf; + CD = PERM[BB + k0] & 0xf; + CE = PERM[AA + k1] & 0xf; + CF = PERM[BA + k1] & 0xf; + CG = PERM[AB + k1] & 0xf; + CH = PERM[BB + k1] & 0xf; + + // subtract 1.0 from xx, yy, zz + int16_t xxm1 = xx - 256; + int16_t yym1 = yy - 256; + int16_t zzm1 = zz - 256; + + // result is -2 to exactly +2 + int16_t g1 = grad3 (CA, xx, yy, zz ); + int16_t g2 = grad3 (CB, xxm1, yy, zz ); + int16_t g3 = grad3 (CC, xx, yym1, zz ); + int16_t g4 = grad3 (CD, xxm1, yym1, zz ); + int16_t g5 = grad3 (CE, xx, yy, zzm1); + int16_t g6 = grad3 (CF, xxm1, yy, zzm1); + int16_t g7 = grad3 (CG, xx, yym1, zzm1); + int16_t g8 = grad3 (CH, xxm1, yym1, zzm1); + + // linear interpolations + int32_t l1 = lerp1(fx, g1, g2) >> 6; + int32_t l2 = lerp1(fx, g3, g4) >> 6; + int32_t l3 = lerp1(fx, g5, g6) >> 6; + int32_t l4 = lerp1(fx, g7, g8) >> 6; + + int32_t l5 = lerp1(fy, l1, l2) >> 12; + int32_t l6 = lerp1(fy, l3, l4) >> 12; + + int32_t l7 = lerp1(fz, l5, l6) >> 12; + + return l7; +} diff --git a/src/perlin/pf2.h b/src/perlin/pf2.h new file mode 100644 index 00000000..d83c8b4a --- /dev/null +++ b/src/perlin/pf2.h @@ -0,0 +1,135 @@ +//============================================================================================= +// LED Matrix Animated Pattern Generator +// Copyright 2014 by Glen Akins. +// All rights reserved. +// +// Set editor width to 96 and tab stop to 4. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Major inspiration for the use of Perlin noise to generate pseudorandom RGB patterns comes +// from the TI RGB LED coffee table project and the following resources: +// +// TI RGB LED Coffee Table: +// +// http://e2e.ti.com/group/microcontrollerprojects/m/msp430microcontrollerprojects/447779.aspx +// https://github.com/bear24rw/rgb_table/tree/master/code/table_drivers/pytable +// +// Casey Duncan's Python C Noise Library: +// +// https://github.com/caseman/noise +// +// Ken Perlin's Original Source Code: +// +// http://www.mrl.nyu.edu/~perlin/doc/oscar.html +// +// Excellent explanation of Perlin noise and seamless looping and tiling here: +// +// http://webstaff.itn.liu.se/~stegu/TNM022-2005/perlinnoiselinks/perlin-noise-math-faq.html +// +//============================================================================================= + +#ifndef __pf2_h_ +#define __pf2_h_ + +class Perlin : public Pattern +{ + public: + + // constructor + Perlin (const int32_t width, const int32_t height, int32_t mode); + + // constructor + // m_hue_option is hue offset from 0.0 to 1.0 for mode 1, hue step for modes 2 and 3 + Perlin (const int32_t width, const int32_t height, + const int32_t mode, const float xy_scale, + const float z_step, const float z_depth, const float hue_options); + + // destructor + ~Perlin (void); + + // reset to first frame in animation + void init (void); + + // calculate next frame in the animation + bool next (void); + + // get / set scale + float getScale (void) { + return m_xy_scale / 256.0; + } + void setScale (float xy_scale) { + m_xy_scale = xy_scale * 256.0; + } + + // get / set z step + float getZStep (void) { + return m_z_step; + } + void setZStep (float z_step) { + m_z_step = z_step; + } + + // get / set z depth + float getZDepth (void) { + return m_z_depth; + } + void setZDepth (float z_depth) { + m_z_depth = z_depth; + m_z_state = 0; + } + + // get / set hue options + float getHueOptions (void) { + return m_hue_options; + } + void setHueOptions (float hue_options) { + m_hue_options = hue_options; + } + + private: + + // 3d perlin noise function + int32_t noise (uint16_t x, uint16_t y, uint16_t z); + + // mode: + // 1 = fixed background hue + // 2 = hue rotates and varies with noise + // 3 = hue rotates, noise varies brightness + const int32_t m_mode; + + // x and y scale of noise + int32_t m_xy_scale; + + // step in the z direction between displayed x-y planes + float m_z_step; + + // depth in the z direction before the pattern repeats + float m_z_depth; + + // background hue for mode 1, from 0.0 to 1.0 + // hue step size for modes 2 and 3 + float m_hue_options; + + // current z coordinate, mod z depth + float m_z_state; + + // current hue, mod 1.0 + float m_hue_state; + + // current minimum and maximum noise values for normalization + float m_min, m_max; +}; + +#endif From 30443ccc76d85e0a81381d5f5673764d9b6f5757 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 24 Jan 2014 22:52:42 +0000 Subject: [PATCH 175/332] import of GPLed perlin noise code and wrapper for ledscape --- src/perlin/perlin-ledscape.cpp | 148 +++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 src/perlin/perlin-ledscape.cpp diff --git a/src/perlin/perlin-ledscape.cpp b/src/perlin/perlin-ledscape.cpp new file mode 100644 index 00000000..abc9f553 --- /dev/null +++ b/src/perlin/perlin-ledscape.cpp @@ -0,0 +1,148 @@ +//============================================================================================= +// LED Matrix Animated Pattern Generator +// Copyright 2014 by Glen Akins. +// Updated to work with LEDscape by Trammell Hudson +// All rights reserved. +// +// Set editor width to 96 and tab stop to 4. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +//============================================================================================= + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +#include "globals.h" +#include "pattern.h" +#include "pf2.h" +#include "ledscape.h" + +static ledscape_t * leds; + +// global levels to write to FPGA +uint16_t gLevels[DISPLAY_HEIGHT][DISPLAY_WIDTH]; + +// global object to create animated pattern +Perlin *gPattern = NULL; + +// prototypes +void Quit (int sig); +void BlankDisplay (void); +void WriteLevels (void); +void timer_handler (int signum); + +int main (int argc, char *argv[]) +{ + struct sigaction sa; + struct itimerval timer; + + // trap ctrl-c to call quit function + signal (SIGINT, Quit); + + ledscape_config_t * config = &ledscape_matrix_default; + config->matrix_config.width = 256; + config->matrix_config.height = 128; + leds = ledscape_init(config); + + // initialize levels to all off + BlankDisplay (); + + // create a new pattern object -- perlin noise, mode 2 long repeating + gPattern = new Perlin (DISPLAY_WIDTH, DISPLAY_HEIGHT, 2, 6.0/64.0, 1.0/64.0, 256.0, 0.005); + + // create a new pattern object -- perlin noise, mode 1 short repeat + // gPattern = new Perlin (DISPLAY_WIDTH, DISPLAY_HEIGHT, 1, 8.0/64.0, 0.0125, 1.0, 0.2); + + // reset to first frame + gPattern->init (); + + // install timer handler + memset (&sa, 0, sizeof (sa)); + sa.sa_handler = &timer_handler; + sigaction (SIGALRM, &sa, NULL); + + // configure the timer to expire after 20 msec + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = 20000; + + // and every 20 msec after that. + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 20000; + + // start the timer + setitimer (ITIMER_REAL, &timer, NULL); + + // wait forever + while (1) { + sleep (1); + } + + // delete pattern object + delete gPattern; + + return 0; +} + + +void Quit (int sig) +{ + exit (-1); +} + + +void BlankDisplay (void) +{ + // initialize levels to all off + for (int32_t row = 0; row < DISPLAY_HEIGHT; row++) { + for (int32_t col = 0; col < DISPLAY_WIDTH; col++) { + gLevels[row][col] = 0x0000; + } + } + + // send levels to board + WriteLevels (); +} + + +void WriteLevels (void) +{ + ledscape_draw(leds, gLevels); +} + + +void timer_handler (int signum) +{ + // write levels to display + WriteLevels (); + + // calculate next frame in animation + if (gPattern != NULL) { + bool patternComplete = gPattern->next (); + } +} From 60e4b7a38b7d7244b6529708cbd02d1b7a7893c7 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 24 Jan 2014 23:28:00 +0000 Subject: [PATCH 176/332] brighten it up --- src/ledscape/matrix.p | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ledscape/matrix.p b/src/ledscape/matrix.p index 9b95d8ab..7c8f6002 100644 --- a/src/ledscape/matrix.p +++ b/src/ledscape/matrix.p @@ -24,7 +24,7 @@ // higher constants == brighter. // 4 is a ok brightness, 5 is bright, 6 is powerful -#define BRIGHT_SHIFT 4 +#define BRIGHT_SHIFT 6 #define r11_gpio 2 From a9ed36b25c5140b4a03f924433eb4f6043d2032e Mon Sep 17 00:00:00 2001 From: root Date: Fri, 24 Jan 2014 23:30:40 +0000 Subject: [PATCH 177/332] build the perlin demo --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 9d977c5e..76889d39 100755 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ SUBDIR-y += src/ledscape SUBDIR-y += src/demos +SUBDIR-y += src/perlin SUBDIR-y += src/mta SUBDIR-y += src/net From c28d29df212d6b0b68364616315ab786331d02ed Mon Sep 17 00:00:00 2001 From: root Date: Fri, 24 Jan 2014 23:31:02 +0000 Subject: [PATCH 178/332] do panel copy in one pass --- src/ledscape/ledscape.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index c4e55ac1..072a73c1 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -191,19 +191,19 @@ ledscape_remap( * If rot == 0, rotate -90, else rotate +90. */ static void -ledscape_matrix_panel_copy_half( +ledscape_matrix_panel_copy( uint8_t * const out, const uint32_t * const in, const ledscape_matrix_config_t * const config, const int rot ) { - const size_t row_stride = LEDSCAPE_MATRIX_OUTPUTS*2*3; + const size_t row_stride = LEDSCAPE_MATRIX_OUTPUTS*3*2; const size_t row_len = config->leds_width*row_stride; for (int x = 0 ; x < config->panel_width ; x++) { - for (int y = 0 ; y < config->panel_height/2 ; y++) + for (int y = 0 ; y < config->panel_height ; y++) { int ix, iy; if (rot == 0) @@ -237,7 +237,12 @@ ledscape_matrix_panel_copy_half( const uint32_t * const col_ptr = &in[ix + config->width*iy]; const uint32_t col = *col_ptr; - uint8_t * const pix = &out[x*row_stride + y*row_len]; + + // the top half and bottom half of the panels + // are squished together in the output since + // they are drawn simultaneously. + uint8_t * const pix = &out[x*row_stride + (y/8)*3 + (y%8)*row_len]; + pix[0] = (col >> 16) & 0xFF; // red pix[1] = (col >> 8) & 0xFF; // green pix[2] = (col >> 0) & 0xFF; // blue @@ -289,22 +294,12 @@ ledscape_matrix_draw( uint8_t * const op = &out[6*i + j*panel_stride]; // copy the top half of this matrix - ledscape_matrix_panel_copy_half( + ledscape_matrix_panel_copy( op, ip, config, panel->rot ); - - // and the bottom half, which is stored next in - // the output bitstream, but occurs half a panel - // height later in the input image. - ledscape_matrix_panel_copy_half( - op + 3, - ip + config->width*config->panel_height/2, - config, - panel->rot - ); } } From 3b5096b4e468c2f7464c1ffa9714e8f539e5f827 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 24 Jan 2014 23:31:25 +0000 Subject: [PATCH 179/332] fix matrix mode inits --- src/demos/identify.c | 12 +++++++++--- src/demos/matrix-test.c | 11 +++++++---- src/perlin/perlin-ledscape.cpp | 14 ++++++++++++-- tall-cylinder.config | 32 ++++++++++++++++---------------- 4 files changed, 44 insertions(+), 25 deletions(-) diff --git a/src/demos/identify.c b/src/demos/identify.c index fd820993..bb1014e6 100644 --- a/src/demos/identify.c +++ b/src/demos/identify.c @@ -17,6 +17,9 @@ main( char ** argv ) { + const int width = 256; + const int height = 128; + ledscape_config_t * config = &ledscape_matrix_default; if (argc > 1) { @@ -25,10 +28,13 @@ main( return EXIT_FAILURE; } - ledscape_t * const leds = ledscape_init(config); + if (config->type == LEDSCAPE_MATRIX) + { + config->matrix_config.width = width; + config->matrix_config.height = height; + } - const int width = 256; - const int height = 128; + ledscape_t * const leds = ledscape_init(config); //printf("init done %d,%d\n", width, height); time_t last_time = time(NULL); diff --git a/src/demos/matrix-test.c b/src/demos/matrix-test.c index 343ccf0d..29892b88 100644 --- a/src/demos/matrix-test.c +++ b/src/demos/matrix-test.c @@ -192,8 +192,8 @@ main( const char ** argv ) { - int width = 64; // 256; - int height = 48; //128; + int width = 256; + int height = 128; ledscape_config_t * config = &ledscape_matrix_default; if (argc > 1) @@ -203,8 +203,11 @@ main( return EXIT_FAILURE; } - //config->matrix_config.width = width; - //config->matrix_config.height = height; + if (config->type == LEDSCAPE_MATRIX) + { + config->matrix_config.width = width; + config->matrix_config.height = height; + } ledscape_t * const leds = ledscape_init(config); diff --git a/src/perlin/perlin-ledscape.cpp b/src/perlin/perlin-ledscape.cpp index abc9f553..18e3663b 100644 --- a/src/perlin/perlin-ledscape.cpp +++ b/src/perlin/perlin-ledscape.cpp @@ -66,10 +66,20 @@ int main (int argc, char *argv[]) signal (SIGINT, Quit); ledscape_config_t * config = &ledscape_matrix_default; - config->matrix_config.width = 256; - config->matrix_config.height = 128; + if (argc > 1) + { + config = ledscape_config(argv[1]); + if (!config) + return EXIT_FAILURE; + } + + config->matrix_config.width = DISPLAY_WIDTH; + config->matrix_config.height = DISPLAY_HEIGHT; leds = ledscape_init(config); + ledscape_printf((uint32_t*)(uintptr_t)gLevels, DISPLAY_WIDTH, 0xFF0000, "Perlin noise by Glen Akins"); + ledscape_draw(leds, gLevels); + // initialize levels to all off BlankDisplay (); diff --git a/tall-cylinder.config b/tall-cylinder.config index 8de6e6ec..23f1b79a 100644 --- a/tall-cylinder.config +++ b/tall-cylinder.config @@ -1,17 +1,17 @@ matrix16 -0,0 L 0,0 -0,1 R 16,0 -0,2 L 32,0 -0,3 R 48,0 -0,4 L 64,0 -0,5 R 80,0 -0,6 L 96,0 -0,7 R 112,0 -1,0 L 128,0 -1,1 R 144,0 -1,2 L 160,0 -1,3 R 176,0 -1,4 L 192,0 -1,5 R 208,0 -1,6 L 224,0 -1,7 R 240,0 +0,0 R 0,0 +0,1 L 16,0 +0,2 R 32,0 +0,3 L 48,0 +0,4 R 64,0 +0,5 L 80,0 +0,6 R 96,0 +0,7 L 112,0 +1,0 R 128,0 +1,1 L 144,0 +1,2 R 160,0 +1,3 L 176,0 +1,4 R 192,0 +1,5 L 208,0 +1,6 R 224,0 +1,7 L 240,0 From be5f5c295ddbcca48b1cd706d1493a408c20bd31 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 25 Jan 2014 00:05:58 +0000 Subject: [PATCH 180/332] fix color space for 24-bit rgb --- src/perlin/globals.h | 2 +- src/perlin/pattern.cpp | 36 ++++++++++++++++++++++------------ src/perlin/pattern.h | 4 ++-- src/perlin/perlin-ledscape.cpp | 16 +++++++++++++-- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/perlin/globals.h b/src/perlin/globals.h index ab2e6133..73ef57ee 100644 --- a/src/perlin/globals.h +++ b/src/perlin/globals.h @@ -25,6 +25,6 @@ #define DISPLAY_WIDTH 256 #define DISPLAY_HEIGHT 128 -extern uint16_t gLevels[DISPLAY_HEIGHT][DISPLAY_WIDTH]; +extern uint32_t gLevels[DISPLAY_HEIGHT][DISPLAY_WIDTH]; #endif diff --git a/src/perlin/pattern.cpp b/src/perlin/pattern.cpp index fa087e0f..bd0fee54 100644 --- a/src/perlin/pattern.cpp +++ b/src/perlin/pattern.cpp @@ -27,7 +27,8 @@ #include "gammalut.h" #include "pattern.h" -#define MAKE_COLOR(r,g,b) (((r)&0xf)<<8)+(((g)&0xf)<<4)+((b)&0xf) +#define MAKE_COLOR(r,g,b) \ + (((r) << 16) | ((g) << 8) | ((b) << 0)) //--------------------------------------------------------------------------------------------- // convert a hue from 0 to 95 to its 12-bit RGB color @@ -35,14 +36,15 @@ // hue: 0 = red, 32 = blue, 64 = green // -uint16_t Pattern::translateHue (int32_t hue) +uint32_t Pattern::translateHue (int32_t hue) { uint8_t hi, lo; - uint8_t r, g, b; + uint32_t r, g, b; hi = hue >> 4; lo = ((hue & 0xf) << 4) | (hue & 0xf); +#if 1 switch (hi) { case 0: r = 0xff; g = 0; b = lo; break; case 1: r = 0xff-lo, g = 0, b = 0xff; break; @@ -51,12 +53,20 @@ uint16_t Pattern::translateHue (int32_t hue) case 4: r = lo, g = 0xff, b = 0; break; case 5: r = 0xff, g = 0xff-lo, b = 0; break; } - - r = gammaLut[r]; - g = gammaLut[g]; - b = gammaLut[b]; - - return MAKE_COLOR (r,g,b); +//printf("hue=%d=%d,%d: %d,%d,%d\n", hue, hi, lo, r, g, b); + r = gammaLut[r] << 3; + g = gammaLut[g] << 3; + b = gammaLut[b] << 3; +#else + b = hue; + r = 0; + g = 0; +#endif + + + uint32_t color = MAKE_COLOR (r,g,b); + //printf("color=%08x\n", color); +return color; } @@ -67,7 +77,7 @@ uint16_t Pattern::translateHue (int32_t hue) // value: 0 = off, 1.0 = 100% // -uint16_t Pattern::translateHueValue (int32_t hue, float value) +uint32_t Pattern::translateHueValue (int32_t hue, float value) { uint8_t hi, lo; uint8_t r, g, b; @@ -88,9 +98,9 @@ uint16_t Pattern::translateHueValue (int32_t hue, float value) g = ((float)g + 0.5) * value; b = ((float)b + 0.5) * value; - r = gammaLut[r]; - g = gammaLut[g]; - b = gammaLut[b]; + r = gammaLut[r] << 4; + g = gammaLut[g] << 4; + b = gammaLut[b] << 4; return MAKE_COLOR (r,g,b); } diff --git a/src/perlin/pattern.h b/src/perlin/pattern.h index bc263d0d..522ba44a 100644 --- a/src/perlin/pattern.h +++ b/src/perlin/pattern.h @@ -46,8 +46,8 @@ class Pattern width = m_width; height = m_height; } - uint16_t translateHue (int32_t hue); - uint16_t translateHueValue (int32_t hue, float value); + uint32_t translateHue (int32_t hue); + uint32_t translateHueValue (int32_t hue, float value); protected: const int32_t m_width; diff --git a/src/perlin/perlin-ledscape.cpp b/src/perlin/perlin-ledscape.cpp index 18e3663b..b0818657 100644 --- a/src/perlin/perlin-ledscape.cpp +++ b/src/perlin/perlin-ledscape.cpp @@ -46,7 +46,7 @@ using namespace std; static ledscape_t * leds; // global levels to write to FPGA -uint16_t gLevels[DISPLAY_HEIGHT][DISPLAY_WIDTH]; +uint32_t gLevels[DISPLAY_HEIGHT][DISPLAY_WIDTH]; // global object to create animated pattern Perlin *gPattern = NULL; @@ -73,6 +73,10 @@ int main (int argc, char *argv[]) return EXIT_FAILURE; } + float hue_options = 0.005; + if (argc > 2) + hue_options = atof(argv[2]); + config->matrix_config.width = DISPLAY_WIDTH; config->matrix_config.height = DISPLAY_HEIGHT; leds = ledscape_init(config); @@ -84,7 +88,15 @@ int main (int argc, char *argv[]) BlankDisplay (); // create a new pattern object -- perlin noise, mode 2 long repeating - gPattern = new Perlin (DISPLAY_WIDTH, DISPLAY_HEIGHT, 2, 6.0/64.0, 1.0/64.0, 256.0, 0.005); + gPattern = new Perlin( + DISPLAY_WIDTH, + DISPLAY_HEIGHT, + 2, // mode + 3.0/64.0, // size of blobs: smaller value == larger blob + 1.0/64.0, // speed + 256.0, + hue_options + ); // create a new pattern object -- perlin noise, mode 1 short repeat // gPattern = new Perlin (DISPLAY_WIDTH, DISPLAY_HEIGHT, 1, 8.0/64.0, 0.0125, 1.0, 0.2); From 5df3e8e721aaaf51972f516cccb1e9b5fc0a8fe3 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 22 Feb 2014 05:16:50 +0000 Subject: [PATCH 181/332] bbb pru config finally works. device tree sucks --- Makefile | 11 ++++ cape-bone-octo.dts | 141 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 cape-bone-octo.dts diff --git a/Makefile b/Makefile index 67d8c367..c2df07bc 100755 --- a/Makefile +++ b/Makefile @@ -104,6 +104,9 @@ clean: # capemgr and a Device Tree file. But it doesn't work. # SLOT_FILE=/sys/devices/bone_capemgr.8/slots +DTS=CAPE-BONE-OCTO +DTB=/lib/firmware/$(DTS)-00A0.dtbo + dts: LEDscape.dts @SLOT="`grep LEDSCAPE $(SLOT_FILE) | cut -d: -f1`"; \ if [ ! -z "$$SLOT" ]; then \ @@ -114,6 +117,14 @@ dts: LEDscape.dts echo BB-LEDSCAPE > $(SLOT_FILE) + +firmware: $(DTB) + echo $(DTS) > $(SLOT_FILE) + +$(DTB): cape-bone-octo.dts FORCE + dtc -O dtb -o $@ -b 0 -@ $< +FORCE: + ########### # # PRU Libraries and PRU assembler are build from their own trees. diff --git a/cape-bone-octo.dts b/cape-bone-octo.dts new file mode 100644 index 00000000..fcf36556 --- /dev/null +++ b/cape-bone-octo.dts @@ -0,0 +1,141 @@ +/* +* pru dts file BB-BONE-PRU-00A0.dts +* +* Available outputs on pru 0 and their r30 pins: +* p9.31: 0 +* p9.29: 1 +* p9.30: 2 +* p9.28: 3 +* p9.27: 5 +* p9.25: 7 +* p8.12: 14 +* p8.11: 15 + +gpio 0: 23, 27, 22, 10, 9, 8, 26, 11, 30, 31, 5, 3, 20, 4, 2, 14, 7 +gpio 1: 13, 15, 12, 14, 29, 16, 17, 28, 18, 19, +gpio 2: 2, 5, 22, 23, 14, 12, 10, 8, 6, 3, 4, 1, 24, 25, 17, 16, 15, 13, 11, 9, 7, +gpio 3: 21, 19, 15, 14, 17, 16 + +*/ +/dts-v1/; +/plugin/; + +/ { + compatible = "ti,beaglebone", "ti,beaglebone-black"; + + /* identification */ + part-number = "BB-BONE-OCTO"; + version = "00A0"; + + exclusive-use = +//gpio 0: 23, 27, 22, 10, 9, 8, 26, 11, 30, 31, 5, 3, 20, 4, 2, 14, 7 + "P9.11", "P9.12", "P9.13", "P9.14", "P9.15", "P9.16", "P9.17", + "P9.18", + + "P9.21", "P9.22", "P9.23", "P9.24", "P9.25", "P9.26", + "P9.27", "P9.28", "P9.29", "P9.30", + + "P9.41", "P9.42", + + "P8.7", "P8.8", "P8.9", "P8.10", "P8.11", "P8.12", "P8.13", + "P8.14", "P8.15", "P8.16", "P8.17", "P8.18", "P8.19", + + "P8.26", "P8.27", "P8.28", "P8.29", "P8.30", "P8.31", "P8.32", + "P8.33", "P8.34", "P8.35", "P8.36", "P8.37", "P8.38", "P8.39", + "P8.40", "P8.41", "P8.42", "P8.43", "P8.44", "P8.45", "P8.46"; + + fragment@0 { + target = <&am33xx_pinmux>; + __overlay__ { + mygpio: pinmux_mygpio { + pinctrl-single,pins = < + // p9.11-18 + 0x070 0x7 + 0x078 0x7 + 0x074 0x7 + 0x048 0x7 + 0x040 0x7 + 0x04c 0x7 + 0x15c 0x7 + 0x158 0x7 + + // p9.21-29 + 0x154 0x7 + 0x150 0x7 + 0x044 0x7 + 0x184 0x7 + 0x1AC 0x7 + 0x180 0x7 + 0x1A4 0x7 + 0x19C 0x7 + 0x194 0x7 + + // p9.41-42, but alternate functions to input + 0x1B4 0x7 // gpio0.20 as output + 0x164 0x7 // gpio0.7 as output + 0x1A8 0x27 // gpio3.18 as input + 0x1A0 0x27 // gpio3.18 as input + + // p8.7-19 + 0x090 0x7 + 0x094 0x7 + 0x09c 0x7 + 0x098 0x7 + 0x034 0x7 + 0x030 0x7 + 0x024 0x7 + 0x028 0x7 + 0x03c 0x7 + 0x038 0x7 + 0x02c 0x7 + 0x08c 0x7 + 0x020 0x7 + + // p8.26-46 + 0x07c 0x7 + 0x0e0 0x7 + 0x0e8 0x7 + 0x0e4 0x7 + 0x0ec 0x7 + 0x0d8 0x7 + 0x0dc 0x7 + 0x0d4 0x7 + 0x0cc 0x7 + 0x0d4 0x7 + 0x0cc 0x7 + 0x0d0 0x7 + 0x0c8 0x7 + 0x0c0 0x7 + 0x0c4 0x7 + 0x0b8 0x7 + 0x0bc 0x7 + 0x0b0 0x7 + 0x0b4 0x7 + 0x0a8 0x7 + 0x0ac 0x7 + 0x0a0 0x7 + 0x0a4 0x7 + >; + }; + }; + }; + + fragment@1 { + target = <&ocp>; + __overlay__ { + test_helper: helper { + compatible = "bone-pinmux-helper"; + pinctrl-names = "default"; + pinctrl-0 = <&mygpio>; + status = "okay"; + }; + }; + }; + + fragment@2{ + target = <&pruss>; + __overlay__ { + status = "okay"; + }; + }; +}; From 7acf010f30d1ec4486fa22cc308eba0a9ac3439c Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 22 Feb 2014 05:23:59 +0000 Subject: [PATCH 182/332] support the 32x32 arrays --- ledscape.c | 11 +++++++---- matrix-test.c | 4 ++-- matrix.p | 5 +++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/ledscape.c b/ledscape.c index 603bf1b4..fa426099 100644 --- a/ledscape.c +++ b/ledscape.c @@ -294,15 +294,18 @@ ledscape_init( #ifdef CONFIG_LED_MATRIX *(leds->matrix) = (led_matrix_config_t) { .matrix_width = 128, - .matrix_height = 8, + .matrix_height = 16, .matrix = { { 0, 0 }, - { 0, 8 }, { 0, 16 }, - { 0, 24 }, + { 0, 32 }, - { 0, 40 }, { 0, 48 }, + + { 0, 0 }, + { 0, 16 }, + + { 0, 16 }, { 0, 56 }, { 128, 0 }, { 128, 8 }, diff --git a/matrix-test.c b/matrix-test.c index 6582989f..a5f7fc1d 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -153,8 +153,8 @@ gradient( int main(void) { - const int width = 128; - const int height = 48; + const int width = 256; + const int height = 64; ledscape_t * const leds = ledscape_init(width, height); printf("init done\n"); time_t last_time = time(NULL); diff --git a/matrix.p b/matrix.p index 798b69ce..2f5c9ade 100644 --- a/matrix.p +++ b/matrix.p @@ -439,7 +439,8 @@ NEW_ROW_LOOP: //LSL out_clr, 1, bright //LSL out_clr, out_clr, 1 //MOV out_clr, 2048 - LSL out_clr, bright_thresh, 5 + LSL out_clr, bright_thresh, 4 + //LSL out_clr, bright_thresh, 10 //QBBS no_blank, out_set, bright QBGT no_blank, out_set, out_clr @@ -467,7 +468,7 @@ NEW_ROW_LOOP: ADD data_addr, data_addr, offset ADD row, row, 1 - QBEQ READ_LOOP, row, 8 + QBEQ READ_LOOP, row, 16 QBA NEW_ROW_LOOP From 01bf6d427ee6f29ac6b9bddbd6f778cb43dd0fe1 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 22 Feb 2014 21:11:48 +0000 Subject: [PATCH 183/332] brightness note --- matrix.p | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/matrix.p b/matrix.p index 2f5c9ade..34a0203e 100644 --- a/matrix.p +++ b/matrix.p @@ -439,7 +439,10 @@ NEW_ROW_LOOP: //LSL out_clr, 1, bright //LSL out_clr, out_clr, 1 //MOV out_clr, 2048 - LSL out_clr, bright_thresh, 4 + + // higher constants == brighter. + // 4 is a ok brightness, 5 is bright, 6 is powerful + LSL out_clr, bright_thresh, 5 //LSL out_clr, bright_thresh, 10 //QBBS no_blank, out_set, bright From fa2196521975a0251da630369dc2b68f103658ed Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 23 Feb 2014 10:31:12 -0500 Subject: [PATCH 184/332] started on MTA sign font --- fonts/mta-sign.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 fonts/mta-sign.json diff --git a/fonts/mta-sign.json b/fonts/mta-sign.json new file mode 100644 index 00000000..e7793499 --- /dev/null +++ b/fonts/mta-sign.json @@ -0,0 +1 @@ +{"33":[1920,8160,16368,31992,31864,64764,64764,64764,31992,31992,16368,8160,1920,0,0,0],"35":[1920,8160,16368,30840,29496,62460,63740,62460,29496,30840,16368,8160,1920,0,0,0],"36":[1920,8160,16368,31224,30968,63868,63932,61500,31224,31224,16368,8160,1920,0,0,0],"37":[1920,8160,16368,28728,32568,65340,61500,62460,29496,30840,16368,8160,1920,0,0,0],"45":[0,0,0,0,0,0,0,124,0,0,0,0,0,0,0,0],"46":[0,0,0,0,0,0,0,0,0,0,12,12,0,0,0,0],"47":[0,0,0,504,496,480,496,440,284,12,0,0,0,0,0,0],"48":[0,120,204,204,204,204,204,204,204,204,204,120,0,0,0,0],"49":[0,224,240,216,204,192,192,192,192,192,192,192,0,0,0,0],"50":[0,120,252,204,192,192,96,112,56,28,252,252,0,0,0,0],"51":[0,120,252,204,192,112,112,192,192,204,252,120,0,0,0,0],"52":[0,128,192,224,240,216,204,252,252,192,192,192,0,0,0,0],"53":[0,252,252,12,12,124,252,192,192,192,252,124,0,0,0,0],"54":[0,120,252,204,12,124,252,204,204,204,252,120,0,0,0,0],"55":[0,252,252,192,96,96,48,48,24,24,12,12,0,0,0,0],"56":[0,120,252,204,204,120,120,204,204,204,252,120,0,0,0,0],"60":[0,0,0,32,48,1016,1020,1016,48,32,0,0,0,0,0,0],"62":[0,0,0,64,192,508,1020,508,192,64,0,0,0,0,0,0],"64":[1920,8160,16368,30840,29496,62460,63996,64764,32376,28728,16368,8160,1920,0,0,0],"65":[0,224,224,224,432,432,432,792,1016,1016,1548,1548,0,0,0,0],"66":[0,124,252,204,204,124,124,204,204,204,252,124,0,0,0,0],"68":[0,124,252,460,396,396,396,396,396,460,252,124,0,0,0,0],"69":[0,508,508,12,12,508,508,12,12,12,508,508,0,0,0,0],"70":[0,252,252,12,12,124,124,12,12,12,12,12,0,0,0,0],"72":[0,396,396,396,396,508,508,396,396,396,396,396,0,0,0,0],"76":[0,12,12,12,12,12,12,12,12,12,1020,1020,0,0,0,0],"78":[0,396,412,444,508,492,492,460,396,396,396,396,0,0,0,0],"80":[0,0,124,252,204,204,252,124,12,12,12,12,0,0,0,0],"81":[0,0,248,508,396,396,396,396,396,236,1020,888,0,0,0,0],"83":[0,248,508,396,396,60,248,448,396,396,508,248,0,0,0,0],"85":[0,792,792,792,792,792,792,792,792,792,1016,496,0,0,0,0],"87":[0,780,780,780,780,780,780,876,1020,1020,924,780,0,0,0,0],"92":[0,0,0,252,124,60,124,236,452,384,0,0,0,0,0,0],"94":[1920,8160,16368,30840,32568,65340,63548,62268,29496,30840,16368,8160,1920,0,0,0],"97":[0,0,0,0,120,252,204,240,252,204,252,216,0,0,0,0],"98":[0,12,12,12,60,124,108,108,108,108,124,60,0,0,0,0],"99":[0,0,0,0,112,248,204,12,12,204,248,112,0,0,0,0],"100":[0,192,192,192,248,252,204,204,204,204,252,248,0,0,0,0],"101":[0,0,0,0,120,252,204,252,12,204,252,120,0,0,0,0],"102":[0,48,56,24,60,60,24,24,24,24,24,24,0,0,0,0],"103":[0,0,0,0,216,252,204,204,204,204,252,216,192,204,120,0],"104":[0,12,12,12,108,252,204,204,204,204,204,204,0,0,0,0],"105":[0,24,24,0,24,24,24,24,24,24,60,60,0,0,0,0],"107":[0,12,12,12,204,108,60,124,108,108,204,204,0,0,0,0],"108":[0,12,12,12,12,12,12,12,12,12,12,12,0,0,0,0],"109":[0,0,0,0,1916,4092,3276,3276,3276,3276,3276,3276,0,0,0,0],"110":[0,0,0,0,124,204,204,204,204,204,204,204,0,0,0,0],"111":[0,0,0,0,120,252,204,204,204,204,252,120,0,0,0,0],"112":[0,0,0,0,60,124,108,108,108,108,124,60,12,12,12,0],"114":[0,0,0,0,56,124,12,12,12,12,12,12,0,0,0,0],"115":[0,0,0,0,120,252,12,124,248,192,252,124,0,0,0,0],"116":[0,24,24,24,60,60,24,24,24,24,56,56,0,0,0,0],"117":[0,0,0,0,204,204,204,204,204,204,252,248,0,0,0,0],"118":[0,0,0,0,780,780,780,408,504,240,96,96,0,0,0,0],"119":[0,0,0,0,6156,6156,6604,6604,2920,3960,3640,3640,0,0,0,0],"121":[0,0,0,0,0,780,780,408,408,240,240,96,96,120,56,0],"122":[0,0,0,0,252,252,224,112,56,28,252,252,0,0,0,0],"name":"MTA","copy":"TrammellHudson","letterspace":"64"} From 57ef1c6bbd26fd55f810a5c4f0e2cff733f61886 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 23 Feb 2014 16:15:29 -0500 Subject: [PATCH 185/332] updated a few chars --- fonts/mta-sign.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fonts/mta-sign.json b/fonts/mta-sign.json index e7793499..9c48bbab 100644 --- a/fonts/mta-sign.json +++ b/fonts/mta-sign.json @@ -1 +1 @@ -{"33":[1920,8160,16368,31992,31864,64764,64764,64764,31992,31992,16368,8160,1920,0,0,0],"35":[1920,8160,16368,30840,29496,62460,63740,62460,29496,30840,16368,8160,1920,0,0,0],"36":[1920,8160,16368,31224,30968,63868,63932,61500,31224,31224,16368,8160,1920,0,0,0],"37":[1920,8160,16368,28728,32568,65340,61500,62460,29496,30840,16368,8160,1920,0,0,0],"45":[0,0,0,0,0,0,0,124,0,0,0,0,0,0,0,0],"46":[0,0,0,0,0,0,0,0,0,0,12,12,0,0,0,0],"47":[0,0,0,504,496,480,496,440,284,12,0,0,0,0,0,0],"48":[0,120,204,204,204,204,204,204,204,204,204,120,0,0,0,0],"49":[0,224,240,216,204,192,192,192,192,192,192,192,0,0,0,0],"50":[0,120,252,204,192,192,96,112,56,28,252,252,0,0,0,0],"51":[0,120,252,204,192,112,112,192,192,204,252,120,0,0,0,0],"52":[0,128,192,224,240,216,204,252,252,192,192,192,0,0,0,0],"53":[0,252,252,12,12,124,252,192,192,192,252,124,0,0,0,0],"54":[0,120,252,204,12,124,252,204,204,204,252,120,0,0,0,0],"55":[0,252,252,192,96,96,48,48,24,24,12,12,0,0,0,0],"56":[0,120,252,204,204,120,120,204,204,204,252,120,0,0,0,0],"60":[0,0,0,32,48,1016,1020,1016,48,32,0,0,0,0,0,0],"62":[0,0,0,64,192,508,1020,508,192,64,0,0,0,0,0,0],"64":[1920,8160,16368,30840,29496,62460,63996,64764,32376,28728,16368,8160,1920,0,0,0],"65":[0,224,224,224,432,432,432,792,1016,1016,1548,1548,0,0,0,0],"66":[0,124,252,204,204,124,124,204,204,204,252,124,0,0,0,0],"68":[0,124,252,460,396,396,396,396,396,460,252,124,0,0,0,0],"69":[0,508,508,12,12,508,508,12,12,12,508,508,0,0,0,0],"70":[0,252,252,12,12,124,124,12,12,12,12,12,0,0,0,0],"72":[0,396,396,396,396,508,508,396,396,396,396,396,0,0,0,0],"76":[0,12,12,12,12,12,12,12,12,12,1020,1020,0,0,0,0],"78":[0,396,412,444,508,492,492,460,396,396,396,396,0,0,0,0],"80":[0,0,124,252,204,204,252,124,12,12,12,12,0,0,0,0],"81":[0,0,248,508,396,396,396,396,396,236,1020,888,0,0,0,0],"83":[0,248,508,396,396,60,248,448,396,396,508,248,0,0,0,0],"85":[0,792,792,792,792,792,792,792,792,792,1016,496,0,0,0,0],"87":[0,780,780,780,780,780,780,876,1020,1020,924,780,0,0,0,0],"92":[0,0,0,252,124,60,124,236,452,384,0,0,0,0,0,0],"94":[1920,8160,16368,30840,32568,65340,63548,62268,29496,30840,16368,8160,1920,0,0,0],"97":[0,0,0,0,120,252,204,240,252,204,252,216,0,0,0,0],"98":[0,12,12,12,60,124,108,108,108,108,124,60,0,0,0,0],"99":[0,0,0,0,112,248,204,12,12,204,248,112,0,0,0,0],"100":[0,192,192,192,248,252,204,204,204,204,252,248,0,0,0,0],"101":[0,0,0,0,120,252,204,252,12,204,252,120,0,0,0,0],"102":[0,48,56,24,60,60,24,24,24,24,24,24,0,0,0,0],"103":[0,0,0,0,216,252,204,204,204,204,252,216,192,204,120,0],"104":[0,12,12,12,108,252,204,204,204,204,204,204,0,0,0,0],"105":[0,24,24,0,24,24,24,24,24,24,60,60,0,0,0,0],"107":[0,12,12,12,204,108,60,124,108,108,204,204,0,0,0,0],"108":[0,12,12,12,12,12,12,12,12,12,12,12,0,0,0,0],"109":[0,0,0,0,1916,4092,3276,3276,3276,3276,3276,3276,0,0,0,0],"110":[0,0,0,0,124,204,204,204,204,204,204,204,0,0,0,0],"111":[0,0,0,0,120,252,204,204,204,204,252,120,0,0,0,0],"112":[0,0,0,0,60,124,108,108,108,108,124,60,12,12,12,0],"114":[0,0,0,0,56,124,12,12,12,12,12,12,0,0,0,0],"115":[0,0,0,0,120,252,12,124,248,192,252,124,0,0,0,0],"116":[0,24,24,24,60,60,24,24,24,24,56,56,0,0,0,0],"117":[0,0,0,0,204,204,204,204,204,204,252,248,0,0,0,0],"118":[0,0,0,0,780,780,780,408,504,240,96,96,0,0,0,0],"119":[0,0,0,0,6156,6156,6604,6604,2920,3960,3640,3640,0,0,0,0],"121":[0,0,0,0,0,780,780,408,408,240,240,96,96,120,56,0],"122":[0,0,0,0,252,252,224,112,56,28,252,252,0,0,0,0],"name":"MTA","copy":"TrammellHudson","letterspace":"64"} +{"33":[1920,8160,16368,31992,31864,64764,64764,64764,31992,31992,16368,8160,1920,0,0,0],"35":[1920,8160,16368,30840,29496,62460,63740,62460,29496,30840,16368,8160,1920,0,0,0],"36":[1920,8160,16368,31224,30968,63868,63932,61500,31224,31224,16368,8160,1920,0,0,0],"37":[1920,8160,16368,28728,32568,65340,61500,62460,29496,30840,16368,8160,1920,0,0,0],"45":[0,0,0,0,0,0,0,124,0,0,0,0,0,0,0,0],"46":[0,0,0,0,0,0,0,0,0,0,12,12,0,0,0,0],"47":[0,0,0,504,496,480,496,440,284,12,0,0,0,0,0,0],"48":[0,120,204,204,204,204,204,204,204,204,204,120,0,0,0,0],"49":[0,224,240,216,204,192,192,192,192,192,192,192,0,0,0,0],"50":[0,120,252,204,192,192,96,112,56,28,252,252,0,0,0,0],"51":[0,120,252,204,192,112,112,192,192,204,252,120,0,0,0,0],"52":[0,128,192,224,240,216,204,252,252,192,192,192,0,0,0,0],"53":[0,252,252,12,12,124,252,192,192,192,252,124,0,0,0,0],"54":[0,120,252,204,12,124,252,204,204,204,252,120,0,0,0,0],"55":[0,252,252,192,96,96,48,48,24,24,12,12,0,0,0,0],"56":[0,120,252,204,204,120,120,204,204,204,252,120,0,0,0,0],"60":[0,0,0,32,48,1016,1020,1016,48,32,0,0,0,0,0,0],"62":[0,0,0,64,192,508,1020,508,192,64,0,0,0,0,0,0],"64":[1920,8160,16368,30840,29496,62460,63996,64764,32376,28728,16368,8160,1920,0,0,0],"65":[0,224,224,224,432,432,432,792,1016,1016,1548,1548,0,0,0,0],"66":[0,124,252,204,204,124,124,204,204,204,252,124,0,0,0,0],"68":[0,124,252,460,396,396,396,396,396,460,252,124,0,0,0,0],"69":[0,508,508,12,12,508,508,12,12,12,508,508,0,0,0,0],"70":[0,252,252,12,12,124,124,12,12,12,12,12,0,0,0,0],"72":[0,396,396,396,396,508,508,396,396,396,396,396,0,0,0,0],"76":[0,12,12,12,12,12,12,12,12,12,1020,1020,0,0,0,0],"78":[0,396,412,444,508,492,492,460,396,396,396,396,0,0,0,0],"80":[0,0,124,252,204,204,252,124,12,12,12,12,0,0,0,0],"81":[0,0,248,508,396,396,396,396,396,236,1020,888,0,0,0,0],"83":[0,248,508,396,396,60,248,448,396,396,508,248,0,0,0,0],"85":[0,792,792,792,792,792,792,792,792,792,1016,496,0,0,0,0],"87":[0,780,780,780,780,780,780,876,1020,1020,924,780,0,0,0,0],"92":[0,0,0,252,124,60,124,236,452,384,0,0,0,0,0,0],"94":[1920,8160,16368,30840,32568,65340,63548,62268,29496,30840,16368,8160,1920,0,0,0],"97":[0,0,0,0,120,252,204,240,252,204,252,216,0,0,0,0],"98":[0,12,12,12,60,124,108,108,108,108,124,60,0,0,0,0],"99":[0,0,0,0,112,248,204,12,12,204,248,112,0,0,0,0],"100":[0,192,192,192,248,252,204,204,204,204,252,248,0,0,0,0],"101":[0,0,0,0,120,252,204,252,12,204,252,120,0,0,0,0],"102":[0,48,56,24,60,60,24,24,24,24,24,24,0,0,0,0],"103":[0,0,0,0,216,252,204,204,204,204,252,216,192,204,120,0],"104":[0,12,12,12,108,252,204,204,204,204,204,204,0,0,0,0],"105":[0,24,24,0,24,24,24,24,24,24,60,60,0,0,0,0],"107":[0,12,12,12,204,108,60,124,108,108,204,204,0,0,0,0],"108":[0,12,12,12,12,12,12,12,12,12,12,12,0,0,0,0],"109":[0,0,0,0,1916,4092,3276,3276,3276,3276,3276,3276,0,0,0,0],"110":[0,0,0,0,124,252,204,204,204,204,204,204,0,0,0,0],"111":[0,0,0,0,120,252,204,204,204,204,252,120,0,0,0,0],"112":[0,0,0,0,60,124,108,108,108,108,124,60,12,12,12,0],"114":[0,0,0,0,56,124,12,12,12,12,12,12,0,0,0,0],"115":[0,0,0,0,120,252,12,124,248,192,252,124,0,0,0,0],"116":[0,24,24,24,60,60,24,24,24,24,56,56,0,0,0,0],"117":[0,0,0,0,204,204,204,204,204,204,252,248,0,0,0,0],"118":[0,0,0,0,780,780,780,408,504,240,96,96,0,0,0,0],"119":[0,0,0,0,6156,6156,6604,6604,2920,3960,3640,3640,0,0,0,0],"121":[0,0,0,0,780,780,408,408,240,240,96,96,120,56,0,0],"122":[0,0,0,0,252,252,224,112,56,28,252,252,0,0,0,0],"name":"MTA","copy":"TrammellHudson","letterspace":"64"} From 93546a4e76acb7f6cac29e0a609fb85c71ff349c Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Tue, 25 Feb 2014 20:05:45 -0500 Subject: [PATCH 186/332] more letters imported --- fonts/mta-sign.json | 67 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/fonts/mta-sign.json b/fonts/mta-sign.json index 9c48bbab..f3996959 100644 --- a/fonts/mta-sign.json +++ b/fonts/mta-sign.json @@ -1 +1,66 @@ -{"33":[1920,8160,16368,31992,31864,64764,64764,64764,31992,31992,16368,8160,1920,0,0,0],"35":[1920,8160,16368,30840,29496,62460,63740,62460,29496,30840,16368,8160,1920,0,0,0],"36":[1920,8160,16368,31224,30968,63868,63932,61500,31224,31224,16368,8160,1920,0,0,0],"37":[1920,8160,16368,28728,32568,65340,61500,62460,29496,30840,16368,8160,1920,0,0,0],"45":[0,0,0,0,0,0,0,124,0,0,0,0,0,0,0,0],"46":[0,0,0,0,0,0,0,0,0,0,12,12,0,0,0,0],"47":[0,0,0,504,496,480,496,440,284,12,0,0,0,0,0,0],"48":[0,120,204,204,204,204,204,204,204,204,204,120,0,0,0,0],"49":[0,224,240,216,204,192,192,192,192,192,192,192,0,0,0,0],"50":[0,120,252,204,192,192,96,112,56,28,252,252,0,0,0,0],"51":[0,120,252,204,192,112,112,192,192,204,252,120,0,0,0,0],"52":[0,128,192,224,240,216,204,252,252,192,192,192,0,0,0,0],"53":[0,252,252,12,12,124,252,192,192,192,252,124,0,0,0,0],"54":[0,120,252,204,12,124,252,204,204,204,252,120,0,0,0,0],"55":[0,252,252,192,96,96,48,48,24,24,12,12,0,0,0,0],"56":[0,120,252,204,204,120,120,204,204,204,252,120,0,0,0,0],"60":[0,0,0,32,48,1016,1020,1016,48,32,0,0,0,0,0,0],"62":[0,0,0,64,192,508,1020,508,192,64,0,0,0,0,0,0],"64":[1920,8160,16368,30840,29496,62460,63996,64764,32376,28728,16368,8160,1920,0,0,0],"65":[0,224,224,224,432,432,432,792,1016,1016,1548,1548,0,0,0,0],"66":[0,124,252,204,204,124,124,204,204,204,252,124,0,0,0,0],"68":[0,124,252,460,396,396,396,396,396,460,252,124,0,0,0,0],"69":[0,508,508,12,12,508,508,12,12,12,508,508,0,0,0,0],"70":[0,252,252,12,12,124,124,12,12,12,12,12,0,0,0,0],"72":[0,396,396,396,396,508,508,396,396,396,396,396,0,0,0,0],"76":[0,12,12,12,12,12,12,12,12,12,1020,1020,0,0,0,0],"78":[0,396,412,444,508,492,492,460,396,396,396,396,0,0,0,0],"80":[0,0,124,252,204,204,252,124,12,12,12,12,0,0,0,0],"81":[0,0,248,508,396,396,396,396,396,236,1020,888,0,0,0,0],"83":[0,248,508,396,396,60,248,448,396,396,508,248,0,0,0,0],"85":[0,792,792,792,792,792,792,792,792,792,1016,496,0,0,0,0],"87":[0,780,780,780,780,780,780,876,1020,1020,924,780,0,0,0,0],"92":[0,0,0,252,124,60,124,236,452,384,0,0,0,0,0,0],"94":[1920,8160,16368,30840,32568,65340,63548,62268,29496,30840,16368,8160,1920,0,0,0],"97":[0,0,0,0,120,252,204,240,252,204,252,216,0,0,0,0],"98":[0,12,12,12,60,124,108,108,108,108,124,60,0,0,0,0],"99":[0,0,0,0,112,248,204,12,12,204,248,112,0,0,0,0],"100":[0,192,192,192,248,252,204,204,204,204,252,248,0,0,0,0],"101":[0,0,0,0,120,252,204,252,12,204,252,120,0,0,0,0],"102":[0,48,56,24,60,60,24,24,24,24,24,24,0,0,0,0],"103":[0,0,0,0,216,252,204,204,204,204,252,216,192,204,120,0],"104":[0,12,12,12,108,252,204,204,204,204,204,204,0,0,0,0],"105":[0,24,24,0,24,24,24,24,24,24,60,60,0,0,0,0],"107":[0,12,12,12,204,108,60,124,108,108,204,204,0,0,0,0],"108":[0,12,12,12,12,12,12,12,12,12,12,12,0,0,0,0],"109":[0,0,0,0,1916,4092,3276,3276,3276,3276,3276,3276,0,0,0,0],"110":[0,0,0,0,124,252,204,204,204,204,204,204,0,0,0,0],"111":[0,0,0,0,120,252,204,204,204,204,252,120,0,0,0,0],"112":[0,0,0,0,60,124,108,108,108,108,124,60,12,12,12,0],"114":[0,0,0,0,56,124,12,12,12,12,12,12,0,0,0,0],"115":[0,0,0,0,120,252,12,124,248,192,252,124,0,0,0,0],"116":[0,24,24,24,60,60,24,24,24,24,56,56,0,0,0,0],"117":[0,0,0,0,204,204,204,204,204,204,252,248,0,0,0,0],"118":[0,0,0,0,780,780,780,408,504,240,96,96,0,0,0,0],"119":[0,0,0,0,6156,6156,6604,6604,2920,3960,3640,3640,0,0,0,0],"121":[0,0,0,0,780,780,408,408,240,240,96,96,120,56,0,0],"122":[0,0,0,0,252,252,224,112,56,28,252,252,0,0,0,0],"name":"MTA","copy":"TrammellHudson","letterspace":"64"} +{"33":[1920,8160,16368,31992,31864,64764,64764,64764,31992,31992,16368,8160,1920,0,0,0], +"35":[1920,8160,16368,30840,29496,62460,63740,62460,29496,30840,16368,8160,1920,0,0,0], +"36":[1920,8160,16368,31224,30968,63868,63932,61500,31224,31224,16368,8160,1920,0,0,0], +"37":[1920,8160,16368,28728,32568,65340,61500,62460,29496,30840,16368,8160,1920,0,0,0], +"45":[0,0,0,0,0,0,0,124,0,0,0,0,0,0,0,0], +"46":[0,0,0,0,0,0,0,0,0,0,12,12,0,0,0,0], +"47":[0,0,0,504,496,480,496,440,284,12,0,0,0,0,0,0], +"48":[0,120,204,204,204,204,204,204,204,204,204,120,0,0,0,0], +"49":[0,224,240,216,204,192,192,192,192,192,192,192,0,0,0,0], +"50":[0,120,252,204,192,192,96,112,56,28,252,252,0,0,0,0], +"51":[0,120,252,204,192,112,112,192,192,204,252,120,0,0,0,0], +"52":[0,128,192,224,240,216,204,252,252,192,192,192,0,0,0,0], +"53":[0,252,252,12,12,124,252,192,192,192,252,124,0,0,0,0], +"54":[0,120,252,204,12,124,252,204,204,204,252,120,0,0,0,0], +"55":[0,252,252,192,96,96,48,48,24,24,12,12,0,0,0,0], +"56":[0,120,252,204,204,120,120,204,204,204,252,120,0,0,0,0], +"57":[0,120,252,204,204,204,252,248,192,204,252,120,0,0,0,0], +"60":[0,0,0,32,48,1016,1020,1016,48,32,0,0,0,0,0,0], +"62":[0,0,0,64,192,508,1020,508,192,64,0,0,0,0,0,0], +"64":[1920,8160,16368,30840,29496,62460,63996,64764,32376,28728,16368,8160,1920,0,0,0], +"65":[0,224,224,224,432,432,432,792,1016,1016,1548,1548,0,0,0,0], +"66":[0,124,252,204,204,124,124,204,204,204,252,124,0,0,0,0], +"67":[0,240,504,920,268,12,12,12,268,920,504,240,0,0,0,0], +"68":[0,124,252,460,396,396,396,396,396,460,252,124,0,0,0,0], +"69":[0,508,508,12,12,508,508,12,12,12,508,508,0,0,0,0], +"70":[0,252,252,12,12,124,124,12,12,12,12,12,0,0,0,0], +"71":[0,240,504,920,268,12,12,972,972,408,504,240,0,0,0,0], +"72":[0,396,396,396,396,508,508,396,396,396,396,396,0,0,0,0], +"73":[0,252,252,48,48,48,48,48,48,48,252,252,0,0,0,0], +"76":[0,12,12,12,12,12,12,12,12,12,1020,1020,0,0,0,0], +"78":[0,396,412,444,508,492,492,460,396,396,396,396,0,0,0,0], +"79":[0,240,504,408,780,780,780,780,780,408,504,240,0,0,0,0], +"80":[0,124,252,204,204,252,124,12,12,12,12,12,0,0,0,0], +"81":[0,248,508,396,396,396,396,396,396,236,1020,888,0,0,0,0], +"83":[0,248,508,396,396,60,248,448,396,396,508,248,0,0,0,0], +"85":[0,792,792,792,792,792,792,792,792,792,1016,496,0,0,0,0], +"87":[0,780,780,780,780,780,780,876,1020,1020,924,780,0,0,0,0], +"92":[0,0,0,252,124,60,124,236,452,384,0,0,0,0,0,0], +"94":[1920,8160,16368,30840,32568,65340,63548,62268,29496,30840,16368,8160,1920,0,0,0], +"97":[0,0,0,0,120,252,204,240,252,204,252,216,0,0,0,0], +"98":[0,12,12,12,124,252,204,204,204,204,252,124,0,0,0,0], +"99":[0,0,0,0,112,248,204,12,12,204,248,112,0,0,0,0], +"100":[0,192,192,192,248,252,204,204,204,204,252,248,0,0,0,0], +"101":[0,0,0,0,120,252,204,252,12,204,252,120,0,0,0,0], +"102":[0,48,56,24,60,60,24,24,24,24,24,24,0,0,0,0], +"103":[0,0,0,0,216,252,204,204,204,204,252,216,192,204,120,0], +"104":[0,12,12,12,108,252,204,204,204,204,204,204,0,0,0,0], +"105":[0,24,24,0,24,24,24,24,24,24,60,60,0,0,0,0], +"107":[0,12,12,12,204,108,60,124,108,108,204,204,0,0,0,0], +"108":[0,12,12,12,12,12,12,12,12,12,12,12,0,0,0,0], +"109":[0,0,0,0,1916,4092,3276,3276,3276,3276,3276,3276,0,0,0,0], +"110":[0,0,0,0,124,252,204,204,204,204,204,204,0,0,0,0], +"111":[0,0,0,0,120,252,204,204,204,204,252,120,0,0,0,0], +"112":[0,0,0,0,60,124,108,108,108,108,124,60,12,12,12,0], +"114":[0,0,0,0,56,124,12,12,12,12,12,12,0,0,0,0], +"115":[0,0,0,0,120,252,12,124,248,192,252,124,0,0,0,0], +"116":[0,24,24,60,60,24,24,24,24,24,56,56,0,0,0,0], +"117":[0,0,0,0,204,204,204,204,204,204,252,248,0,0,0,0], +"118":[0,0,0,0,780,780,780,408,504,240,96,96,0,0,0,0], +"119":[0,0,0,0,6156,6156,6604,6604,2920,3960,3640,3640,0,0,0,0], +"120":[0,0,0,0,396,396,216,112,112,216,396,396,0,0,0,0], +"121":[0,0,0,0,780,780,408,408,240,240,96,96,120,56,0,0], +"122":[0,0,0,0,252,252,224,112,56,28,252,252,0,0,0,0], +"name":"MTA", +"copy":"TrammellHudson", +"letterspace":"64"} From 00dd809702003b7d1375f9dfc8707944537c7946 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 26 Feb 2014 02:01:24 +0000 Subject: [PATCH 187/332] Fix capemgr for debian --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c2df07bc..bc6e2d23 100755 --- a/Makefile +++ b/Makefile @@ -103,7 +103,7 @@ clean: # The correct way to reserve the GPIO pins on the BBB is with the # capemgr and a Device Tree file. But it doesn't work. # -SLOT_FILE=/sys/devices/bone_capemgr.8/slots +SLOT_FILE=/sys/devices/bone_capemgr.9/slots DTS=CAPE-BONE-OCTO DTB=/lib/firmware/$(DTS)-00A0.dtbo From a2d26ed06bb93dc1b9668a5590f3ac5f62e3387c Mon Sep 17 00:00:00 2001 From: root Date: Wed, 26 Feb 2014 02:01:34 +0000 Subject: [PATCH 188/332] fix for cube --- ledscape.c | 11 ++++++----- matrix-test.c | 48 +++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/ledscape.c b/ledscape.c index fa426099..fe198dd7 100644 --- a/ledscape.c +++ b/ledscape.c @@ -293,7 +293,7 @@ ledscape_init( #ifdef CONFIG_LED_MATRIX *(leds->matrix) = (led_matrix_config_t) { - .matrix_width = 128, + .matrix_width = 64, .matrix_height = 16, .matrix = { { 0, 0 }, @@ -302,11 +302,12 @@ ledscape_init( { 0, 32 }, { 0, 48 }, - { 0, 0 }, - { 0, 16 }, + { 0, 64 }, + { 0, 80 }, + + { 0, 96 }, + { 0, 112 }, - { 0, 16 }, - { 0, 56 }, { 128, 0 }, { 128, 8 }, { 128, 16 }, diff --git a/matrix-test.c b/matrix-test.c index a5f7fc1d..76766d08 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -141,10 +141,44 @@ gradient( uint8_t b = 0xFF; out[1] = b * ((((x + y + cycle) >> 5) ) & 1); #else - uint8_t b = ((x+2*y+cycle)) * 4; - out[0] = b; - out[1] = b; - out[2] = b; + uint32_t b = 0; + + if (x % 32 == 0 && y % 32 == 0) + { + b = 0xFFFFFF; + } else + if (x < 32) + { + if (y < 32) + b = 0xFF0000; + else + if (y < 64) + b = 0x0000FF; + else + if (y < 96) + b = 0x00FF00; + else + b = 0x411111; + } else + if (x < 64) + { + if (y < 32) + b = 0xFF00FF; + else + if (y < 64) + b = 0x00FFFF; + else + if (y < 96) + b = 0xFFFF00; + else + b = 0x114111; + } else { + b = 0x111141; + } + + out[0] = (b >> 16) & 0xFF; + out[1] = (b >> 8) & 0xFF; + out[2] = (b >> 0) & 0xFF; #endif } } @@ -153,8 +187,8 @@ gradient( int main(void) { - const int width = 256; - const int height = 64; + const int width = 64; + const int height = 128; ledscape_t * const leds = ledscape_init(width, height); printf("init done\n"); time_t last_time = time(NULL); @@ -174,7 +208,7 @@ main(void) while (1) { - if (1) + if (0) rainbow(p, width, height, 10, i++); else gradient(p, width, height, 10, i++); From 21a33b12e202d7d770c95c8f90d1766778fc6a8b Mon Sep 17 00:00:00 2001 From: root Date: Wed, 26 Feb 2014 02:39:55 +0000 Subject: [PATCH 189/332] turn off the power management features for wifi --- mac80211.conf | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 mac80211.conf diff --git a/mac80211.conf b/mac80211.conf new file mode 100644 index 00000000..3f4f693e --- /dev/null +++ b/mac80211.conf @@ -0,0 +1,2 @@ +# Disable the wifi power management +options mac80211 max_probe_tries=1 probe_wait_ms=500 From 48d42eaf75ccd4f782017f2b9fa975c03c6d307d Mon Sep 17 00:00:00 2001 From: root Date: Wed, 26 Feb 2014 02:44:42 +0000 Subject: [PATCH 190/332] something is not right with the width; glitches at 128? --- ledscape.c | 16 ++++++++-------- matrix-test.c | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ledscape.c b/ledscape.c index fe198dd7..6a7985c3 100644 --- a/ledscape.c +++ b/ledscape.c @@ -308,14 +308,14 @@ ledscape_init( { 0, 96 }, { 0, 112 }, - { 128, 0 }, - { 128, 8 }, - { 128, 16 }, - { 128, 24 }, - { 128, 32 }, - { 128, 40 }, - { 128, 48 }, - { 128, 56 }, + { 0, 0 }, + { 0, 8 }, + { 0, 16 }, + { 0, 24 }, + { 0, 32 }, + { 0, 40 }, + { 0, 48 }, + { 0, 56 }, }, }; diff --git a/matrix-test.c b/matrix-test.c index 76766d08..05318b4c 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -187,7 +187,7 @@ gradient( int main(void) { - const int width = 64; + const int width = 128; const int height = 128; ledscape_t * const leds = ledscape_init(width, height); printf("init done\n"); @@ -208,7 +208,7 @@ main(void) while (1) { - if (0) + if (1) rainbow(p, width, height, 10, i++); else gradient(p, width, height, 10, i++); From d368caceacbe601f0ba7c5c509f497884de44fe8 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 2 Mar 2014 22:22:43 +0000 Subject: [PATCH 191/332] life on the cube scroller --- cube-life.c | 235 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 cube-life.c diff --git a/cube-life.c b/cube-life.c new file mode 100644 index 00000000..bb304732 --- /dev/null +++ b/cube-life.c @@ -0,0 +1,235 @@ +/** \file + * Play the game of life on the matrix cube. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "ledscape.h" + + +/* LED mappings: + + +--------+ + | | + | Yellow | + |o 3 ^| + +-------|+ + | 2 || + | Green | + |o 0x32 | + +--------+--------+ + |o 0 |o 1 | + | red | purple | + |0x0 --> | + +--------+--------+--------+ + | 5 <-- 4 | + | Teal | Blue | + | o| 0x64 o| + +--------+--------+ + */ + +#define WIDTH 32 +typedef struct +{ + unsigned px, py; + unsigned rotate; // 0, 1, 2, or 3, viewed from the top + + uint8_t edges[4][2]; // top, right, bottom, left + uint8_t board[WIDTH][WIDTH]; +} game_t; + +static game_t boards[6] = { + { + // red + .px = 0, .py = 0, .rotate = 0, + }, + { + // purple + .px = WIDTH, .py = 0, .rotate = 0, + }, + { + // green + .px = 0, .py = WIDTH, .rotate = 3, + }, + { + // yellow + .px = WIDTH, .py = WIDTH, .rotate = 3, + }, + { + // blue + .px = 0, .py = 2*WIDTH, .rotate = 2, + }, + { + // teal + .px = WIDTH, .py = 2*WIDTH, .rotate = 2, + }, + +}; + +static void +randomize( + game_t * const b +) +{ + for (int y = 0 ; y < WIDTH ; y++) + { + for (int x = 0 ; x < WIDTH ; x++) + { + unsigned live = (rand() % 128 < 20); + b->board[y][x] = live ? 3 : 0; + } + } +} + + +static void +play_game( + game_t * const b +) +{ + for (int y = 0 ; y < WIDTH ; y++) + { + for (int x = 0 ; x < WIDTH ; x++) + { + uint8_t sum = 0; + const unsigned bx = x == 0; + const unsigned by = y == 0; + const unsigned tx = x == WIDTH-1; + const unsigned ty = y == WIDTH-1; + + if (!bx && !by) + sum += b->board[y-1][x-1] & 1; + if (!bx && !ty) + sum += b->board[y+1][x-1] & 1; + + if (!tx && !by) + sum += b->board[y-1][x+1] & 1; + if (!tx && !ty) + sum += b->board[y+1][x+1] & 1; + + if (!bx) + sum += b->board[y+0][x-1] & 1; + if (!tx) + sum += b->board[y+0][x+1] & 1; + + if (!by) + sum += b->board[y-1][x+0] & 1; + if (!ty) + sum += b->board[y+1][x+0] & 1; + + +/* +Any live cell with fewer than two live neighbours dies, +as if caused by under-population. +Any live cell with two or three live neighbours lives +on to the next generation. +Any live cell with more than three live neighbours dies, +as if by overcrowding. +Any dead cell with exactly three live neighbours becomes a live cell, +as if by reproduction. +*/ + if (b->board[y][x] & 1) + { + // currently live + if (sum == 2 || sum == 3) + b->board[y][x] |= 2; + else + b->board[y][x] &= ~2; + } else { + // currently dead + if (sum == 3) + b->board[y][x] |= 2; + else + b->board[y][x] &= ~2; + } + } + } +} + + +static void +copy_to_fb( + uint32_t * const p, + const unsigned width, + const unsigned height, + game_t * const board +) +{ + for (int y = 0 ; y < WIDTH ; y++) + { + for (int x = 0 ; x < WIDTH ; x++) + { + uint32_t * const pix_ptr = &p[width*(y+board->py) + x + board->px]; + uint32_t pix = *pix_ptr; + unsigned r = (pix >> 0) & 0xFF; + unsigned g = (pix >> 8) & 0xFF; + unsigned b = (pix >> 16) & 0xFF; + + // copy the new value to the current value + uint8_t * const sq = &board->board[y][x]; + *sq = (*sq & 2) | (*sq >> 1); + + unsigned live = *sq & 1; + if (live) + { + g += 10; + if (g > 0xFF) + g = 0xFF; + } else { +#define SMOOTH 16 + r = (r * SMOOTH) / (SMOOTH+1); + g = (g * SMOOTH) / (SMOOTH+1); + b = (b * SMOOTH) / (SMOOTH+1); + } + + *pix_ptr = (r << 0) | (g << 8) | (b << 16); + } + } +} + + +int +main(void) +{ + const int width = 128; + const int height = 128; + ledscape_t * const leds = ledscape_init(width, height); + printf("init done\n"); + time_t last_time = time(NULL); + unsigned last_i = 0; + + unsigned i = 0; + uint32_t * const p = calloc(width*height,4); + + while (1) + { + if ((i & 0x001FF) == 0) + { + printf("randomize\n"); + for (int i = 0 ; i < 6 ; i++) + randomize(&boards[i]); + } + + if (i++ % 4 == 0) + { + printf("i=%x\n", i); + for (int i = 0 ; i < 6 ; i++) + play_game(&boards[i]); + } + + for (int i = 0 ; i < 6 ; i++) + copy_to_fb(p, width, height, &boards[i]); + + ledscape_draw(leds, p); + usleep(10000); + } + + ledscape_close(leds); + + return EXIT_SUCCESS; +} From 78daee8bc3edee0b500680289f199ecd7e441057 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 2 Mar 2014 22:27:43 +0000 Subject: [PATCH 192/332] colorful fading --- cube-life.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/cube-life.c b/cube-life.c index bb304732..e8345f94 100644 --- a/cube-life.c +++ b/cube-life.c @@ -177,14 +177,22 @@ copy_to_fb( unsigned live = *sq & 1; if (live) { - g += 10; + r += 10; + g += 5; + b += 30; + if (r > 0xFF) + r = 0xFF; if (g > 0xFF) g = 0xFF; + if (b > 0xFF) + b = 0xFF; } else { -#define SMOOTH 16 - r = (r * SMOOTH) / (SMOOTH+1); - g = (g * SMOOTH) / (SMOOTH+1); - b = (b * SMOOTH) / (SMOOTH+1); +#define SMOOTH_R 7 +#define SMOOTH_G 63 +#define SMOOTH_B 15 + r = (r * SMOOTH_R) / (SMOOTH_R+1); + g = (g * SMOOTH_G) / (SMOOTH_G+1); + b = (b * SMOOTH_B) / (SMOOTH_B+1); } *pix_ptr = (r << 0) | (g << 8) | (b << 16); From cd5cbfd362b0f3d40b7d5b82d5b57bc511b57156 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 2 Mar 2014 23:22:35 +0000 Subject: [PATCH 193/332] cube life almost works; edges not quite right yet --- cube-life.c | 168 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 133 insertions(+), 35 deletions(-) diff --git a/cube-life.c b/cube-life.c index e8345f94..e7c5775d 100644 --- a/cube-life.c +++ b/cube-life.c @@ -34,39 +34,49 @@ */ #define WIDTH 32 -typedef struct +typedef struct game game_t; +typedef struct { + game_t * board; + int edge; +} edge_t; + +struct game { unsigned px, py; - unsigned rotate; // 0, 1, 2, or 3, viewed from the top - uint8_t edges[4][2]; // top, right, bottom, left + edge_t top; + edge_t bottom; + edge_t left; + edge_t right; + uint8_t board[WIDTH][WIDTH]; -} game_t; +}; + static game_t boards[6] = { { // red - .px = 0, .py = 0, .rotate = 0, + .px = 0, .py = 0, }, { // purple - .px = WIDTH, .py = 0, .rotate = 0, + .px = WIDTH, .py = 0, }, { // green - .px = 0, .py = WIDTH, .rotate = 3, + .px = 0, .py = WIDTH, }, { // yellow - .px = WIDTH, .py = WIDTH, .rotate = 3, + .px = WIDTH, .py = WIDTH, }, { // blue - .px = 0, .py = 2*WIDTH, .rotate = 2, + .px = 0, .py = 2*WIDTH, }, { // teal - .px = WIDTH, .py = 2*WIDTH, .rotate = 2, + .px = WIDTH, .py = 2*WIDTH, }, }; @@ -87,6 +97,70 @@ randomize( } +static unsigned +get_edge( + edge_t * const e, + int pos +) +{ + game_t * const b = e->board; + const int edge = e->edge; + + if (edge == 1) + return b->board[0][pos] & 1; + if (edge == 2) + return b->board[pos][WIDTH-1] & 1; + if (edge == 3) + return b->board[WIDTH-1][pos] & 1; + if (edge == 4) + return b->board[pos][0] & 1; + + if (edge == -1) + return b->board[0][WIDTH-pos-1] & 1; + if (edge == -2) + return b->board[WIDTH-pos-1][WIDTH-1] & 1; + if (edge == -3) + return b->board[WIDTH-1][WIDTH-pos-1] & 1; + if (edge == -4) + return b->board[WIDTH-pos-1][0] & 1; + +printf("bad %d,%d\n", edge, pos); + return 9; +} + + +static unsigned +get_space( + game_t * const b, + int x, + int y +) +{ + if (x >= 0 && y >= 0 && x < WIDTH && y < WIDTH) + return b->board[y][x] & 1; + + // don't deal with diagonal connections + if (x < 0 && y < 0) + return 0; + if (x >= WIDTH && y >= WIDTH) + return 0; + + // Check for the four cardinal ones + if (y < 0) + return get_edge(&b->top, x); + if (y >= WIDTH) + return get_edge(&b->bottom, x); + if (x < 0) + return get_edge(&b->left, y); + if (x >= WIDTH) + return get_edge(&b->right, y); + + // huh? +printf("bad %d,%d\n", x, y); + return 9; +} + + static void play_game( game_t * const b @@ -97,30 +171,17 @@ play_game( for (int x = 0 ; x < WIDTH ; x++) { uint8_t sum = 0; - const unsigned bx = x == 0; - const unsigned by = y == 0; - const unsigned tx = x == WIDTH-1; - const unsigned ty = y == WIDTH-1; - - if (!bx && !by) - sum += b->board[y-1][x-1] & 1; - if (!bx && !ty) - sum += b->board[y+1][x-1] & 1; - if (!tx && !by) - sum += b->board[y-1][x+1] & 1; - if (!tx && !ty) - sum += b->board[y+1][x+1] & 1; + sum += get_space(b, x-1, y-1); + sum += get_space(b, x-1, y ); + sum += get_space(b, x-1, y+1); - if (!bx) - sum += b->board[y+0][x-1] & 1; - if (!tx) - sum += b->board[y+0][x+1] & 1; + sum += get_space(b, x , y-1); + sum += get_space(b, x , y+1); - if (!by) - sum += b->board[y-1][x+0] & 1; - if (!ty) - sum += b->board[y+1][x+0] & 1; + sum += get_space(b, x+1, y-1); + sum += get_space(b, x+1, y ); + sum += get_space(b, x+1, y+1); /* @@ -187,9 +248,15 @@ copy_to_fb( if (b > 0xFF) b = 0xFF; } else { +#if 1 #define SMOOTH_R 7 #define SMOOTH_G 63 #define SMOOTH_B 15 +#else +#define SMOOTH_R 1 +#define SMOOTH_G 1 +#define SMOOTH_B 1 +#endif r = (r * SMOOTH_R) / (SMOOTH_R+1); g = (g * SMOOTH_G) / (SMOOTH_G+1); b = (b * SMOOTH_B) / (SMOOTH_B+1); @@ -214,20 +281,51 @@ main(void) unsigned i = 0; uint32_t * const p = calloc(width*height,4); + boards[0].top = (edge_t) { &boards[2], 4 }; + boards[0].right = (edge_t) { &boards[1], 4 }; + boards[0].bottom = (edge_t) { &boards[4], -3 }; + boards[0].left = (edge_t) { &boards[5], -3 }; + + boards[1].top = (edge_t) { &boards[2], 4 }; + boards[1].right = (edge_t) { &boards[3], 4 }; + boards[1].bottom = (edge_t) { &boards[4], -4 }; + boards[1].left = (edge_t) { &boards[0], 2 }; + + boards[2].top = (edge_t) { &boards[5], 2 }; + boards[2].right = (edge_t) { &boards[3], 4 }; + boards[2].bottom = (edge_t) { &boards[1], 1 }; + boards[2].left = (edge_t) { &boards[0], 1 }; + + boards[3].top = (edge_t) { &boards[5], 1 }; + boards[3].right = (edge_t) { &boards[4], -1 }; + boards[3].bottom = (edge_t) { &boards[1], 2 }; + boards[3].left = (edge_t) { &boards[2], 2 }; + + boards[4].top = (edge_t) { &boards[3], -2 }; + boards[4].right = (edge_t) { &boards[5], 4 }; + boards[4].bottom = (edge_t) { &boards[0], -2 }; + boards[4].left = (edge_t) { &boards[1], 3 }; + + boards[5].top = (edge_t) { &boards[3], -1 }; + boards[5].right = (edge_t) { &boards[2], 1 }; + boards[5].bottom = (edge_t) { &boards[0], -4 }; + boards[5].left = (edge_t) { &boards[1], 2 }; + + while (1) { if ((i & 0x001FF) == 0) { printf("randomize\n"); - for (int i = 0 ; i < 6 ; i++) - randomize(&boards[i]); + for (int i = 0 ; i < 6 ; i++) + randomize(&boards[i]); } if (i++ % 4 == 0) { printf("i=%x\n", i); - for (int i = 0 ; i < 6 ; i++) - play_game(&boards[i]); + for (int i = 0 ; i < 6 ; i++) + play_game(&boards[i]); } for (int i = 0 ; i < 6 ; i++) From e0e27b8d7d3494c7090089d09411133a6fea31f0 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 3 Mar 2014 01:10:40 +0000 Subject: [PATCH 194/332] identify is broken? something is wrong with the expected layout --- cube-life.c | 293 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 226 insertions(+), 67 deletions(-) diff --git a/cube-life.c b/cube-life.c index e7c5775d..1967aba3 100644 --- a/cube-life.c +++ b/cube-life.c @@ -53,79 +53,97 @@ struct game }; -static game_t boards[6] = { - { - // red - .px = 0, .py = 0, - }, - { - // purple - .px = WIDTH, .py = 0, - }, - { - // green - .px = 0, .py = WIDTH, - }, - { - // yellow - .px = WIDTH, .py = WIDTH, - }, - { - // blue - .px = 0, .py = 2*WIDTH, - }, - { - // teal - .px = WIDTH, .py = 2*WIDTH, - }, - -}; +static game_t boards[6] = {}; static void randomize( - game_t * const b + game_t * const b, + int chance ) { for (int y = 0 ; y < WIDTH ; y++) { for (int x = 0 ; x < WIDTH ; x++) { - unsigned live = (rand() % 128 < 20); +#if 1 + unsigned live = (rand() % 128 < chance); b->board[y][x] = live ? 3 : 0; +#else + b->board[y][x] = 0; +#endif } } + } -static unsigned -get_edge( +static void +make_glider( + game_t * const b +) +{ + // X + // X + // XXX + int px = (rand() % 8) + 10; + int py = (rand() % 8) + 20; + b->board[py+0][px+0] = 0; + b->board[py+0][px+1] = 3; + b->board[py+0][px+2] = 0; + + b->board[py+1][px+0] = 0; + b->board[py+1][px+1] = 0; + b->board[py+1][px+2] = 3; + + b->board[py+2][px+0] = 3; + b->board[py+2][px+1] = 3; + b->board[py+2][px+2] = 3; +} + + +static uint8_t * +_get_edge( edge_t * const e, int pos ) { game_t * const b = e->board; const int edge = e->edge; + const int neg_pos = WIDTH - pos - 1; if (edge == 1) - return b->board[0][pos] & 1; + return &b->board[0][pos]; if (edge == 2) - return b->board[pos][WIDTH-1] & 1; + return &b->board[pos][WIDTH-1]; if (edge == 3) - return b->board[WIDTH-1][pos] & 1; + return &b->board[WIDTH-1][pos]; if (edge == 4) - return b->board[pos][0] & 1; + return &b->board[pos][0]; if (edge == -1) - return b->board[0][WIDTH-pos-1] & 1; + return &b->board[0][neg_pos]; if (edge == -2) - return b->board[WIDTH-pos-1][WIDTH-1] & 1; + return &b->board[neg_pos][WIDTH-1]; if (edge == -3) - return b->board[WIDTH-1][WIDTH-pos-1] & 1; + return &b->board[WIDTH-1][neg_pos]; if (edge == -4) - return b->board[WIDTH-pos-1][0] & 1; + return &b->board[neg_pos][0]; printf("bad %d,%d\n", edge, pos); - return 9; + return NULL; +} + + +static uint8_t +get_edge( + edge_t * const e, + int pos +) +{ + uint8_t * const u = _get_edge(e, pos); + if (u) + return *u; + return 0; } @@ -213,6 +231,49 @@ as if by reproduction. } +static void +identify( + uint8_t * const out, + int x, + int y +) +{ + uint32_t b = 0; + + if (x < 32) + { + if (y < 32) + b = 0xFF0000; + else + if (y < 64) + b = 0x0000FF; + else + if (y < 96) + b = 0x00FF00; + else + b = 0x411111; + } else + if (x < 64) + { + if (y < 32) + b = 0xFF00FF; + else + if (y < 64) + b = 0x00FFFF; + else + if (y < 96) + b = 0xFFFF00; + else + b = 0x114111; + } else { + b = 0x111141; + } + + out[0] = (b >> 16) & 0xFF; + out[1] = (b >> 8) & 0xFF; + out[2] = (b >> 0) & 0xFF; +} + static void copy_to_fb( uint32_t * const p, @@ -262,12 +323,53 @@ copy_to_fb( b = (b * SMOOTH_B) / (SMOOTH_B+1); } - *pix_ptr = (r << 0) | (g << 8) | (b << 16); + if (x < 3 && y == 0) + identify(pix_ptr, board->px, board->py); + else + *pix_ptr = (r << 0) | (g << 8) | (b << 16); } } } +static void +check_edge( + game_t * const boards, + int i, + edge_t *edge, + int this_edge +) +{ + game_t * b = &boards[i]; + game_t * n = edge->board; + int e = edge->edge; + + // verify that the back link from the remote board is to this + // edge on this board. + if (e == 1 && n->top.board == b && n->top.edge == this_edge) + return; + if (e == 2 && n->right.board == b && n->right.edge == this_edge) + return; + if (e == 3 && n->bottom.board == b && n->bottom.edge == this_edge) + return; + if (e == 4 && n->left.board == b && n->left.edge == this_edge) + return; + + if (e == -1 && n->top.board == b && n->top.edge == -this_edge) + return; + if (e == -2 && n->right.board == b && n->right.edge == -this_edge) + return; + if (e == -3 && n->bottom.board == b && n->bottom.edge == -this_edge) + return; + if (e == -4 && n->left.board == b && n->left.edge == -this_edge) + return; + + fprintf(stderr, "%d edge %d bad back link?\n", i, this_edge); + exit(-1); +} + + + int main(void) { @@ -281,44 +383,101 @@ main(void) unsigned i = 0; uint32_t * const p = calloc(width*height,4); - boards[0].top = (edge_t) { &boards[2], 4 }; - boards[0].right = (edge_t) { &boards[1], 4 }; - boards[0].bottom = (edge_t) { &boards[4], -3 }; - boards[0].left = (edge_t) { &boards[5], -3 }; + game_t * const red = &boards[0]; + game_t * const purple = &boards[1]; + game_t * const green = &boards[2]; + game_t * const yellow = &boards[3]; + game_t * const blue = &boards[4]; + game_t * const teal = &boards[5]; + + // red + red->px = 0; + red->py = 0; + red->top = (edge_t) { green, 4 }; + red->right = (edge_t) { purple, 4 }; + red->bottom = (edge_t) { blue, -3 }; + red->left = (edge_t) { teal, -3 }; + + // purple + purple->px = WIDTH; + purple->py = 0; + purple->top = (edge_t) { green, 3 }; + purple->right = (edge_t) { yellow, 3 }; + purple->bottom = (edge_t) { blue, -4 }; + purple->left = (edge_t) { red, 2 }; + + // green + green->px = 0; + green->py = 2*WIDTH; + green->top = (edge_t) { teal, -2 }; + green->right = (edge_t) { yellow, 4 }; + green->bottom = (edge_t) { purple, 1 }; + green->left = (edge_t) { red, 1 }; + + // yellow + yellow->px = WIDTH; + yellow->py = 2*WIDTH; + yellow->top = (edge_t) { teal, -1 }; + yellow->right = (edge_t) { blue, -1 }; + yellow->bottom = (edge_t) { purple, 2 }; + yellow->left = (edge_t) { green, 2 }; + + // blue + blue->px = 0; + blue->py = WIDTH; + blue->top = (edge_t) { yellow, -2 }; + blue->right = (edge_t) { teal, 4 }; + blue->bottom = (edge_t) { red, -3 }; + blue->left = (edge_t) { purple, -3 }; + + // teal + teal->px = WIDTH; + teal->py = WIDTH; + teal->top = (edge_t) { yellow, -1 }; + teal->right = (edge_t) { green, -1 }; + teal->bottom = (edge_t) { red, -4 }; + teal->left = (edge_t) { blue, 2 }; + + for (int i = 0 ; i < 6 ; i++) + { + game_t * b = &boards[i]; + check_edge(boards, i, &boards[i].top, 1); + check_edge(boards, i, &boards[i].right, 2); + check_edge(boards, i, &boards[i].bottom, 3); + check_edge(boards, i, &boards[i].left, 4); + } - boards[1].top = (edge_t) { &boards[2], 4 }; - boards[1].right = (edge_t) { &boards[3], 4 }; - boards[1].bottom = (edge_t) { &boards[4], -4 }; - boards[1].left = (edge_t) { &boards[0], 2 }; + srand(getpid()); - boards[2].top = (edge_t) { &boards[5], 2 }; - boards[2].right = (edge_t) { &boards[3], 4 }; - boards[2].bottom = (edge_t) { &boards[1], 1 }; - boards[2].left = (edge_t) { &boards[0], 1 }; +if (1){ + int which = 5; + game_t * const b = &boards[which]; + + b->board[0][4] = 3; + *_get_edge(&b->top, 4) = 3; - boards[3].top = (edge_t) { &boards[5], 1 }; - boards[3].right = (edge_t) { &boards[4], -1 }; - boards[3].bottom = (edge_t) { &boards[1], 2 }; - boards[3].left = (edge_t) { &boards[2], 2 }; + b->board[6][WIDTH-1] = 3; + *_get_edge(&b->right, 6) = 3; - boards[4].top = (edge_t) { &boards[3], -2 }; - boards[4].right = (edge_t) { &boards[5], 4 }; - boards[4].bottom = (edge_t) { &boards[0], -2 }; - boards[4].left = (edge_t) { &boards[1], 3 }; + b->board[WIDTH-1][8] = 3; + *_get_edge(&b->bottom, 8) = 3; - boards[5].top = (edge_t) { &boards[3], -1 }; - boards[5].right = (edge_t) { &boards[2], 1 }; - boards[5].bottom = (edge_t) { &boards[0], -4 }; - boards[5].left = (edge_t) { &boards[1], 2 }; + b->board[8][0] = 3; + *_get_edge(&b->left, 8) = 3; +} while (1) { - if ((i & 0x001FF) == 0) + if (0 && (i & 0x003FF) == 0) { printf("randomize\n"); for (int i = 0 ; i < 6 ; i++) - randomize(&boards[i]); + { + randomize(&boards[i], 0); + make_glider(&boards[i]); + } + //make_glider(&boards[rand() % 6]); } if (i++ % 4 == 0) From cfae76f4e1f40016fdb97e8a05149bbb82e7d7fa Mon Sep 17 00:00:00 2001 From: root Date: Mon, 3 Mar 2014 01:16:56 +0000 Subject: [PATCH 195/332] draw six image faces --- companion-cube.raw | Bin 0 -> 4096 bytes image-cube.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 companion-cube.raw create mode 100644 image-cube.c diff --git a/companion-cube.raw b/companion-cube.raw new file mode 100644 index 0000000000000000000000000000000000000000..1adcd80e54986d08ee61169cc2f5b9752e55807d GIT binary patch literal 4096 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 +#include +#include +#include +#include +#include +#include +#include +#include "ledscape.h" + + +int +main(void) +{ + const int width = 128; + const int height = 128; + ledscape_t * const leds = ledscape_init(width, height); + printf("init done\n"); + time_t last_time = time(NULL); + unsigned last_i = 0; + + uint32_t bits[32][32]; + memset(bits, 0, sizeof(bits)); + ssize_t rc = read(0, bits, sizeof(bits)); + if (rc != sizeof(bits)) + { + fprintf(stderr, "only read %zu bytes\n", rc); + return -1; + } + + uint32_t * const p = calloc(4, width*height); + + for (int x = 0 ; x < 32 ; x++) + { + for (int y = 0 ; y < 32 ; y++) + { + uint32_t c = bits[x][y]; + uint32_t r = (c >> 16) & 0xFF; + uint32_t g = (c >> 8) & 0xFF; + uint32_t b = (c >> 0) & 0xFF; + r = r; + g = g; + b = b; + c = (r << 0) | (g << 8) | (b << 16); + printf("%d,%d %08x %d,%d,%d\n", x, y, c, r, g, b); + p[width*((31-y)+0) + x] = c; + p[width*((31-y)+0) + x + 32] = c; + p[width*((31-x)+32) + (31-y)] = c; + p[width*((31-x)+32) + (31-y) + 32] = c; + p[width*((31-x)+64) + (31-y)] = c; + p[width*((31-x)+64) + (31-y) + 32] = c; + } + } + + + while (1) + { + ledscape_draw(leds, p); + usleep(20000); + } + + //ledscape_close(leds); + + return EXIT_SUCCESS; +} From f7b955d98ec3e8a6894d19ed3173fdc55fb07959 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 3 Mar 2014 01:17:14 +0000 Subject: [PATCH 196/332] cube life works. frustratingly the mapping is backwards? --- Makefile | 2 ++ cube-life.c | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index bc6e2d23..ffdf69b3 100755 --- a/Makefile +++ b/Makefile @@ -7,6 +7,8 @@ TARGETS += matrix-test TARGETS += fire TARGETS += matrix-udp-rx TARGETS += opc-rx +TARGETS += cube-life +TARGETS += image-cube LEDSCAPE_OBJS = ledscape.o pru.o bitslice.o util.o LEDSCAPE_LIB := libledscape.a diff --git a/cube-life.c b/cube-life.c index 1967aba3..0794e3ac 100644 --- a/cube-life.c +++ b/cube-life.c @@ -142,7 +142,7 @@ get_edge( { uint8_t * const u = _get_edge(e, pos); if (u) - return *u; + return (*u) & 1; return 0; } @@ -323,7 +323,7 @@ copy_to_fb( b = (b * SMOOTH_B) / (SMOOTH_B+1); } - if (x < 3 && y == 0) + if (0 && x == 0 && y == 0) identify(pix_ptr, board->px, board->py); else *pix_ptr = (r << 0) | (g << 8) | (b << 16); @@ -469,13 +469,13 @@ if (1){ while (1) { - if (0 && (i & 0x003FF) == 0) + if ((i & 0x1FF) == 0) { printf("randomize\n"); for (int i = 0 ; i < 6 ; i++) { - randomize(&boards[i], 0); - make_glider(&boards[i]); + randomize(&boards[i], 40); + //make_glider(&boards[i]); } //make_glider(&boards[rand() % 6]); } From 5bf50428fb5e4218ab88de96113ecd11004f7f65 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 3 Mar 2014 01:17:53 +0000 Subject: [PATCH 197/332] tweak identify routine --- matrix-test.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/matrix-test.c b/matrix-test.c index 05318b4c..b142fcac 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -143,7 +143,7 @@ gradient( #else uint32_t b = 0; - if (x % 32 == 0 && y % 32 == 0) + if (x % 32 < (x/32 + 4) && y % 32 < (y/32+1)) { b = 0xFFFFFF; } else @@ -179,6 +179,7 @@ gradient( out[0] = (b >> 16) & 0xFF; out[1] = (b >> 8) & 0xFF; out[2] = (b >> 0) & 0xFF; + //*out = b; #endif } } From 4ea24e99f6ce96c504159425f8ae4b7dfaf823e5 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 3 Mar 2014 01:44:46 +0000 Subject: [PATCH 198/332] tweak parameters --- cube-life.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cube-life.c b/cube-life.c index 0794e3ac..dc1d6475 100644 --- a/cube-life.c +++ b/cube-life.c @@ -299,7 +299,7 @@ copy_to_fb( unsigned live = *sq & 1; if (live) { - r += 10; + r += 80; g += 5; b += 30; if (r > 0xFF) @@ -310,9 +310,9 @@ copy_to_fb( b = 0xFF; } else { #if 1 -#define SMOOTH_R 7 -#define SMOOTH_G 63 -#define SMOOTH_B 15 +#define SMOOTH_R 3 +#define SMOOTH_G 127 +#define SMOOTH_B 63 #else #define SMOOTH_R 1 #define SMOOTH_G 1 @@ -469,12 +469,12 @@ if (1){ while (1) { - if ((i & 0x1FF) == 0) + if ((i & 0x3FF) == 0) { printf("randomize\n"); for (int i = 0 ; i < 6 ; i++) { - randomize(&boards[i], 40); + randomize(&boards[i], 20); //make_glider(&boards[i]); } //make_glider(&boards[rand() % 6]); From 2bf8d005e447401f0ff8beb1ad6138af468c3e73 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 3 Mar 2014 01:45:05 +0000 Subject: [PATCH 199/332] rename image-cube to cube-image --- Makefile | 2 +- image-cube.c => cube-image.c | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename image-cube.c => cube-image.c (100%) diff --git a/Makefile b/Makefile index ffdf69b3..b9942a67 100755 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ TARGETS += fire TARGETS += matrix-udp-rx TARGETS += opc-rx TARGETS += cube-life -TARGETS += image-cube +TARGETS += cube-image LEDSCAPE_OBJS = ledscape.o pru.o bitslice.o util.o LEDSCAPE_LIB := libledscape.a diff --git a/image-cube.c b/cube-image.c similarity index 100% rename from image-cube.c rename to cube-image.c From a6dc6d6a7eed458011bda5a2c1c10dca443e0b92 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 3 Mar 2014 01:45:37 +0000 Subject: [PATCH 200/332] avoid extra prints --- cube-life.c | 1 - 1 file changed, 1 deletion(-) diff --git a/cube-life.c b/cube-life.c index dc1d6475..ebd549dd 100644 --- a/cube-life.c +++ b/cube-life.c @@ -482,7 +482,6 @@ if (1){ if (i++ % 4 == 0) { - printf("i=%x\n", i); for (int i = 0 ; i < 6 ; i++) play_game(&boards[i]); } From e131ef101c333c2c684ca1f1644abcbabebd43ac Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Thu, 20 Mar 2014 19:30:22 -0400 Subject: [PATCH 201/332] flat bracket to connect to 15mm extrusion --- pcb/flat-bracket.svg | 573 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 573 insertions(+) create mode 100644 pcb/flat-bracket.svg diff --git a/pcb/flat-bracket.svg b/pcb/flat-bracket.svg new file mode 100644 index 00000000..cd3a9139 --- /dev/null +++ b/pcb/flat-bracket.svg @@ -0,0 +1,573 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + trmm.net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + trmm.net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + trmm.net + + + From ccfff362a88ae11d7303889ecb665ecf469385e2 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Thu, 20 Mar 2014 22:21:20 -0400 Subject: [PATCH 202/332] brackets for 15mm mitsum rail --- pcb/flat-bracket.scad | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 pcb/flat-bracket.scad diff --git a/pcb/flat-bracket.scad b/pcb/flat-bracket.scad new file mode 100644 index 00000000..d273806b --- /dev/null +++ b/pcb/flat-bracket.scad @@ -0,0 +1,42 @@ +/** \file + * mounting bracket for 15mm extrusion. + */ + + +module bracket() +{ + translate([0,0,-3]) linear_extrude(height=3) + polygon([[0,0], [8,0], [8,3], [3,15], [0,15]]); + + cube([8,3,8]); + translate([0,0,-10]) cube([3,15,8]); + +} + +/* +translate([15/2,0,3/2]) render() difference() { + cube([15,10,3], center=true); + translate([7.5/2,1,-2]) cylinder(r=4/2, h=5, $fs=1); + translate([-7.5,1,3]) rotate([0,90,0]) cylinder(r=4,h=4); +} + +translate([0,0,10/2]) rotate([0,90,0]) render() difference() { + cube([10,10,3], center=true); + translate([1,1,-2]) cylinder(r=4/2, h=5, $fs=1); +} +*/ + + +module right() +{ +render() difference() +{ + bracket(); + translate([2.5,4,8/2]) rotate([90,0,0]) cylinder(r=3.8/2, h=5, $fs=1); + translate([-1,7.5,-10+4]) rotate([0,90,0]) cylinder(r=4/2, h=5, $fs=1); +} +} + +right(); + +translate([0,0,20]) scale([1,1,-1]) right(); From 5b9b6bf75d3222f03ba75cf7b462da06f7764444 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 22 Mar 2014 12:07:39 -0400 Subject: [PATCH 203/332] started on bracket to use 20mm extrusion --- pcb/flat-20mm.scad | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 pcb/flat-20mm.scad diff --git a/pcb/flat-20mm.scad b/pcb/flat-20mm.scad new file mode 100644 index 00000000..b5225893 --- /dev/null +++ b/pcb/flat-20mm.scad @@ -0,0 +1,40 @@ +/** \file + * Brackets for 20mm extrusion. + * + * These hold the panels a few mm away from the bracket. + */ + +length=26; +width=20; + +module bracket() +{ + translate([0,0,4]) cube([28,length,8], center=true); + translate([12,0,(width+8)/2]) cube([4,length,width+8], center=true); + translate([-12,0,(width+8)/2]) cube([4,length,width+8], center=true); +} + +color([0,1,0]) translate([0,0,width/2+8]) extrusion(100); + +render() difference() +{ + bracket(); + translate([-10,10,0]) { + translate([0,0,-1]) cylinder(r=3.5/2, h=6, $fs=1); + translate([0,0,4]) cylinder(r=6/2, h=4, $fs=1); + translate([0,0,8]) cylinder(r=12/2, h=8, $fs=1); + } +} + +module extrusion(len) +{ + render() difference() + { + cube([width,len,width], center=true); + translate([width/2-5/2+1,0,0]) cube([5,len+2,5], center=true); + translate([-width/2+5/2-1,0,0]) cube([5,len+2,5], center=true); + + translate([0,0,-width/2+5/2-1]) cube([5,len+2,5], center=true); + translate([0,0,width/2-5/2+1]) cube([5,len+2,5], center=true); + } +} From 8b03b5cb350f1431a460fbd00ceb20c93e92994f Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 22 Mar 2014 12:32:45 -0400 Subject: [PATCH 204/332] printed for flat --- pcb/flat-20mm.scad | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/pcb/flat-20mm.scad b/pcb/flat-20mm.scad index b5225893..c8e2b4eb 100644 --- a/pcb/flat-20mm.scad +++ b/pcb/flat-20mm.scad @@ -4,28 +4,32 @@ * These hold the panels a few mm away from the bracket. */ -length=26; +length=20; width=20; -module bracket() -{ - translate([0,0,4]) cube([28,length,8], center=true); - translate([12,0,(width+8)/2]) cube([4,length,width+8], center=true); - translate([-12,0,(width+8)/2]) cube([4,length,width+8], center=true); +render() difference () { + translate([0,0,4]) cube([28,length,6], center=true); + + translate([10,5,-1]) cylinder(r=3.5/2, h=6, $fs=1); + translate([10,5,4]) cylinder(r=6/2, h=4, $fs=1); + + translate([-10,5,-1]) cylinder(r=3.5/2, h=6, $fs=1); + translate([-10,5,4]) cylinder(r=6/2, h=4, $fs=1); } -color([0,1,0]) translate([0,0,width/2+8]) extrusion(100); +translate([width/2+2,-4,width/2+6]) render() difference() { + cube([4,length-8,width], center=true); + translate([-3,0,0]) rotate([0,90,0]) cylinder(r=4.5/2, h=6, $fs=1); +} -render() difference() -{ - bracket(); - translate([-10,10,0]) { - translate([0,0,-1]) cylinder(r=3.5/2, h=6, $fs=1); - translate([0,0,4]) cylinder(r=6/2, h=4, $fs=1); - translate([0,0,8]) cylinder(r=12/2, h=8, $fs=1); - } +translate([-(width/2+2),-4,width/2+6]) render() difference() { + cube([4,length-8,width], center=true); + translate([-3,0,0]) rotate([0,90,0]) cylinder(r=4.5/2, h=6, $fs=1); } + +%color([0,1,0]) translate([0,0,width/2+6]) extrusion(100); + module extrusion(len) { render() difference() From 84cbe42f3c8cab7e11baa03ae41b9c8a4ad071b0 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 23 Mar 2014 17:45:28 +0000 Subject: [PATCH 205/332] Identify based on the mta font --- Makefile | 1 + identify | 39 --------------- identify.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+), 39 deletions(-) delete mode 100755 identify create mode 100644 identify.c diff --git a/Makefile b/Makefile index 52884981..9863ed20 100755 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ TARGETS += opc-rx TARGETS += cube-life TARGETS += cube-image TARGETS += mta-sign +TARGETS += identify LEDSCAPE_OBJS = ledscape.o pru.o bitslice.o util.o LEDSCAPE_LIB := libledscape.a diff --git a/identify b/identify deleted file mode 100755 index 0a70717b..00000000 --- a/identify +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/python -# Draw an image with PIl that has the coordinates -# in flashing colors -# -import Image, ImageFont, ImageDraw -import socket -import time, datetime -from colorsys import hsv_to_rgb - -sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) -dest = ("localhost", 9999) - -#print im.format, im.size, im.mode -# use a truetype font -font = ImageFont.truetype("pf_tempesta_seven.ttf", 8) - -i = 0 -width = 256 -height = 64 -disp = Image.new("RGB", (width,height), "black") -disp_draw = ImageDraw.Draw(disp) - -def rainbow(i): - rgb = [int(x*256) for x in hsv_to_rgb(i/256.0,0.8,0.8)] - return (rgb[0],rgb[1],rgb[2]) - - -while True: - disp.paste("black", (0,0,width,height)) - - for x in range(0,width, 32): - for y in range(0,height, 16): - s = str(x) + "," + str(y) - disp_draw.text((x+2, y), s, font=font, fill=rainbow(i)) - - # Send it to the drawing server - sock.sendto(chr(1) + disp.tostring(), dest) - i = (i+1) % width - time.sleep(0.025) diff --git a/identify.c b/identify.c new file mode 100644 index 00000000..5e22f920 --- /dev/null +++ b/identify.c @@ -0,0 +1,141 @@ +/** \file + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "ledscape.h" +#include "mta-font.c" + +const int width = 128; +const int height = 128; + + +static int +font_write( + uint32_t * const buf, + const uint32_t color, + const int x0, + const int y0, + const char * s +) +{ + int x = x0; + int y = y0; + + while (1) + { + char c = *s++; + if (!c) + break; + + if (c == '\n') + { + x = x0; + y += 16 * width; + continue; + } + + const uint16_t * ch = font[(uint8_t) c]; + int max_width = 0; + + if (c == ' ' || c == '.') + max_width = 3; + else + for (int h = 0 ; h < 16 ; h++) + { + int width = 0; + uint16_t row = ch[h] >> 2; + while (row) + { + row >>= 1; + width++; + } + + if (width > max_width) + max_width = width; + } + + // add space after the character + max_width++; + + for (int h = 0 ; h < 16 ; h++) + { + uint16_t row = ch[h] >> 2; + for (int j = 0 ; j < max_width ; j++, row >>= 1) + { + uint32_t pixel_color = (row & 1) ? color : 0; + if (x + j >= width || x + j < 0) + continue; + if (y + h >= height || y + h < 0) + continue; + + uint8_t * pix = (uint8_t*) &buf[(y+h)*width + x + j]; + pix[0] = pixel_color >> 16; + pix[1] = pixel_color >> 8; + pix[2] = pixel_color >> 0; + } + } + + x += max_width; + } + + return x; +} + + +int +main( + int argc, + char ** argv +) +{ + ledscape_t * const leds = ledscape_init(width, height); + + + printf("init done\n"); + time_t last_time = time(NULL); + unsigned last_i = 0; + + unsigned i = 0; + uint32_t * const p = calloc(width*height,4); + int scroll_x = 128; + memset(p, 0x10, width*height*4); + + for (int x = 0 ; x < 128 ; x += 32) + { + for (int y = 0 ; y < 128 ; y += 16) + { + char buf[32]; + snprintf(buf, sizeof(buf), "%d,%d", x, y); + font_write(p, 0xFF0000, x, y, buf); + } + } + + while (1) + { + ledscape_draw(leds, p); + usleep(20000); + + // wait for the previous frame to finish; + //const uint32_t response = ledscape_wait(leds); + const uint32_t response = 0; + time_t now = time(NULL); + if (now != last_time) + { + printf("%d fps. starting %d previous %"PRIx32"\n", + i - last_i, i, response); + last_i = i; + last_time = now; + } + + } + + ledscape_close(leds); + + return EXIT_SUCCESS; +} From c30b86dcfb542a6b4347673dd1d8aeafaf5c757b Mon Sep 17 00:00:00 2001 From: root Date: Sun, 23 Mar 2014 17:45:45 +0000 Subject: [PATCH 206/332] flipping works for vertical panels --- mta-sign.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 10 deletions(-) diff --git a/mta-sign.c b/mta-sign.c index 6dc8b74c..bb3fc44d 100644 --- a/mta-sign.c +++ b/mta-sign.c @@ -12,8 +12,10 @@ #include "ledscape.h" #include "mta-font.c" -const int width = 128; -const int height = 128; +const int leds_width = 128; +const int leds_height = 128; +const int width = 256; +const int height = 32; static int @@ -88,6 +90,59 @@ font_write( return x; } +/** Copy a 16x32 region from in to a 32x16 region of out. + * If rot == 0, rotate -90, else rotate +90. + */ +static void +framebuffer_copy( + uint32_t * const out, + const uint32_t * const in, + int rot +) +{ + for (int x = 0 ; x < 16 ; x++) + { + for (int y = 0 ; y < 32 ; y++) + { + int ox, oy; + if (rot) + { + // rotate +90 (0,0) => (0,15) + ox = y; + oy = 15 - x; + } else { + // rotate -90 (0,0) => (31,0) + ox = 31 - y; + oy = x; + } + + out[ox + leds_width*oy] = in[x + width*y]; + } + } +} + + +/** With the panels mounted vertically, adjust the mapping. + * Even panels are rotated -90, odd ones +90. + * Input framebuffer is 256x32 + * Output framebuffer is 128x64 (actually x128, but we are not using the + * other half of it). + */ +void +framebuffer_flip( + uint32_t * const out, + const uint32_t * const in +) +{ + for (int x = 0, rot=0 ; x < width ; x += 16, rot = !rot) + { + int ox = (x*2) % leds_width; + int oy = (((x*2)) / leds_width) * 16; + + framebuffer_copy(&out[ox + oy * leds_width], &in[x], rot); + } +} + int main( @@ -95,7 +150,7 @@ main( char ** argv ) { - ledscape_t * const leds = ledscape_init(width, height); + ledscape_t * const leds = ledscape_init(leds_width, leds_height); printf("init done\n"); @@ -103,23 +158,25 @@ main( unsigned last_i = 0; unsigned i = 0; - uint32_t * const p = calloc(width*height,4); + uint32_t * const p = calloc(width*height, 4); + uint32_t * const fb = calloc(leds_width*leds_height,4); int scroll_x = 128; while (1) { - font_write(p, 0x00FF00, 0, 0, "1!NYCResistor"); - font_write(p, 0xFF0000, 7, 0, "!"); - font_write(p, 0x00FF00, 100, 0, "8min"); + font_write(p, 0x00FF00, 0, 0, "1.! NYCResistor-Atlantic Pacific"); + font_write(p, 0xFF0000, 11, 0, "!"); + font_write(p, 0x00FF00, 224, 0, "8min"); int end_x = font_write(p, 0xFF4000, scroll_x, 16, argc > 1 ? argv[1] : ""); if (end_x <= 0) - scroll_x = 128; + scroll_x = width; else scroll_x--; - ledscape_draw(leds, p); - usleep(30000); + framebuffer_flip(fb, p); + ledscape_draw(leds, fb); + usleep(20000); // wait for the previous frame to finish; //const uint32_t response = ledscape_wait(leds); From 539f380e8035336316608faf8b6a502d141fab67 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 23 Mar 2014 21:37:49 +0000 Subject: [PATCH 207/332] add framebuffer flipping code to deal with zig-zag orientation --- ledscape.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ ledscape.h | 13 +++++++++++ 2 files changed, 77 insertions(+) diff --git a/ledscape.c b/ledscape.c index c2b74df9..59d8f298 100644 --- a/ledscape.c +++ b/ledscape.c @@ -395,3 +395,67 @@ ledscape_set_color( p->g = g; p->b = b; } + + +/** Copy a 16x32 region from in to a 32x16 region of out. + * If rot == 0, rotate -90, else rotate +90. + */ +static void +framebuffer_copy( + uint32_t * const out, + const uint32_t * const in, + const int rot, + const int leds_width, + const int width +) +{ + for (int x = 0 ; x < 16 ; x++) + { + for (int y = 0 ; y < 32 ; y++) + { + int ox, oy; + if (rot) + { + // rotate +90 (0,0) => (0,15) + ox = y; + oy = 15 - x; + } else { + // rotate -90 (0,0) => (31,0) + ox = 31 - y; + oy = x; + } + + out[ox + leds_width*oy] = in[x + width*y]; + } + } +} + + +/** With the panels mounted vertically, adjust the mapping. + * Even panels are rotated -90, odd ones +90. + * Input framebuffer is 256x32 + * Output framebuffer is 128x64 (actually x128, but we are not using the + * other half of it). + */ +void +framebuffer_flip( + uint32_t * const out, + const uint32_t * const in, + const int leds_width, + const int leds_height, + const int width, + const int height +) +{ + (void) height; + + for (int x = 0, rot=0 ; x < width ; x += 16, rot = !rot) + { + int ox = (x*2) % leds_width; + int oy = (((x*2)) / leds_width) * 16; + + framebuffer_copy(&out[ox + oy * leds_width], &in[x], rot, leds_width, width); + } +} + + diff --git a/ledscape.h b/ledscape.h index 45456abf..5941b794 100644 --- a/ledscape.h +++ b/ledscape.h @@ -81,4 +81,17 @@ ledscape_close( ledscape_t * const leds ); + +/** Flip a rectangular frame buffer to map the LED matrices */ +void +framebuffer_flip( + uint32_t * leds_out, + const uint32_t * fb_in, + const int leds_width, + const int leds_height, + const int width, + const int height +); + + #endif From 6edab9eacdfe6b0d675a7a5d3a868de994c9f94b Mon Sep 17 00:00:00 2001 From: root Date: Sun, 23 Mar 2014 21:38:29 +0000 Subject: [PATCH 208/332] move brightness level to a top-level define --- matrix.p | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/matrix.p b/matrix.p index da7fbe16..2229aa04 100644 --- a/matrix.p +++ b/matrix.p @@ -22,6 +22,10 @@ #define MATRIX_HEIGHT 16 // 32x32 matrices #endif +// higher constants == brighter. +// 4 is a ok brightness, 5 is bright, 6 is powerful +#define BRIGHT_SHIFT 5 + #define r11_gpio 2 #define r11_pin 2 @@ -460,9 +464,7 @@ NEW_ROW_LOOP: //LSL out_clr, out_clr, 1 //MOV out_clr, 2048 - // higher constants == brighter. - // 4 is a ok brightness, 5 is bright, 6 is powerful - LSL out_clr, bright_thresh, 5 + LSL out_clr, bright_thresh, BRIGHT_SHIFT //LSL out_clr, bright_thresh, 10 //QBBS no_blank, out_set, bright From 8e6ccd396d7a6356357aec6bcafd3cb2abdf4228 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 23 Mar 2014 21:39:00 +0000 Subject: [PATCH 209/332] use framebuffer flipping code for16 matrix panel --- fire.c | 14 ++++++++----- matrix-udp-rx.c | 19 +++++++++++------ mta-sign.c | 55 +------------------------------------------------ 3 files changed, 23 insertions(+), 65 deletions(-) diff --git a/fire.c b/fire.c index f602df23..a93c81c2 100644 --- a/fire.c +++ b/fire.c @@ -11,6 +11,11 @@ #include #include "ledscape.h" +static const int w = 256; +static const int h = 36; +static const int leds_height = 128; +static const int leds_width = 128; + // Borrowed by OctoWS2811 rainbow test static unsigned int @@ -75,9 +80,6 @@ hsv2rgb( } -static const int w = 256; -static const int h = 64; - // This will contain the pixels used to calculate the fire effect static uint8_t fire[256][64]; @@ -180,7 +182,7 @@ init_pallete(void) int main(void) { - ledscape_t * const leds = ledscape_init(w,h); + ledscape_t * const leds = ledscape_init(leds_width,leds_height); printf("init done\n"); time_t last_time = time(NULL); unsigned last_i = 0; @@ -188,6 +190,7 @@ main(void) unsigned i = 0; init_pallete(); uint32_t * const p = calloc(w*h,4); + uint32_t * const fb = calloc(leds_width*leds_height,4); while (1) { @@ -198,7 +201,8 @@ main(void) fire_draw(p); sparkles(p, delta); - ledscape_draw(leds, p); + framebuffer_flip(fb, p, leds_width, leds_height, w, h); + ledscape_draw(leds, fb); usleep(50000); // wait for the previous frame to finish; diff --git a/matrix-udp-rx.c b/matrix-udp-rx.c index b00c1303..9986abe8 100644 --- a/matrix-udp-rx.c +++ b/matrix-udp-rx.c @@ -59,7 +59,9 @@ main( die("socket port %d failed: %s\n", port, strerror(errno)); const unsigned width = 256; - const unsigned height = 48; + const unsigned height = 64; + const unsigned leds_width = 128; + const unsigned leds_height = 128; const size_t image_size = width * height * 3; // largest possible UDP packet @@ -69,7 +71,7 @@ main( fprintf(stderr, "%u x %u, UDP port %u\n", width, height, port); - ledscape_t * const leds = ledscape_init(width, height); + ledscape_t * const leds = ledscape_init(leds_width, leds_height); const unsigned report_interval = 10; unsigned last_report = 0; @@ -77,6 +79,7 @@ main( unsigned frames = 0; uint32_t * const fb = calloc(width*height,4); + uint32_t * const leds_fb = calloc(leds_width*leds_height,4); while (1) { @@ -118,20 +121,24 @@ main( const unsigned frame_num = 0; + // copy the 3-byte values into the 4-byte framebuffer for (unsigned x = 0 ; x < width ; x++) { for (unsigned y = 0 ; y < height ; y++) { uint8_t * const out = (void*) &fb[x + y*width]; //const uint8_t * const in = &buf[1 + (x*64 + y+24)*3]; - const uint8_t * const in = &buf[1 + 3*(x + y*width)]; + const uint8_t * const in = &buf[1 + 3*(x*height + (width - y - 1))]; out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; + out[1] = in[1] / 2; + out[2] = in[2] / 2; } } - ledscape_draw(leds, fb); + // the panel is 256x32, the pyramid was 256x64. + // ignore the left most 16 pixels + framebuffer_flip(leds_fb, fb + width*0, leds_width, leds_height, width, height-16); + ledscape_draw(leds, leds_fb); gettimeofday(&stop_tv, NULL); timersub(&stop_tv, &start_tv, &delta_tv); diff --git a/mta-sign.c b/mta-sign.c index bb3fc44d..99709bee 100644 --- a/mta-sign.c +++ b/mta-sign.c @@ -90,59 +90,6 @@ font_write( return x; } -/** Copy a 16x32 region from in to a 32x16 region of out. - * If rot == 0, rotate -90, else rotate +90. - */ -static void -framebuffer_copy( - uint32_t * const out, - const uint32_t * const in, - int rot -) -{ - for (int x = 0 ; x < 16 ; x++) - { - for (int y = 0 ; y < 32 ; y++) - { - int ox, oy; - if (rot) - { - // rotate +90 (0,0) => (0,15) - ox = y; - oy = 15 - x; - } else { - // rotate -90 (0,0) => (31,0) - ox = 31 - y; - oy = x; - } - - out[ox + leds_width*oy] = in[x + width*y]; - } - } -} - - -/** With the panels mounted vertically, adjust the mapping. - * Even panels are rotated -90, odd ones +90. - * Input framebuffer is 256x32 - * Output framebuffer is 128x64 (actually x128, but we are not using the - * other half of it). - */ -void -framebuffer_flip( - uint32_t * const out, - const uint32_t * const in -) -{ - for (int x = 0, rot=0 ; x < width ; x += 16, rot = !rot) - { - int ox = (x*2) % leds_width; - int oy = (((x*2)) / leds_width) * 16; - - framebuffer_copy(&out[ox + oy * leds_width], &in[x], rot); - } -} - int main( @@ -174,7 +121,7 @@ main( else scroll_x--; - framebuffer_flip(fb, p); + framebuffer_flip(fb, p, leds_width, leds_height, width, height); ledscape_draw(leds, fb); usleep(20000); From 6b0e0b09bd77ab9e4e248b49ee36279d95a601ac Mon Sep 17 00:00:00 2001 From: root Date: Mon, 24 Mar 2014 01:16:29 +0000 Subject: [PATCH 210/332] flip the framebuffer for the leds --- matrix-test.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/matrix-test.c b/matrix-test.c index b142fcac..2c187a94 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -188,9 +188,12 @@ gradient( int main(void) { - const int width = 128; - const int height = 128; - ledscape_t * const leds = ledscape_init(width, height); + const int width = 256; + const int height = 32; + const int led_width = 128; + const int led_height = 128; + ledscape_t * const leds = ledscape_init(led_width, led_height); + printf("init done\n"); time_t last_time = time(NULL); unsigned last_i = 0; @@ -206,6 +209,7 @@ main(void) unsigned i = 0; uint32_t * const p = calloc(width*height,4); + uint32_t * const led_fb = calloc(led_width*led_height,4); while (1) { @@ -213,7 +217,8 @@ main(void) rainbow(p, width, height, 10, i++); else gradient(p, width, height, 10, i++); - ledscape_draw(leds, p); + framebuffer_flip(led_fb, p, led_width, led_height, width, height); + ledscape_draw(leds, led_fb); usleep(20000); // wait for the previous frame to finish; From 98a904b9c4d29d15c885c686a7a6ee6d2fc3c1f1 Mon Sep 17 00:00:00 2001 From: Guy Dickinson Date: Wed, 26 Mar 2014 12:03:15 -0400 Subject: [PATCH 211/332] Add 'q', ':', ',' to MTA font JSON --- fonts/mta-sign.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fonts/mta-sign.json b/fonts/mta-sign.json index b3cb9ee6..bc0c5a3f 100644 --- a/fonts/mta-sign.json +++ b/fonts/mta-sign.json @@ -3,7 +3,7 @@ "36":[1920,8160,16368,31224,30968,63868,63932,61500,31224,31224,16368,8160,1920,0,0,0], "37":[1920,8160,16368,28728,32568,65340,61500,62460,29496,30840,16368,8160,1920,0,0,0], "42":[256,896,1984,3168,6960,16184,31804,14648,6448,3168,1984,896,256,0,0,0], -"44":[0,0,0,0,0,0,0,0,0,0,12,12,8,4,0,0], +"44":[0,0,0,0,0,0,0,0,0,0,12,12,4,6,0,0], "45":[0,0,0,0,0,0,0,124,0,0,0,0,0,0,0,0], "46":[0,0,0,0,0,0,0,0,0,0,12,12,0,0,0,0], "47":[0,0,0,504,496,480,496,440,284,12,0,0,0,0,0,0], @@ -17,6 +17,7 @@ "55":[0,252,252,192,96,96,48,48,24,24,12,12,0,0,0,0], "56":[0,120,252,204,204,120,120,204,204,204,252,120,0,0,0,0], "57":[0,120,252,204,204,204,252,248,192,204,252,120,0,0,0,0], +"58":[0,0,0,0,24,24,0,0,0,0,24,24,0,0,0,0], "60":[0,0,0,32,48,1016,1020,1016,48,32,0,0,0,0,0,0], "62":[0,0,0,64,192,508,1020,508,192,64,0,0,0,0,0,0], "64":[1920,8160,16368,30840,29496,62460,63996,64764,32376,28728,16368,8160,1920,0,0,0], @@ -61,6 +62,7 @@ "110":[0,0,0,0,124,252,204,204,204,204,204,204,0,0,0,0], "111":[0,0,0,0,120,252,204,204,204,204,252,120,0,0,0,0], "112":[0,0,0,0,60,124,108,108,108,108,124,60,12,12,12,0], +"113":[0,0,0,0,248,252,204,204,204,204,252,248,192,192,192,0], "114":[0,0,0,0,56,124,12,12,12,12,12,12,0,0,0,0], "115":[0,0,0,0,120,252,12,124,248,192,252,124,0,0,0,0], "116":[0,24,24,60,60,24,24,24,24,24,56,56,0,0,0,0], From 7581bcbb958ab4aa5dfd20ffc7541c60f4281ee7 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 28 Mar 2014 10:43:31 -0400 Subject: [PATCH 212/332] brackets for octoscroller, 8 or 16 sided --- pcb/octoscroller.scad | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 pcb/octoscroller.scad diff --git a/pcb/octoscroller.scad b/pcb/octoscroller.scad new file mode 100644 index 00000000..ee17659a --- /dev/null +++ b/pcb/octoscroller.scad @@ -0,0 +1,52 @@ +/** \file + * 3D printed brackets for N sided LED matrix displays. + * + * Horizontal or vertical connections are possible. + * The spacing between the holes differs for each. + */ +sides = 16; +orientation = 1; + + +// horizontal has 13 mm from edge to center of hole. +module horizontal_bracket() +{ + rotate([0,0,-360/sides/2]) + render() difference() { + translate([-20,0,]) cube([20,6,10]); + translate([-13,15,5]) rotate([90,0,0]) cylinder(r=3,h=20); + } + + rotate([0,0,+360/sides/2]) + render() difference() { + translate([0,0,]) cube([20,6,10]); + translate([13,15,5]) rotate([90,0,0]) cylinder(r=3,h=20); + } +} + +// vetical has only 10mm +module vertical_bracket() +{ + rotate([0,0,-360/sides/2]) + render() difference() { + translate([-16,0,]) cube([16,8,10]); + translate([-10,15,5]) rotate([90,0,0]) cylinder(r=2,h=20, $fs=1); + } + + rotate([0,0,+360/sides/2]) + render() difference() { + translate([0,0,]) cube([16,8,10]); + translate([10,15,5]) rotate([90,0,0]) cylinder(r=2,h=20, $fs=1); + } +} + + +for (i = [0:3]) +{ + for (j = [0:3]) + { + translate([i*21, j*37,0]) + rotate([0,0,90]) + vertical_bracket(); + } +} From e6a70651a191921c3b9f57548085fb104ada62d6 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 28 Mar 2014 20:23:36 +0000 Subject: [PATCH 213/332] matrix config into a separate routine --- mta-sign.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 162 insertions(+), 7 deletions(-) diff --git a/mta-sign.c b/mta-sign.c index 99709bee..b6f623f8 100644 --- a/mta-sign.c +++ b/mta-sign.c @@ -12,8 +12,6 @@ #include "ledscape.h" #include "mta-font.c" -const int leds_width = 128; -const int leds_height = 128; const int width = 256; const int height = 32; @@ -72,8 +70,15 @@ font_write( for (int j = 0 ; j < max_width ; j++, row >>= 1) { uint32_t pixel_color = (row & 1) ? color : 0; +/* if (x + j >= width || x + j < 0) continue; +*/ + if (x + j >= width) + continue; + if (x + j < 0) + x = width - x + j; + if (y + h >= height || y + h < 0) continue; @@ -91,13 +96,163 @@ font_write( } +typedef struct { + int x; + int y; + int rot; // 0 == none, 1 == left, 2 == right, 3 == flip +} ledscape_panel_t; + +#define LEDSCAPE_OUTPUTS 8 // number of outputs on the cape +#define LEDSCAPE_PANELS 8 // number of panels chained per output + +typedef struct { + int width; + int height; + int panel_width; + int panel_height; + int leds_width; + int leds_height; + ledscape_panel_t panels[LEDSCAPE_OUTPUTS][LEDSCAPE_PANELS]; +} ledscape_config_t; + +static ledscape_config_t ledscape_config = +{ + // frame buffer size + .width = 256, + .height = 32, + + // panel size + .panel_width = 32, + .panel_height = 16, + + // ledscape matrix output size + .leds_width = LEDSCAPE_PANELS*32, // could be less + .leds_height = LEDSCAPE_OUTPUTS*16, + + .panels = { + [0] = { + [0] = { 0, 0, 2 }, + [1] = { 16, 0, 1 }, + [2] = { 32, 0, 2 }, + [3] = { 48, 0, 1 }, + [4] = { 64, 0, 2 }, + [5] = { 80, 0, 1 }, + [6] = { 96, 0, 2 }, + [7] = { 112, 0, 1 }, + }, + [1] = { + [7] = { 128, 0, 2 }, + [6] = { 144, 0, 1 }, + [5] = { 160, 0, 2 }, + [4] = { 176, 0, 1 }, + [3] = { 192, 0, 2 }, + [2] = { 208, 0, 1 }, + [1] = { 224, 0, 2 }, + [0] = { 240, 0, 1 }, + }, + }, +}; + + +/** Copy a 16x32 region from in to a 32x16 region of out. + * If rot == 0, rotate -90, else rotate +90. + */ +static void +framebuffer_copy( + uint32_t * const out, + const uint32_t * const in, + const ledscape_config_t * const config, + const int rot +) +{ + for (int x = 0 ; x < config->panel_width ; x++) + { + for (int y = 0 ; y < config->panel_height ; y++) + { + int ox, oy; + if (rot == 0) + { + // no rotation == (0,0) => (0,0) + ox = x; + oy = y; + } else + if (rot == 1) + { + // rotate +90 (0,0) => (0,15) + ox = config->panel_height-1 - y; + oy = x; + } else + if (rot == 2) + { + // rotate -90 (0,0) => (31,0) + ox = y; + oy = config->panel_width-1 - x; + } else + if (rot == 3) + { + // flip == (0,0) => (31,15) + ox = config->panel_width-1 - x; + oy = config->panel_height-1 - y; + } else + { + // barf + ox = oy = 0; + } + + out[x + config->leds_width*y] + = in[ox + config->width*oy]; + } + } +} + + +/** With the panels mounted vertically, adjust the mapping. + * Even panels are rotated -90, odd ones +90. + * Input framebuffer is 256x32 + */ +void +framebuffer_fixup( + uint32_t * const out, + const uint32_t * const in, + const ledscape_config_t * const config +) +{ + for (int i = 0 ; i < LEDSCAPE_OUTPUTS ; i++) + { + for (int j = 0 ; j < LEDSCAPE_PANELS ; j++) + { + const ledscape_panel_t * const panel + = &config->panels[i][j]; + + int ox = config->panel_width * j; + int oy = config->panel_height * i; + printf("%d,%d => %d,%d <= %d,%d,%d\n", i, j, ox, oy, panel->x, panel->y, panel->rot); + + const uint32_t * const ip + = &in[panel->x + panel->y * config->width]; + uint32_t * const op + = &out[ox + oy * config->leds_width]; + + framebuffer_copy( + op, + ip, + config, + panel->rot + ); + } + } +} + + + int main( int argc, char ** argv ) { - ledscape_t * const leds = ledscape_init(leds_width, leds_height); + ledscape_t * const leds + = ledscape_init(ledscape_config.leds_width, ledscape_config.leds_height); printf("init done\n"); @@ -105,9 +260,9 @@ main( unsigned last_i = 0; unsigned i = 0; - uint32_t * const p = calloc(width*height, 4); - uint32_t * const fb = calloc(leds_width*leds_height,4); - int scroll_x = 128; + uint32_t * const p = calloc(ledscape_config.width*ledscape_config.height, 4); + uint32_t * const fb = calloc(ledscape_config.leds_width*ledscape_config.leds_height,4); + int scroll_x = 256; while (1) { @@ -121,7 +276,7 @@ main( else scroll_x--; - framebuffer_flip(fb, p, leds_width, leds_height, width, height); + framebuffer_fixup(fb, p, &ledscape_config); ledscape_draw(leds, fb); usleep(20000); From 3d818a9d43e7691c4f4d15418ebbdd5aa580f485 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 28 Mar 2014 20:55:35 +0000 Subject: [PATCH 214/332] wrapping sort of works --- mta-sign.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/mta-sign.c b/mta-sign.c index b6f623f8..c775b3cc 100644 --- a/mta-sign.c +++ b/mta-sign.c @@ -70,19 +70,22 @@ font_write( for (int j = 0 ; j < max_width ; j++, row >>= 1) { uint32_t pixel_color = (row & 1) ? color : 0; + int ox = x + j; /* if (x + j >= width || x + j < 0) continue; */ - if (x + j >= width) + if (ox >= width) continue; - if (x + j < 0) - x = width - x + j; + + // wrap in x + if (ox < 0) + ox += width; if (y + h >= height || y + h < 0) continue; - uint8_t * pix = (uint8_t*) &buf[(y+h)*width + x + j]; + uint8_t * pix = (uint8_t*) &buf[(y+h)*width + ox]; pix[0] = pixel_color >> 16; pix[1] = pixel_color >> 8; pix[2] = pixel_color >> 0; From 4559efe9a2fe414b6c8ce780e23e70d358bfd194 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 28 Mar 2014 20:55:58 +0000 Subject: [PATCH 215/332] 8 panels of output; should be a config --- ledscape.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/ledscape.c b/ledscape.c index 59d8f298..3c09ebf4 100644 --- a/ledscape.c +++ b/ledscape.c @@ -293,7 +293,7 @@ ledscape_init( #ifdef CONFIG_LED_MATRIX *(leds->matrix) = (led_matrix_config_t) { - .matrix_width = 128, + .matrix_width = 256, .matrix_height = 8, .matrix = { { 0, 0 }, @@ -454,7 +454,17 @@ framebuffer_flip( int ox = (x*2) % leds_width; int oy = (((x*2)) / leds_width) * 16; - framebuffer_copy(&out[ox + oy * leds_width], &in[x], rot, leds_width, width); + // if we are more than half-way past the width, + // flip the axis + const uint32_t * p = &in[x]; + + framebuffer_copy( + &out[ox + oy * leds_width], + p, + rot, + leds_width, + width + ); } } From 748d5d55d10c4fb716d340c53569dbc4d842e14a Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 28 Mar 2014 17:02:45 -0400 Subject: [PATCH 216/332] config files --- mac80211.conf => debian/mac80211.conf | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename mac80211.conf => debian/mac80211.conf (100%) diff --git a/mac80211.conf b/debian/mac80211.conf similarity index 100% rename from mac80211.conf rename to debian/mac80211.conf From 15b730c17750b12a57fa382caa4b2e306c7273ba Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Fri, 28 Mar 2014 19:06:42 -0400 Subject: [PATCH 217/332] 20mm brackets the other way --- pcb/flat-20mm.scad | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/pcb/flat-20mm.scad b/pcb/flat-20mm.scad index c8e2b4eb..6715f7c6 100644 --- a/pcb/flat-20mm.scad +++ b/pcb/flat-20mm.scad @@ -1,33 +1,48 @@ /** \file * Brackets for 20mm extrusion. * - * These hold the panels a few mm away from the bracket. + * These hold the panels a few mm away from the bracket in alternating + * orientation. */ -length=20; width=20; -render() difference () { - translate([0,0,4]) cube([28,length,6], center=true); +module baseplate() +{ +render() difference() +{ + translate([0,0,3]) cube([32,28,6], center=true); - translate([10,5,-1]) cylinder(r=3.5/2, h=6, $fs=1); - translate([10,5,4]) cylinder(r=6/2, h=4, $fs=1); + translate([0,-10,-1]) cylinder(r=3.75/2, h=6, $fs=1); + translate([0,-10,2]) cylinder(r=6/2, h=5, $fs=1); - translate([-10,5,-1]) cylinder(r=3.5/2, h=6, $fs=1); - translate([-10,5,4]) cylinder(r=6/2, h=4, $fs=1); + translate([0,+10,-1]) cylinder(r=3.75/2, h=6, $fs=1); + translate([0,+10,2]) cylinder(r=6/2, h=5, $fs=1); +} } -translate([width/2+2,-4,width/2+6]) render() difference() { - cube([4,length-8,width], center=true); - translate([-3,0,0]) rotate([0,90,0]) cylinder(r=4.5/2, h=6, $fs=1); +module upright() +{ + rotate([0,-90,0]) render() difference() { + linear_extrude(height=6) + polygon([[-1,-14], [0,-14], [20,-5], [20,+5], [0,+14], [-1,+14]]); + translate([10,0,-1]) cylinder(r=4.5/2, h=8, $fs=1); + } } -translate([-(width/2+2),-4,width/2+6]) render() difference() { - cube([4,length-8,width], center=true); - translate([-3,0,0]) rotate([0,90,0]) cylinder(r=4.5/2, h=6, $fs=1); +module bracket() +{ + baseplate(); + translate([20/2+6,0,6]) upright(); + translate([-20/2,0,6]) upright(); } +for (i=[-3:4]) +{ + translate([0,i*30,0]) bracket(); +} + %color([0,1,0]) translate([0,0,width/2+6]) extrusion(100); module extrusion(len) From 41666a8824f13a9fd0444eab18d81c6f46f7cbef Mon Sep 17 00:00:00 2001 From: root Date: Sat, 29 Mar 2014 18:20:27 +0000 Subject: [PATCH 218/332] matrix-udp-rx works with pyramid and mini-pyramid --- matrix-udp-rx.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/matrix-udp-rx.c b/matrix-udp-rx.c index 9986abe8..afc18e37 100644 --- a/matrix-udp-rx.c +++ b/matrix-udp-rx.c @@ -60,7 +60,7 @@ main( const unsigned width = 256; const unsigned height = 64; - const unsigned leds_width = 128; + const unsigned leds_width = 256; const unsigned leds_height = 128; const size_t image_size = width * height * 3; @@ -80,6 +80,7 @@ main( uint32_t * const fb = calloc(width*height,4); uint32_t * const leds_fb = calloc(leds_width*leds_height,4); + ledscape_draw(leds, leds_fb); while (1) { @@ -122,11 +123,12 @@ main( const unsigned frame_num = 0; // copy the 3-byte values into the 4-byte framebuffer - for (unsigned x = 0 ; x < width ; x++) + // and turn onto the side + for (unsigned x = 0 ; x < width ; x++) // 256 { - for (unsigned y = 0 ; y < height ; y++) + for (unsigned y = 0 ; y < height ; y++) // 64 { - uint8_t * const out = (void*) &fb[x + y*width]; + uint8_t * const out = (void*) &fb[y*2*leds_width + x]; //const uint8_t * const in = &buf[1 + (x*64 + y+24)*3]; const uint8_t * const in = &buf[1 + 3*(x*height + (width - y - 1))]; out[0] = in[0]; @@ -135,10 +137,13 @@ main( } } - // the panel is 256x32, the pyramid was 256x64. - // ignore the left most 16 pixels +#if 0 + // the panel is 256x128, the pyramid was 256x64. framebuffer_flip(leds_fb, fb + width*0, leds_width, leds_height, width, height-16); ledscape_draw(leds, leds_fb); +#else + ledscape_draw(leds, fb); +#endif gettimeofday(&stop_tv, NULL); timersub(&stop_tv, &start_tv, &delta_tv); From 2ec1727dc93605241f3e45babc6d758fcebf327e Mon Sep 17 00:00:00 2001 From: root Date: Fri, 4 Apr 2014 01:27:01 +0000 Subject: [PATCH 219/332] fire rendering works on the mini-pyramid --- fire.c | 61 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/fire.c b/fire.c index a93c81c2..1b8b71a3 100644 --- a/fire.c +++ b/fire.c @@ -11,10 +11,12 @@ #include #include "ledscape.h" -static const int w = 256; -static const int h = 36; +// sideways pyramid; 256 height, but 128 wide +#define width 128 +#define height 256 + +static const int leds_width = 256; static const int leds_height = 128; -static const int leds_width = 128; // Borrowed by OctoWS2811 rainbow test @@ -81,51 +83,60 @@ hsv2rgb( // This will contain the pixels used to calculate the fire effect -static uint8_t fire[256][64]; +static uint8_t fire[width][height]; // Flame colors static uint32_t palette[255]; static float angle; -static uint32_t calc1[256], calc2[256], calc3[256], calc4[256], calc5[256]; +static uint32_t calc1[width], calc2[height], calc3[width], calc4[width], calc5[height]; static void fire_draw( uint32_t * const frame ) { - memset(frame, 0, w*h*sizeof(*frame)); + memset(frame, 0, width*height*sizeof(*frame)); angle = angle + 0.05; // Randomize the bottom row of the fire buffer - for (int x = 0; x < w; x++) + for (int x = 0; x < width; x++) { - fire[x][h-1] = random() % 190; + fire[x][height-1] = random() % 190; } int counter = 0; // Do the fire calculations for every pixel, from top to bottom - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { + for (int x = 0; x < width; x++) { // up to 128, leds_height + for (int y = 0; y < height; y++) { // up to 256, leds_width // Add pixel values around current pixel fire[x][y] = ((fire[calc3[x]][calc2[y]] + fire[calc1[x]][calc2[y]] + fire[calc4[x]][calc2[y]] - + fire[calc1[x]][calc5[y]]) << 5) / (128+(abs(x-w/2))/4); // 129; + + fire[calc1[x]][calc5[y]]) << 5) / (128+(abs(x-width/2))/4); // 129; // Output everything to screen using our palette colors const uint32_t c = palette[fire[x][y]]; //frame[counter] = fire[x][y]; // Extract the red value using right shift and bit mask - // equivalent of red(pgTemp.pixels[x+y*w]) + // equivalent of red(pgTemp.pixels[x+y*width]) // Only map 3D cube 'lit' pixels onto fire array needed for next frame if (((c >> 0) & 0xFF) == 128) fire[x][y] = 128; - frame[counter++] = c; + // skip the bottom few rows +#if 1 + if (y > height - leds_width) + frame[y - (height - leds_width) + x*leds_width] = c; +#else + if (x > height - leds_width) + frame[y - (height - leds_width) + x*leds_width] = c; +#endif + //frame[(leds_width-x-1) + y*leds_height] = c; + //frame[counter++] = c; } } } @@ -138,7 +149,7 @@ sparkles( ) { for(int i = 0 ; i < num_sparkles ; i++) - frame[rand() % (16*256)] = 0xFFFFFF; + frame[rand() % (width*height)] = 0xFFFFFF; } static int constrain( @@ -166,15 +177,15 @@ init_pallete(void) // Precalculate which pixel values to add during animation loop // this speeds up the effect by 10fps - for (int x = 0; x < w; x++) { - calc1[x] = x % w; - calc3[x] = (x - 1 + w) % w; - calc4[x] = (x + 1) % w; + for (int x = 0; x < width; x++) { + calc1[x] = x % width; + calc3[x] = (x - 1 + width) % width; + calc4[x] = (x + 1) % width; } - for (int y = 0; y < h; y++) { - calc2[y] = (y + 1) % h; - calc5[y] = (y + 2) % h; + for (int y = 0; y < height; y++) { + calc2[y] = (y + 1) % height; + calc5[y] = (y + 2) % height; } } @@ -189,7 +200,7 @@ main(void) unsigned i = 0; init_pallete(); - uint32_t * const p = calloc(w*h,4); + uint32_t * const p = calloc(width*height,4); uint32_t * const fb = calloc(leds_width*leds_height,4); while (1) @@ -201,8 +212,12 @@ main(void) fire_draw(p); sparkles(p, delta); - framebuffer_flip(fb, p, leds_width, leds_height, w, h); +#if 0 + framebuffer_flip(fb, p, leds_width, leds_height, width, height); ledscape_draw(leds, fb); +#else + ledscape_draw(leds, p); +#endif usleep(50000); // wait for the previous frame to finish; From d7b5cb668ebef29fc9014e7887eb9162862dfc29 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 4 Apr 2014 01:27:17 +0000 Subject: [PATCH 220/332] full size octoscroller matrix --- identify.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/identify.c b/identify.c index 5e22f920..06a5f18f 100644 --- a/identify.c +++ b/identify.c @@ -11,7 +11,7 @@ #include "ledscape.h" #include "mta-font.c" -const int width = 128; +const int width = 256; const int height = 128; @@ -106,7 +106,7 @@ main( int scroll_x = 128; memset(p, 0x10, width*height*4); - for (int x = 0 ; x < 128 ; x += 32) + for (int x = 0 ; x < 256 ; x += 32) { for (int y = 0 ; y < 128 ; y += 16) { From c49e2a8a65d4ef28b92dc68ea5b4626d8ad54b65 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 4 Apr 2014 01:27:40 +0000 Subject: [PATCH 221/332] full size mini-pyramid --- matrix-test.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/matrix-test.c b/matrix-test.c index 2c187a94..997bfd54 100644 --- a/matrix-test.c +++ b/matrix-test.c @@ -189,8 +189,8 @@ int main(void) { const int width = 256; - const int height = 32; - const int led_width = 128; + const int height = 128; + const int led_width = 256; const int led_height = 128; ledscape_t * const leds = ledscape_init(led_width, led_height); @@ -217,8 +217,15 @@ main(void) rainbow(p, width, height, 10, i++); else gradient(p, width, height, 10, i++); - framebuffer_flip(led_fb, p, led_width, led_height, width, height); - ledscape_draw(leds, led_fb); + + if (0) + { + framebuffer_flip(led_fb, p, led_width, led_height, width, height); + ledscape_draw(leds, led_fb); + } else { + ledscape_draw(leds, p); + } + usleep(20000); // wait for the previous frame to finish; From a8c7093130585c5d921e35173e4fbc3011d1732f Mon Sep 17 00:00:00 2001 From: root Date: Fri, 4 Apr 2014 01:27:59 +0000 Subject: [PATCH 222/332] receive and space the pixels for the mini pyramid --- matrix-udp-rx.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/matrix-udp-rx.c b/matrix-udp-rx.c index afc18e37..691c19b0 100644 --- a/matrix-udp-rx.c +++ b/matrix-udp-rx.c @@ -128,12 +128,19 @@ main( { for (unsigned y = 0 ; y < height ; y++) // 64 { - uint8_t * const out = (void*) &fb[y*2*leds_width + x]; - //const uint8_t * const in = &buf[1 + (x*64 + y+24)*3]; + uint8_t * out = (void*) &fb[y*2*leds_width + x]; const uint8_t * const in = &buf[1 + 3*(x*height + (width - y - 1))]; out[0] = in[0]; - out[1] = in[1] / 2; - out[2] = in[2] / 2; + out[1] = in[1];// / 2; + out[2] = in[2];// / 2; + + if (0) { + // double the pixels? + out += leds_width * 4; + out[0] = in[0]; + out[1] = in[1] / 2; + out[2] = in[2] / 2; + } } } From 87e9f86f42ec0144d3afb1bdd5bb5098ae3b8059 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 7 Apr 2014 00:05:15 +0000 Subject: [PATCH 223/332] disable double buffering --- ledscape.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ledscape.c b/ledscape.c index 3c09ebf4..5103d54c 100644 --- a/ledscape.c +++ b/ledscape.c @@ -206,7 +206,7 @@ ledscape_draw( } } leds->ws281x->pixels_dma = leds->pru->ddr_addr + leds->frame_size * frame; - frame = (frame + 1) & 1; + //frame = (frame + 1) & 1; #else // Translate the RGBA frame into G R B, sliced by color // only 48 outputs currently supported @@ -272,6 +272,7 @@ ledscape_init( const size_t frame_size = 48 * width * 8 * 3; #endif + printf("frame-size %zu, ddr-size=%zu\n", frame_size, pru->ddr_size); #if 0 if (2 *frame_size > pru->ddr_size) die("Pixel data needs at least 2 * %zu, only %zu in DDR\n", From a228f07e71f6fa49996c383dc7c0744e2ab315a7 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 7 Apr 2014 00:05:28 +0000 Subject: [PATCH 224/332] enable life on the full pyramid --- Makefile | 3 +- life.c | 236 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ matrix.p | 23 +++++- 3 files changed, 260 insertions(+), 2 deletions(-) create mode 100644 life.c diff --git a/Makefile b/Makefile index 9863ed20..0ea30e2a 100755 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ TARGETS += matrix-test TARGETS += fire TARGETS += matrix-udp-rx TARGETS += opc-rx +TARGETS += life TARGETS += cube-life TARGETS += cube-image TARGETS += mta-sign @@ -107,7 +108,7 @@ clean: # The correct way to reserve the GPIO pins on the BBB is with the # capemgr and a Device Tree file. But it doesn't work. # -SLOT_FILE=/sys/devices/bone_capemgr.8/slots +SLOT_FILE=/sys/devices/bone_capemgr.9/slots DTS=CAPE-BONE-OCTO DTB=/lib/firmware/$(DTS)-00A0.dtbo diff --git a/life.c b/life.c new file mode 100644 index 00000000..b0e9d1cd --- /dev/null +++ b/life.c @@ -0,0 +1,236 @@ +/** \file + * Play the game of life on the normal pyramid + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "ledscape.h" + +#define LIFE_R 0xFF +#define LIFE_G 0x35 +#define LIFE_B 0x90 +#define SMOOTH_R 127 +#define SMOOTH_G 20 +#define SMOOTH_B 10 +#define DELTA_R 10 +#define DELTA_G 30 +#define DELTA_B 80 + +#define WIDTH 128 +#define HEIGHT 256 + +typedef struct +{ + uint8_t board[HEIGHT][WIDTH]; +} game_t; + +static game_t board; + + +static void +randomize( + game_t * const b, + int chance +) +{ + for (int y = 0 ; y < HEIGHT ; y++) + { + for (int x = 0 ; x < WIDTH ; x++) + { +#if 1 + unsigned live = (rand() % 128 < chance); + b->board[y][x] = live ? 3 : 0; +#else + b->board[y][x] = 0; +#endif + } + } + +} + + +static void +make_glider( + game_t * const b +) +{ + // X + // X + // XXX + int px = (rand() % 8) + 10; + int py = (rand() % 8) + 20; + b->board[py+0][px+0] = 0; + b->board[py+0][px+1] = 3; + b->board[py+0][px+2] = 0; + + b->board[py+1][px+0] = 0; + b->board[py+1][px+1] = 0; + b->board[py+1][px+2] = 3; + + b->board[py+2][px+0] = 3; + b->board[py+2][px+1] = 3; + b->board[py+2][px+2] = 3; +} + + + +static unsigned +get_space( + game_t * const b, + int x, + int y +) +{ + if (x >= 0 && y >= 0 && x < WIDTH && y < HEIGHT) + return b->board[y][x] & 1; + + return 0; +} + + +static void +play_game( + game_t * const b +) +{ + for (int y = 0 ; y < HEIGHT ; y++) + { + for (int x = 0 ; x < WIDTH ; x++) + { + uint8_t sum = 0; + + sum += get_space(b, x-1, y-1); + sum += get_space(b, x-1, y ); + sum += get_space(b, x-1, y+1); + + sum += get_space(b, x , y-1); + sum += get_space(b, x , y+1); + + sum += get_space(b, x+1, y-1); + sum += get_space(b, x+1, y ); + sum += get_space(b, x+1, y+1); + + +/* +Any live cell with fewer than two live neighbours dies, +as if caused by under-population. +Any live cell with two or three live neighbours lives +on to the next generation. +Any live cell with more than three live neighbours dies, +as if by overcrowding. +Any dead cell with exactly three live neighbours becomes a live cell, +as if by reproduction. +*/ + if (b->board[y][x] & 1) + { + // currently live + if (sum == 2 || sum == 3) + b->board[y][x] |= 2; + else + b->board[y][x] &= ~2; + } else { + // currently dead + if (sum == 3) + b->board[y][x] |= 2; + else + b->board[y][x] &= ~2; + } + } + } +} + + + +static void +copy_to_fb( + uint32_t * const p, + const unsigned width, + const unsigned height, + game_t * const board +) +{ + (void) height; + + for (int y = 0 ; y < HEIGHT ; y++) + { + for (int x = 0 ; x < WIDTH ; x++) + { + uint32_t * const pix_ptr = &p[width*y + x]; + uint32_t pix = *pix_ptr; + unsigned r = (pix >> 0) & 0xFF; + unsigned g = (pix >> 8) & 0xFF; + unsigned b = (pix >> 16) & 0xFF; + + // copy the new value to the current value + uint8_t * const sq = &board->board[y][x]; + *sq = (*sq & 2) | (*sq >> 1); + + unsigned live = *sq & 1; + if (live) + { + r += DELTA_R; + g += DELTA_G; + b += DELTA_B; + if (r > LIFE_R) + r = LIFE_R; + if (g > LIFE_G) + g = LIFE_G; + if (b > LIFE_B) + b = LIFE_B; + } else { + r = (r * SMOOTH_R) / (SMOOTH_R+1); + g = (g * SMOOTH_G) / (SMOOTH_G+1); + b = (b * SMOOTH_B) / (SMOOTH_B+1); + } + + *pix_ptr = (r << 0) | (g << 8) | (b << 16); + } + } +} + + + +int +main(void) +{ + const int leds_width = 128; + const int leds_height = 256; + ledscape_t * const leds = ledscape_init(leds_width, leds_height); + printf("init done\n"); + time_t last_time = time(NULL); + unsigned last_i = 0; + + unsigned i = 0; + uint32_t * const p = calloc(leds_width*leds_height,4); + + srand(getpid()); + + while (1) + { + if ((i & 0x7FF) == 0) + { + printf("randomize\n"); + randomize(&board, 20); + //make_glider(&boards[i]); + } + + if (i++ % 4 == 0) + { + play_game(&board); + } + + copy_to_fb(p, leds_width, leds_height, &board); + + ledscape_draw(leds, p); + usleep(1000); + } + + ledscape_close(leds); + + return EXIT_SUCCESS; +} diff --git a/matrix.p b/matrix.p index 2229aa04..b9fe7031 100644 --- a/matrix.p +++ b/matrix.p @@ -167,6 +167,8 @@ |(1< Date: Tue, 8 Apr 2014 21:20:20 +0000 Subject: [PATCH 225/332] pre-compiled device tree cape --- dts/CAPE-BONE-OCTO-00A0.dtbo | Bin 0 -> 1858 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 dts/CAPE-BONE-OCTO-00A0.dtbo diff --git a/dts/CAPE-BONE-OCTO-00A0.dtbo b/dts/CAPE-BONE-OCTO-00A0.dtbo new file mode 100644 index 0000000000000000000000000000000000000000..8c464516fa7c982d3f973653e5770eb51493b34b GIT binary patch literal 1858 zcmZ{lziSjh6vt=%6-5Gy1j~qs3f^vRe;7BxBAyBIScScVz_a+Ad5yMod%kQ(p&azow(oXU$^g`l zLOb4Ssjd0Bo9g`a#rbkb;Miekr<=`d&ALxnfamdrDNWY}T7#@f)*^eE>?GMMWNowt z=?&5wq&G-!klrA@L3*RqPhphVL~Bv31+lgU5?cd>t%1PSbP#|A0ay~~kQ|;NIao*z z7LtRdNS#7;ip5E74JQRl{RZ{pq_$>KPLpz)l+&b~Cgn6K)}&aIVoi#*C>9I0wX$G~ zVl9fbDAt-3agwL0kjqJYFVOLm3uP&Bdw~qInR2yp{SQG?zrX(Q7snkZT9t|K_8kXY zp~PMoaJMVZ@_4+9acZ)+B@G)F2_mxK|Au(^1Pt-JhXhGK4=rW z&eX*I=Shr1%vv3z55(+RADkD?=#p3DF;7YFItKj@>-gq$<|aLvP2+yXAJ&DMr?o~O zrg>g#jJ+D3-;X-3KUhUM$0e9!y^i1SJ*Hs^I$7eYO|Gt5%VV7=h~3O<`%=VilBr=H zv|-=CeUy4pC}h#`^VD0FYM#R14ZWbKlBHevBYs literal 0 HcmV?d00001 From c5d880bf78c5e9d2114d0cf9e74aaeb7220e2ad0 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 Apr 2014 17:36:02 +0000 Subject: [PATCH 226/332] move everything into subdirectories; makefile is broken for now --- VideoDisplay/VideoDisplay.ino | 259 ---------- VideoDisplay/mac.cpp | 32 -- VideoDisplay/mac.h | 7 - bad-pattern.c | 27 - bad-pattern.txt | 38 -- bbb-network-setup => bin/bbb-network-setup | 0 find-serial => bin/find-serial | 0 ledscape.service => bin/ledscape.service | 0 python-test => bin/python-test | 0 run-ledscape => bin/run-ledscape | 0 {pcb => brackets}/flat-bracket.scad | 0 {pcb => brackets}/flat-bracket.svg | 0 .../matrix-bracket.scad | 0 {pcb => brackets}/octoscroller.scad | 0 checkerboard | 48 -- LEDscape.dts => dts/LEDscape.dts | 0 cape-bone-octo.dts => dts/cape-bone-octo.dts | 0 .../pf_tempesta_seven.ttf | Bin spincycle.ttf => fonts/spincycle.ttf | Bin rainbow | 42 -- rgb-test.c | 90 ---- .../demos/companion-cube.raw | Bin cube-image.c => src/demos/cube-image.c | 0 cube-life.c => src/demos/cube-life.c | 0 fire.c => src/demos/fire.c | 0 identify.c => src/demos/identify.c | 0 life.c => src/demos/life.c | 0 matrix-test.c => src/demos/matrix-test.c | 0 bitslice.c => src/ledscape/bitslice.c | 0 bitslice.h => src/ledscape/bitslice.h | 0 ledscape.c => src/ledscape/ledscape.c | 0 ledscape.h => src/ledscape/ledscape.h | 0 util.c => src/ledscape/util.c | 0 util.h => src/ledscape/util.h | 0 mta-font.c => src/mta/mta-font.c | 0 mta-sign.c => src/mta/mta-sign.c | 0 matrix-udp-rx.c => src/net/matrix-udp-rx.c | 0 opc-rx.c => src/net/opc-rx.c | 0 udp-rx.c => src/net/udp-rx.c | 0 matrix.p => src/pru/matrix.p | 0 pru.c => src/pru/pru.c | 0 pru.h => src/pru/pru.h | 0 ws281x.hp => src/pru/ws281x.hp | 0 ws281x.p => src/pru/ws281x.p | 0 teensy-udp-rx.c | 461 ------------------ test-bitslice.c | 39 -- 46 files changed, 1043 deletions(-) delete mode 100644 VideoDisplay/VideoDisplay.ino delete mode 100644 VideoDisplay/mac.cpp delete mode 100644 VideoDisplay/mac.h delete mode 100644 bad-pattern.c delete mode 100644 bad-pattern.txt rename bbb-network-setup => bin/bbb-network-setup (100%) rename find-serial => bin/find-serial (100%) rename ledscape.service => bin/ledscape.service (100%) rename python-test => bin/python-test (100%) rename run-ledscape => bin/run-ledscape (100%) rename {pcb => brackets}/flat-bracket.scad (100%) rename {pcb => brackets}/flat-bracket.svg (100%) rename matrix-bracket.scad => brackets/matrix-bracket.scad (100%) rename {pcb => brackets}/octoscroller.scad (100%) delete mode 100755 checkerboard rename LEDscape.dts => dts/LEDscape.dts (100%) rename cape-bone-octo.dts => dts/cape-bone-octo.dts (100%) rename pf_tempesta_seven.ttf => fonts/pf_tempesta_seven.ttf (100%) rename spincycle.ttf => fonts/spincycle.ttf (100%) delete mode 100755 rainbow delete mode 100644 rgb-test.c rename companion-cube.raw => src/demos/companion-cube.raw (100%) rename cube-image.c => src/demos/cube-image.c (100%) rename cube-life.c => src/demos/cube-life.c (100%) rename fire.c => src/demos/fire.c (100%) rename identify.c => src/demos/identify.c (100%) rename life.c => src/demos/life.c (100%) rename matrix-test.c => src/demos/matrix-test.c (100%) rename bitslice.c => src/ledscape/bitslice.c (100%) rename bitslice.h => src/ledscape/bitslice.h (100%) rename ledscape.c => src/ledscape/ledscape.c (100%) rename ledscape.h => src/ledscape/ledscape.h (100%) rename util.c => src/ledscape/util.c (100%) rename util.h => src/ledscape/util.h (100%) rename mta-font.c => src/mta/mta-font.c (100%) rename mta-sign.c => src/mta/mta-sign.c (100%) rename matrix-udp-rx.c => src/net/matrix-udp-rx.c (100%) rename opc-rx.c => src/net/opc-rx.c (100%) rename udp-rx.c => src/net/udp-rx.c (100%) rename matrix.p => src/pru/matrix.p (100%) rename pru.c => src/pru/pru.c (100%) rename pru.h => src/pru/pru.h (100%) rename ws281x.hp => src/pru/ws281x.hp (100%) rename ws281x.p => src/pru/ws281x.p (100%) delete mode 100644 teensy-udp-rx.c delete mode 100644 test-bitslice.c diff --git a/VideoDisplay/VideoDisplay.ino b/VideoDisplay/VideoDisplay.ino deleted file mode 100644 index b56e4255..00000000 --- a/VideoDisplay/VideoDisplay.ino +++ /dev/null @@ -1,259 +0,0 @@ -/* OctoWS2811 VideoDisplay.ino - Video on LEDs, from a PC, Mac, Raspberry Pi - http://www.pjrc.com/teensy/td_libs_OctoWS2811.html - Copyright (c) 2013 Paul Stoffregen, PJRC.COM, LLC - - Updated by Trammell Hudson - - Teport unique Teensy serial number in response to ? command. - - Receive a data frame and wait for a ! command to display it. - - 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. - - - Required Connections - -------------------- - pin 2: LED Strip #1 OctoWS2811 drives 8 LED Strips. - pin 14: LED strip #2 All 8 are the same length. - pin 7: LED strip #3 - pin 8: LED strip #4 A 100 to 220 ohm resistor should used - pin 6: LED strip #5 between each Teensy pin and the - pin 20: LED strip #6 wire to the LED strip, to minimize - pin 21: LED strip #7 high frequency ringining & noise. - pin 5: LED strip #8 - pin 15 & 16 - Connect together, but do not use - pin 4: Do not use - pin 3: Do not use as PWM. Normal use is ok. - pin 12: Frame Sync - - When using more than 1 Teensy to display a video image, connect - the Frame Sync signal between every board. All boards will - synchronize their WS2811 update using this signal. - - Beware of image distortion from long LED strip lengths. During - the WS2811 update, the LEDs update in sequence, not all at the - same instant! The first pixel updates after 30 microseconds, - the second pixel after 60 us, and so on. A strip of 120 LEDs - updates in 3.6 ms, which is 10.8% of a 30 Hz video frame time. - Doubling the strip length to 240 LEDs increases the lag to 21.6% - of a video frame. For best results, use shorter length strips. - Multiple boards linked by the frame sync signal provides superior - video timing accuracy. - - A Multi-TT USB hub should be used if 2 or more Teensy boards - are connected. The Multi-TT feature allows proper USB bandwidth - allocation. Single-TT hubs, or direct connection to multiple - ports on the same motherboard, may give poor performance. -*/ - -#include -#include "mac.h" - -// The actual arrangement of the LEDs connected to this Teensy 3.0 board. -// LED_HEIGHT *must* be a multiple of 8. When 16, 24, 32 are used, each -// strip spans 2, 3, 4 rows. LED_LAYOUT indicates the direction the strips -// are arranged. If 0, each strip begins on the left for its first row, -// then goes right to left for its second row, then left to right, -// zig-zagging for each successive row. -// -// Since the receiving program on the host is slicing the image, -// only the width matters. The height is always 8. -// -#define LED_WIDTH 210 // number of LEDs horizontally -#define LED_HEIGHT 8 // number of LEDs vertically (must be 8) -#define LED_LAYOUT 0 // 0 = even rows left->right, 1 = even rows right->left - -// The portion of the video image to show on this set of LEDs. All 4 numbers -// are percentages, from 0 to 100. For a large LED installation with many -// Teensy 3.0 boards driving groups of LEDs, these parameters allow you to -// program each Teensy to tell the video application which portion of the -// video it displays. By reading these numbers, the video application can -// automatically configure itself, regardless of which serial port COM number -// or device names are assigned to each Teensy 3.0 by your operating system. -#define VIDEO_XOFFSET 0 // always 0 for Disorient pyramid -#define VIDEO_YOFFSET 0 // display entire image -- always 0 for Disorient pyramid -#define VIDEO_WIDTH 100 -#define VIDEO_HEIGHT 100 - -//#define VIDEO_XOFFSET 0 -//#define VIDEO_YOFFSET 0 // display upper half -//#define VIDEO_WIDTH 100 -//#define VIDEO_HEIGHT 50 - -//#define VIDEO_XOFFSET 0 -//#define VIDEO_YOFFSET 50 // display lower half -//#define VIDEO_WIDTH 100 -//#define VIDEO_HEIGHT 50 - - -const int ledsPerStrip = LED_WIDTH * LED_HEIGHT / 8; - -DMAMEM int displayMemory[ledsPerStrip*6]; -int drawingMemory[ledsPerStrip*6]; -elapsedMicros elapsedUsecSinceLastFrameSync = 0; - -const int config = WS2811_800kHz; // color config is on the PC side - -OctoWS2811 leds(ledsPerStrip, displayMemory, drawingMemory, config); - -void setup() { - pinMode(12, INPUT_PULLUP); // Frame Sync - Serial.setTimeout(50); - leds.begin(); - leds.show(); -} - -void loop() { -// -// wait for a Start-Of-Message character: -// -// '*' = Frame of image data, with frame sync pulse to be sent -// a specified number of microseconds after reception of -// the first byte (typically at 75% of the frame time, to -// allow other boards to fully receive their data). -// Normally '*' is used when the sender controls the pace -// of playback by transmitting each frame as it should -// appear. -// -// '$' = Frame of image data, with frame sync pulse to be sent -// a specified number of microseconds after the previous -// frame sync. Normally this is used when the sender -// transmits each frame as quickly as possible, and we -// control the pacing of video playback by updating the -// LEDs based on time elapsed from the previous frame. -// -// '%' = Frame of image data, to be displayed with a frame sync -// pulse is received from another board. In a multi-board -// system, the sender would normally transmit one '*' or '$' -// message and '%' messages to all other boards, so every -// Teensy 3.0 updates at the exact same moment. -// -// '@' = Reset the elapsed time, used for '$' messages. This -// should be sent before the first '$' message, so many -// frames are not played quickly if time as elapsed since -// startup or prior video playing. -// -// '?' = Query LED and Video parameters. Teensy 3.0 responds -// with a comma delimited list of information. -// -// '!' = Display the frame now. -// - int startChar = Serial.read(); - - if (startChar == '*') { - // receive a "master" frame - we send the frame sync to other boards - // the sender is controlling the video pace. The 16 bit number is - // how far into this frame to send the sync to other boards. - unsigned int startAt = micros(); - unsigned int usecUntilFrameSync = 0; - int count = Serial.readBytes((char *)&usecUntilFrameSync, 2); - if (count != 2) return; - count = Serial.readBytes((char *)drawingMemory, sizeof(drawingMemory)); - if (count == sizeof(drawingMemory)) { - unsigned int endAt = micros(); - unsigned int usToWaitBeforeSyncOutput = 100; - if (endAt - startAt < usecUntilFrameSync) { - usToWaitBeforeSyncOutput = usecUntilFrameSync - (endAt - startAt); - } - digitalWrite(12, HIGH); - pinMode(12, OUTPUT); - delayMicroseconds(usToWaitBeforeSyncOutput); - digitalWrite(12, LOW); - // WS2811 update begins immediately after falling edge of frame sync - digitalWrite(13, HIGH); - leds.show(); - digitalWrite(13, LOW); - } - - } else if (startChar == '$') { - // receive a "master" frame - we send the frame sync to other boards - // we are controlling the video pace. The 16 bit number is how long - // after the prior frame sync to wait until showing this frame - unsigned int usecUntilFrameSync = 0; - int count = Serial.readBytes((char *)&usecUntilFrameSync, 2); - if (count != 2) return; - count = Serial.readBytes((char *)drawingMemory, sizeof(drawingMemory)); - if (count == sizeof(drawingMemory)) { - digitalWrite(12, HIGH); - pinMode(12, OUTPUT); - while (elapsedUsecSinceLastFrameSync < usecUntilFrameSync) /* wait */ ; - elapsedUsecSinceLastFrameSync -= usecUntilFrameSync; - digitalWrite(12, LOW); - // WS2811 update begins immediately after falling edge of frame sync - digitalWrite(13, HIGH); - leds.show(); - digitalWrite(13, LOW); - } - - } else if (startChar == '%') { - // receive a "slave" frame - wait to show it until the frame sync arrives - pinMode(12, INPUT_PULLUP); - unsigned int unusedField = 0; - int count = Serial.readBytes((char *)&unusedField, 2); - if (count != 2) return; - count = Serial.readBytes((char *)drawingMemory, sizeof(drawingMemory)); - if (count == sizeof(drawingMemory)) { - elapsedMillis wait = 0; - while (digitalRead(12) != HIGH && wait < 30) ; // wait for sync high - while (digitalRead(12) != LOW && wait < 30) ; // wait for sync high->low - // WS2811 update begins immediately after falling edge of frame sync - if (wait < 30) { - digitalWrite(13, HIGH); - leds.show(); - digitalWrite(13, LOW); - } - } - - } else if (startChar == '@') { - // reset the elapsed frame time, for startup of '$' message playing - elapsedUsecSinceLastFrameSync = 0; - - } else if (startChar == '?') { - // when the video application asks, give it all our info - // for easy and automatic configuration - Serial.print(LED_WIDTH); - Serial.write(','); - Serial.print(LED_HEIGHT); - Serial.write(','); - Serial.print(LED_LAYOUT); - Serial.write(','); - read_mac(); - const uint16_t id = mac[4] << 8 | mac[5]; - Serial.print(id); - Serial.write(','); - Serial.print(0); - Serial.write(','); - Serial.print(VIDEO_XOFFSET); - Serial.write(','); - Serial.print(VIDEO_YOFFSET); - Serial.write(','); - Serial.print(VIDEO_WIDTH); - Serial.write(','); - Serial.print(VIDEO_HEIGHT); - Serial.write(','); - Serial.print(0); - Serial.write(','); - Serial.print(0); - Serial.write(','); - Serial.print(0); - Serial.println(); - - } else if (startChar >= 0) { - // discard unknown characters - } -} - diff --git a/VideoDisplay/mac.cpp b/VideoDisplay/mac.cpp deleted file mode 100644 index 552d612f..00000000 --- a/VideoDisplay/mac.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "mac.h" - -uint8_t mac[6]; - -// http://forum.pjrc.com/threads/91-teensy-3-MAC-address -void read(uint8_t word, uint8_t *mac, uint8_t offset) { - FTFL_FCCOB0 = 0x41; // Selects the READONCE command - FTFL_FCCOB1 = word; // read the given word of read once area - - // launch command and wait until complete - FTFL_FSTAT = FTFL_FSTAT_CCIF; - while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF)); - - *(mac+offset) = FTFL_FCCOB5; // collect only the top three bytes, - *(mac+offset+1) = FTFL_FCCOB6; // in the right orientation (big endian). - *(mac+offset+2) = FTFL_FCCOB7; // Skip FTFL_FCCOB4 as it's always 0. -} - -void read_mac() { - read(0xe,mac,0); - read(0xf,mac,3); -} - -void print_mac() { - size_t count = 0; - for(uint8_t i = 0; i < 6; ++i) { - if (i!=0) count += Serial.print(":"); - count += Serial.print((*(mac+i) & 0xF0) >> 4, 16); - count += Serial.print(*(mac+i) & 0x0F, 16); - } -} - diff --git a/VideoDisplay/mac.h b/VideoDisplay/mac.h deleted file mode 100644 index 904b841e..00000000 --- a/VideoDisplay/mac.h +++ /dev/null @@ -1,7 +0,0 @@ -#include ; - -extern uint8_t mac[6]; - -void read_mac(); -void print_mac(); - diff --git a/bad-pattern.c b/bad-pattern.c deleted file mode 100644 index dff8d975..00000000 --- a/bad-pattern.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include "util.h" - -int main(int argc, char **argv) -{ -#if 1 - const char * dev = argc > 1 ? argv[1] : "/dev/ttyACM2"; - int fd = serial_open(dev); - if (fd < 0) - die("%s: open failed\n", dev); -#endif - - static uint8_t bad_pattern[210*8*3+3] = - { - 0x2a,0x00,0x00 -#include "bad-pattern.txt" -//#include "zeros.txt" - }; - - for (size_t i = 3+24 ; i < sizeof(bad_pattern) ; i++) - bad_pattern[i] &= 0xFF; - - ssize_t rc = write_all(fd, bad_pattern, sizeof(bad_pattern)); - fprintf(stderr, "rc=%zu\n", rc); - - return 0; -} diff --git a/bad-pattern.txt b/bad-pattern.txt deleted file mode 100644 index 8ee7c787..00000000 --- a/bad-pattern.txt +++ /dev/null @@ -1,38 +0,0 @@ -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a /* Change to 0x0a to 0x02 and it is fine */ -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20 -, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 diff --git a/bbb-network-setup b/bin/bbb-network-setup similarity index 100% rename from bbb-network-setup rename to bin/bbb-network-setup diff --git a/find-serial b/bin/find-serial similarity index 100% rename from find-serial rename to bin/find-serial diff --git a/ledscape.service b/bin/ledscape.service similarity index 100% rename from ledscape.service rename to bin/ledscape.service diff --git a/python-test b/bin/python-test similarity index 100% rename from python-test rename to bin/python-test diff --git a/run-ledscape b/bin/run-ledscape similarity index 100% rename from run-ledscape rename to bin/run-ledscape diff --git a/pcb/flat-bracket.scad b/brackets/flat-bracket.scad similarity index 100% rename from pcb/flat-bracket.scad rename to brackets/flat-bracket.scad diff --git a/pcb/flat-bracket.svg b/brackets/flat-bracket.svg similarity index 100% rename from pcb/flat-bracket.svg rename to brackets/flat-bracket.svg diff --git a/matrix-bracket.scad b/brackets/matrix-bracket.scad similarity index 100% rename from matrix-bracket.scad rename to brackets/matrix-bracket.scad diff --git a/pcb/octoscroller.scad b/brackets/octoscroller.scad similarity index 100% rename from pcb/octoscroller.scad rename to brackets/octoscroller.scad diff --git a/checkerboard b/checkerboard deleted file mode 100755 index 371d25a2..00000000 --- a/checkerboard +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/perl -use warnings; -use strict; -use IO::Socket; -use Time::HiRes 'usleep'; - -# Make an RGB checkerboard -my $host = '192.168.7.2:9999'; - -my $sock = IO::Socket::INET->new( - PeerAddr => $host, - Proto => 'udp', -) or die "Socket failed: $!\n"; - - -my $width = 64; -my $height = 210; -my $offset = 0; - -my $i = 0; - -while (1) -{ - $offset++; - my $s = chr(1); - my $bright = 0x30; - - for(my $y = 0 ; $y < $height ; $y++) - { - for(my $x = 0; $x < $width ; $x++) - { - my $c = $i % 7; - my $r = ($c == 0 || $c == 2) ? $bright : 0; - my $g = ($c == 1 || $c == 2) ? $bright : 0; - my $b = 0; #($i % 7 == 2) ? $bright : 0; - - $s .= chr($r); - $s .= chr($g); - $s .= chr($b); - $i++; - } - } - - $sock->send($s); - usleep(1e6/4); - #usleep(10); - $i++; -} diff --git a/LEDscape.dts b/dts/LEDscape.dts similarity index 100% rename from LEDscape.dts rename to dts/LEDscape.dts diff --git a/cape-bone-octo.dts b/dts/cape-bone-octo.dts similarity index 100% rename from cape-bone-octo.dts rename to dts/cape-bone-octo.dts diff --git a/pf_tempesta_seven.ttf b/fonts/pf_tempesta_seven.ttf similarity index 100% rename from pf_tempesta_seven.ttf rename to fonts/pf_tempesta_seven.ttf diff --git a/spincycle.ttf b/fonts/spincycle.ttf similarity index 100% rename from spincycle.ttf rename to fonts/spincycle.ttf diff --git a/rainbow b/rainbow deleted file mode 100755 index d498ad2f..00000000 --- a/rainbow +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/perl -use warnings; -use strict; -use IO::Socket; -use Time::HiRes 'usleep'; - -# Make a smooth gradient pattern -my $host = '192.168.7.2:9999'; - -my $sock = IO::Socket::INET->new( - PeerAddr => $host, - Proto => 'udp', -) or die "Socket failed: $!\n"; - - -my $width = 64; -my $height = 210; -my $offset = 0; - -while (1) -{ - $offset++; - my $s = chr(1); - my $bright = 0x30; - - for(my $y = 0 ; $y < $height ; $y++) - { - for(my $x = 0; $x < $width ; $x++) - { - my $r = (($x + $offset) % $width) * $bright / $width; - my $g = 0; - my $b = (($height - $y - 1 + $offset) % $height) * $bright / $height; - - $s .= chr($r); - $s .= chr($g); - $s .= chr($b); - } - } - - $sock->send($s); - usleep(20000); -} diff --git a/rgb-test.c b/rgb-test.c deleted file mode 100644 index de2419de..00000000 --- a/rgb-test.c +++ /dev/null @@ -1,90 +0,0 @@ -/** \file - * Test the ledscape library by pulsing RGB on the first three LEDS. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "ledscape.h" - -static void -ledscape_fill_color( - ledscape_frame_t * const frame, - const unsigned num_pixels, - const uint8_t r, - const uint8_t g, - const uint8_t b -) -{ - for (unsigned i = 0 ; i < num_pixels ; i++) - for (unsigned strip = 0 ; strip < LEDSCAPE_NUM_STRIPS ; strip++) - ledscape_set_color(frame, strip, i, r, g, b); -} - - -int main (void) -{ - const int num_pixels = 128; - ledscape_t * const leds = ledscape_init(num_pixels); - time_t last_time = time(NULL); - unsigned last_i = 0; - - unsigned i = 0; - while (1) - { - // Alternate frame buffers on each draw command - const unsigned frame_num = i++ % 2; - ledscape_frame_t * const frame - = ledscape_frame(leds, frame_num); - - uint8_t val = i >> 1; - uint16_t r = ((i >> 0) & 0xFF); - uint16_t g = ((i >> 8) & 0xFF); - uint16_t b = ((i >> 16) & 0xFF); - ledscape_fill_color(frame, num_pixels, val, val, val); - - for (unsigned strip = 0 ; strip < 32 ; strip++) - { - for (unsigned p = 0 ; p < 64 ; p++) - { - ledscape_set_color( - frame, - strip, - p, -#if 1 - ((strip % 3) == 0) ? (i) : 0, - ((strip % 3) == 1) ? (i) : 0, - ((strip % 3) == 2) ? (i) : 0 -#else - ((strip % 3) == 0) ? 100 : 0, - ((strip % 3) == 1) ? 100 : 0, - ((strip % 3) == 2) ? 100 : 0 -#endif - ); - //ledscape_set_color(frame, strip, 3*p+1, 0, p+val + 80, 0); - //ledscape_set_color(frame, strip, 3*p+2, 0, 0, p+val + 160); - } - } - - // wait for the previous frame to finish; - const uint32_t response = ledscape_wait(leds); - time_t now = time(NULL); - if (now != last_time) - { - printf("%d fps. starting %d previous %"PRIx32"\n", - i - last_i, i, response); - last_i = i; - last_time = now; - } - - ledscape_draw(leds, frame_num); - } - - ledscape_close(leds); - - return EXIT_SUCCESS; -} diff --git a/companion-cube.raw b/src/demos/companion-cube.raw similarity index 100% rename from companion-cube.raw rename to src/demos/companion-cube.raw diff --git a/cube-image.c b/src/demos/cube-image.c similarity index 100% rename from cube-image.c rename to src/demos/cube-image.c diff --git a/cube-life.c b/src/demos/cube-life.c similarity index 100% rename from cube-life.c rename to src/demos/cube-life.c diff --git a/fire.c b/src/demos/fire.c similarity index 100% rename from fire.c rename to src/demos/fire.c diff --git a/identify.c b/src/demos/identify.c similarity index 100% rename from identify.c rename to src/demos/identify.c diff --git a/life.c b/src/demos/life.c similarity index 100% rename from life.c rename to src/demos/life.c diff --git a/matrix-test.c b/src/demos/matrix-test.c similarity index 100% rename from matrix-test.c rename to src/demos/matrix-test.c diff --git a/bitslice.c b/src/ledscape/bitslice.c similarity index 100% rename from bitslice.c rename to src/ledscape/bitslice.c diff --git a/bitslice.h b/src/ledscape/bitslice.h similarity index 100% rename from bitslice.h rename to src/ledscape/bitslice.h diff --git a/ledscape.c b/src/ledscape/ledscape.c similarity index 100% rename from ledscape.c rename to src/ledscape/ledscape.c diff --git a/ledscape.h b/src/ledscape/ledscape.h similarity index 100% rename from ledscape.h rename to src/ledscape/ledscape.h diff --git a/util.c b/src/ledscape/util.c similarity index 100% rename from util.c rename to src/ledscape/util.c diff --git a/util.h b/src/ledscape/util.h similarity index 100% rename from util.h rename to src/ledscape/util.h diff --git a/mta-font.c b/src/mta/mta-font.c similarity index 100% rename from mta-font.c rename to src/mta/mta-font.c diff --git a/mta-sign.c b/src/mta/mta-sign.c similarity index 100% rename from mta-sign.c rename to src/mta/mta-sign.c diff --git a/matrix-udp-rx.c b/src/net/matrix-udp-rx.c similarity index 100% rename from matrix-udp-rx.c rename to src/net/matrix-udp-rx.c diff --git a/opc-rx.c b/src/net/opc-rx.c similarity index 100% rename from opc-rx.c rename to src/net/opc-rx.c diff --git a/udp-rx.c b/src/net/udp-rx.c similarity index 100% rename from udp-rx.c rename to src/net/udp-rx.c diff --git a/matrix.p b/src/pru/matrix.p similarity index 100% rename from matrix.p rename to src/pru/matrix.p diff --git a/pru.c b/src/pru/pru.c similarity index 100% rename from pru.c rename to src/pru/pru.c diff --git a/pru.h b/src/pru/pru.h similarity index 100% rename from pru.h rename to src/pru/pru.h diff --git a/ws281x.hp b/src/pru/ws281x.hp similarity index 100% rename from ws281x.hp rename to src/pru/ws281x.hp diff --git a/ws281x.p b/src/pru/ws281x.p similarity index 100% rename from ws281x.p rename to src/pru/ws281x.p diff --git a/teensy-udp-rx.c b/teensy-udp-rx.c deleted file mode 100644 index 9f6f34df..00000000 --- a/teensy-udp-rx.c +++ /dev/null @@ -1,461 +0,0 @@ -/** \file - * UDP image packet receiver. - * - * Based on the HackRockCity LED Display code: - * https://github.com/agwn/pyramidTransmitter/blob/master/LEDDisplay.pde - * - * Designed to clock data out to USB teensy3 serial devices, which require - * bitslicing into the raw form for the OctoWS2811 firmware. - * - * Since the teensy devices might come and go, this allows them to go into - * a disconnected state and will attempt to reconnect when the device port - * re-appears. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "util.h" -#include "bitslice.h" - -static int port = 9999; -static unsigned width = 64; -static unsigned height = 210; - -static int -udp_socket( - const int port -) -{ - const int sock = socket(AF_INET, SOCK_DGRAM, 0); - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_port = htons(port), - .sin_addr.s_addr = INADDR_ANY, - }; - - if (sock < 0) - return -1; - if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr)) < 0) - return -1; - - return sock; -} - - -typedef struct -{ - const char * dev; - int fd; - unsigned id; - int warned; -} teensy_dev_t; - -#define MAX_STRIPS 32 -#define MAX_PIXELS 256 - -typedef struct -{ - unsigned id; - unsigned x_offset; - teensy_dev_t * dev; - uint8_t bad[MAX_PIXELS]; // which pixels are to be masked out -} teensy_strip_t; - -// \todo read this from a file at run time -static teensy_strip_t strips[MAX_STRIPS]; -static unsigned num_strips; - - -static teensy_dev_t teensy_devs[] = { - { .dev = "/dev/ttyACM0", .fd = -1 }, - { .dev = "/dev/ttyACM1", .fd = -1 }, - { .dev = "/dev/ttyACM2", .fd = -1 }, - { .dev = "/dev/ttyACM3", .fd = -1 }, - { .dev = "/dev/ttyACM4", .fd = -1 }, - { .dev = "/dev/ttyACM5", .fd = -1 }, - { .dev = "/dev/ttyACM6", .fd = -1 }, - { .dev = "/dev/ttyACM7", .fd = -1 }, -}; - - -static const unsigned num_devs = sizeof(teensy_devs) / sizeof(*teensy_devs); - - -static teensy_strip_t * -strip_find( - teensy_dev_t * const dev -) -{ - // Look through our table to find where this one goes - for (unsigned j = 0 ; j < num_strips ; j++) - { - teensy_strip_t * const leds = &strips[j]; - if (leds->id != dev->id) - continue; - - if (leds->dev != NULL) - { - fprintf(stderr, "FATAL: %s: Duplicate ID %u (%s)\n", - dev->dev, dev->id, leds->dev->dev); - return NULL; - } - - leds->dev = dev; - return leds; - } - - fprintf(stderr, "FATAL: %s: Unknown ID %u\n", dev->dev, dev->id); - return NULL; -} - - -static void -strip_close( - teensy_strip_t * const strip -) -{ - teensy_dev_t * const dev = strip->dev; - if (!dev) - return; - - if (dev->fd >= 0) - close(dev->fd); - - dev->fd = -1; - dev->id = 0; - strip->dev = NULL; -} - - -static int -teensy_open( - teensy_dev_t * const dev -) -{ - dev->fd = serial_open(dev->dev); - if (dev->fd < 0) - { - if (errno == ENOENT) - return 0; - - warn("%s: Unable to open serial port: %s\n", - dev->dev, - strerror(errno) - ); - - // Something else went wrong - goto fail; - } - - // Find out the serial number of this teensy - ssize_t rc; - rc = write_all(dev->fd, "?", 1); - if (rc < 0) - { - if (!dev->warned) - warn("%s: write failed: %s\n", dev->dev, strerror(errno)); - dev->warned = 1; - goto fail; - } - - dev->warned = 0; - - // \todo: Read until a newline or a timeout - usleep(10000); - char response[128]; - rc = read(dev->fd, response, sizeof(response)-1); - if (rc < 0) - { - warn("%s: read failed: %s\n", dev->dev, strerror(errno)); - goto fail; - } - - response[rc] = '\0'; - if (0) printf("read: '%s'\n", response); - - unsigned this_height; - if (sscanf(response, "%d,%*d,%*d,%d", &this_height, &dev->id) != 2) - { - warn("%s: Unable to parse response: '%s'\n", dev->dev, response); - goto fail; - } - - printf("%s: ID %d height %d\n", dev->dev, dev->id, this_height); - - if (dev->id == 0) - { - warn("%s: dev id == 0. NOT GOOD\n", dev->dev); - goto fail; - } - - if (this_height != height) - { - warn("%s: height %d != expected %d\n", dev->dev, this_height, height); - goto fail; - } - - teensy_strip_t * const leds = strip_find(dev); - if (!leds) - goto fail; - - return 1; - -fail: - dev->id = 0; - if (dev->fd >= 0) - close(dev->fd); - return -1; -} - - -static void * -reopen_thread( - void * const arg -) -{ - (void) arg; - - while (1) - { - for (unsigned i = 0 ; i < num_devs ; i++) - { - teensy_dev_t * const dev = &teensy_devs[i]; - if (dev->id != 0) - continue; - teensy_open(dev); - } - - sleep(1); - } - - return NULL; -} - - -/** Config file format; - * - */ -static void -read_config( - const char * const config_file -) -{ - FILE * const f = fopen(config_file, "r"); - if (!f) - die("%s: Unable to open: %s\n", config_file, strerror(errno)); - - char line[1024]; - - if (fgets(line, sizeof(line), f) == NULL) - die("%s: Unable to read port num\n", config_file); - - port = atoi(line); - - if (fgets(line, sizeof(line), f) == NULL) - die("%s: Unable to read dimenstions\n", config_file); - - if (sscanf(line, "%u,%u\n", &width, &height) != 2) - die("%s: Parse error on image width or port\n", config_file); - - unsigned line_num = 2; - - for (num_strips = 0 ; num_strips < MAX_STRIPS ; num_strips++, line_num++) - { - if (fgets(line, sizeof(line), f) == NULL) - break; - - teensy_strip_t * const strip = &strips[num_strips]; - int offset = 0; - int rc = sscanf(line, "%u,%u%n", - &strip->id, - &strip->x_offset, - &offset - ); - - if (rc != 2) - die("%s:%d: unable to parse rc=%d\n", config_file, line_num, rc); - - char * s = line + offset; - if (*s == ',') - s++; - - do { - char * eol = strchr(s, ','); - if (eol) - *eol++ = '\0'; - if (*s == '\0' || *s == '\n') - break; - - unsigned bad_strip; - unsigned bad_pixel; - - if (sscanf(s, "%u:%u", &bad_strip, &bad_pixel) != 2) - die("%s:%d: unable to parse bad pixels '%s'\n", config_file, line_num, s); - - if (bad_strip >= MAX_STRIPS) - die("%s:%d: bad bad strip %u\n", config_file, line_num, bad_strip); - if (bad_pixel >= MAX_PIXELS) - die("%s:%d: bad bad pixel %u\n", config_file, line_num, bad_pixel); - strip->bad[bad_pixel] |= 1 << bad_strip; - s = eol; - printf("%u: bad %u:%u\n", strip->id, bad_strip, bad_pixel); - } while (s); - } - -} - - -int -main( - int argc, - char ** argv -) -{ - if (argc != 2) - die("Require config file path\n"); - read_config(argv[1]); - - const int sock = udp_socket(port); - if (sock < 0) - die("socket port %d failed: %s\n", port, strerror(errno)); - - pthread_t reopen_tid; - if (pthread_create(&reopen_tid, NULL, reopen_thread, NULL) < 0) - die("pthread create failed: %s\n", strerror(errno)); - - const size_t image_size = width * height * 3; - const size_t slice_size = height * 8 * 3 + 3; - uint8_t * const slice = calloc(1, slice_size); - - // largest possible UDP packet - uint8_t buf[65536]; - if (sizeof(buf) < image_size + 1) - die("%u x %u too large for UDP\n", width, height); - - fprintf(stderr, "%u x %u, UDP port %u\n", width, height, port); - - const unsigned report_interval = 10; - unsigned last_report = 0; - unsigned long delta_sum = 0; - unsigned frames = 0; - - while (1) - { - const ssize_t rlen = recv(sock, buf, sizeof(buf), 0); - if (rlen < 0) - die("recv failed: %s\n", strerror(errno)); - warn_once("received %zu bytes\n", rlen); - - if (buf[0] == 2) - { - // image type - printf("image type: %.*s\n", - (int) rlen - 1, - &buf[1] - ); - continue; - } - - if (buf[0] != 1) - { - // What is it? - warn_once("Unknown image type '%c' (%02x)\n", - buf[0], - buf[0] - ); - continue; - } - - if ((size_t) rlen != image_size + 1) - { - warn_once("WARNING: Received packet %zu bytes, expected %zu\n", - rlen, - image_size + 1 - ); - } - - // Header for the frame to the teensy indicating that it - // is to be drawn immediately. - slice[0] = '*'; - slice[1] = 0; - slice[2] = 1; - - struct timeval start_tv, stop_tv, delta_tv; - gettimeofday(&start_tv, NULL); - - // Translate the image from packed RGB into sliced 24-bit - // for each teensy. - for (unsigned i = 0 ; i < num_strips ; i++) - { - teensy_strip_t * const strip = &strips[i]; - teensy_dev_t * const dev = strip->dev; - - // If it hasn't been opened yet, go onto the next one - if (!dev) - continue; - - bitslice( - slice + 3, - strip->bad, - buf + 1, - width, - height, - strip->x_offset - ); - - const ssize_t rc - = write_all(dev->fd, slice, slice_size); - - if ((size_t) rc == slice_size) - continue; - - if (rc < 0) - warn("%s: write failed: %s\n", - dev->dev, - strerror(errno) - ); - else - warn("%s: short write %zu != %zu: %s\n", - dev->dev, - rc, - slice_size, - strerror(errno) - ); - - strip_close(strip); - } - - gettimeofday(&stop_tv, NULL); - timersub(&stop_tv, &start_tv, &delta_tv); - - frames++; - delta_sum += delta_tv.tv_usec; - if (stop_tv.tv_sec - last_report < report_interval) - continue; - last_report = stop_tv.tv_sec; - - const unsigned delta_avg = delta_sum / frames; - printf("%6u usec avg, max %.2f fps, actual %.2f fps (over %u frames)\n", - delta_avg, - report_interval * 1.0e6 / delta_avg, - frames * 1.0 / report_interval, - frames - ); - - frames = delta_sum = 0; - } - - return 0; -} diff --git a/test-bitslice.c b/test-bitslice.c deleted file mode 100644 index 8b348555..00000000 --- a/test-bitslice.c +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include "bitslice.h" -#include "util.h" - -int main(void) -{ - uint8_t bitmap[2][9][3] = { - { - { 0x03, 0x03, 0x03 }, - { 0x00, 0x00, 0x00 }, - { 0x03, 0x03, 0x03 }, - { 0x00, 0x00, 0x00 }, - { 0x03, 0x03, 0x03 }, - { 0x00, 0x00, 0x00 }, - { 0x03, 0x03, 0x03 }, - { 0x00, 0x00, 0x00 }, - { 0x03, 0x03, 0x03 }, - }, - { - { 0x00, 0x00, 0x00 }, - { 0x03, 0x03, 0x03 }, - { 0x01, 0x02, 0x04 }, - { 0xF2, 0xF4, 0xF8 }, - { 0x04, 0x08, 0x10 }, - { 0xF8, 0xF0, 0x22 }, - { 0x10, 0x20, 0x40 }, - { 0xF1, 0x4F, 0x8F }, - { 0x02, 0x80, 0x00 }, - }, - }; - - hexdump(stdout, bitmap, sizeof(bitmap)); - - uint8_t out[1024]; - - bitslice(out, NULL, (const uint8_t*) bitmap, 9, 2, 1); - - hexdump(stdout, out, 8 * 2 * 3); -} From 543ceda7522cda808c7f31b39b459cf3af42ce09 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 Apr 2014 18:50:08 +0000 Subject: [PATCH 227/332] makefiles that sort of work --- Makefile | 151 +++----------------------------- Makefile.common | 150 +++++++++++++++++++++++++++++++ src/demos/Makefile | 16 ++++ src/ledscape/Makefile | 18 ++++ src/ledscape/ledscape.c | 4 +- src/{pru => ledscape}/matrix.p | 0 src/{pru => ledscape}/pru.c | 0 src/{pru => ledscape}/pru.h | 0 src/{pru => ledscape}/ws281x.hp | 0 src/{pru => ledscape}/ws281x.p | 0 10 files changed, 200 insertions(+), 139 deletions(-) create mode 100644 Makefile.common create mode 100755 src/demos/Makefile create mode 100755 src/ledscape/Makefile rename src/{pru => ledscape}/matrix.p (100%) rename src/{pru => ledscape}/pru.c (100%) rename src/{pru => ledscape}/pru.h (100%) rename src/{pru => ledscape}/ws281x.hp (100%) rename src/{pru => ledscape}/ws281x.p (100%) diff --git a/Makefile b/Makefile index 0ea30e2a..1ed7ea4b 100755 --- a/Makefile +++ b/Makefile @@ -1,144 +1,21 @@ ######### # -# The top level targets link in the two .o files for now. -# -TARGETS += teensy-udp-rx -TARGETS += matrix-test -TARGETS += fire -TARGETS += matrix-udp-rx -TARGETS += opc-rx -TARGETS += life -TARGETS += cube-life -TARGETS += cube-image -TARGETS += mta-sign -TARGETS += identify - -LEDSCAPE_OBJS = ledscape.o pru.o bitslice.o util.o -LEDSCAPE_LIB := libledscape.a - -all: $(TARGETS) ws281x.bin matrix.bin - - -ifeq ($(shell uname -m),armv7l) -# We are on the BeagleBone Black itself; -# do not cross compile. -export CROSS_COMPILE:= -else -# We are not on the BeagleBone and might be cross compiling. -# If the environment does not set CROSS_COMPILE, set our -# own. Install a cross compiler with something like: -# -# sudo apt-get install gcc-arm-linux-gnueabi -# -export CROSS_COMPILE?=arm-linux-gnueabi- -endif - -CFLAGS += \ - -std=c99 \ - -W \ - -Wall \ - -D_BSD_SOURCE \ - -Wp,-MMD,$(dir $@).$(notdir $@).d \ - -Wp,-MT,$@ \ - -I. \ - -O2 \ - -mtune=cortex-a8 \ - -march=armv7-a \ - -LDFLAGS += \ - -LDLIBS += \ - -lpthread \ - -COMPILE.o = $(CROSS_COMPILE)gcc $(CFLAGS) -c -o $@ $< -COMPILE.a = $(CROSS_COMPILE)gcc -c -o $@ $< -COMPILE.link = $(CROSS_COMPILE)gcc $(LDFLAGS) -o $@ $^ $(LDLIBS) - - -##### -# -# The TI "app_loader" is the userspace library for talking to -# the PRU and mapping memory between it and the ARM. -# -APP_LOADER_DIR ?= ./am335x/app_loader -APP_LOADER_LIB := $(APP_LOADER_DIR)/lib/libprussdrv.a -CFLAGS += -I$(APP_LOADER_DIR)/include -LDLIBS += $(APP_LOADER_LIB) - -##### -# -# The TI PRU assembler looks like it has macros and includes, -# but it really doesn't. So instead we use cpp to pre-process the -# file and then strip out all of the directives that it adds. -# PASM also doesn't handle multiple statements per line, so we -# insert hard newline characters for every ; in the file. -# -PASM_DIR ?= ./am335x/pasm -PASM := $(PASM_DIR)/pasm - -%.bin: %.p $(PASM) - $(CPP) - < $< | perl -p -e 's/^#.*//; s/;/\n/g; s/BYTE\((\d+)\)/t\1/g' > $<.i - $(PASM) -V3 -b $<.i $(basename $@) - $(RM) $<.i - -%.o: %.c - $(COMPILE.o) +# Top level Makefile. +# Mostly just recurse into subdirectories. -$(foreach O,$(TARGETS),$(eval $O: $O.o $(LEDSCAPE_OBJS) $(APP_LOADER_LIB))) +SUBDIR-y += src/ledscape +SUBDIR-y += src/demos +SUBDIR-y += src/mta +SUBDIR-y += src/net +SUBDIR-y += am335x -$(TARGETS): - $(COMPILE.link) - - -.PHONY: clean +all: + for dir in $(SUBDIR-y); do \ + $(MAKE) -C $$dir; \ + done clean: - rm -rf \ - *.o \ - *.i \ - .*.o.d \ - *~ \ - $(INCDIR_APP_LOADER)/*~ \ - $(TARGETS) \ - ws281x.bin \ - - -########### -# -# The correct way to reserve the GPIO pins on the BBB is with the -# capemgr and a Device Tree file. But it doesn't work. -# -SLOT_FILE=/sys/devices/bone_capemgr.9/slots -DTS=CAPE-BONE-OCTO -DTB=/lib/firmware/$(DTS)-00A0.dtbo - -dts: LEDscape.dts - @SLOT="`grep LEDSCAPE $(SLOT_FILE) | cut -d: -f1`"; \ - if [ ! -z "$$SLOT" ]; then \ - echo "Removing slot $$SLOT"; \ - echo -$$SLOT > $(SLOT_FILE); \ - fi - dtc -O dtb -o /lib/firmware/BB-LEDSCAPE-00A0.dtbo -b 0 -@ LEDscape.dts - echo BB-LEDSCAPE > $(SLOT_FILE) - - - -firmware: $(DTB) - echo $(DTS) > $(SLOT_FILE) - -$(DTB): cape-bone-octo.dts FORCE - dtc -O dtb -o $@ -b 0 -@ $< -FORCE: - -########### -# -# PRU Libraries and PRU assembler are build from their own trees. -# -$(APP_LOADER_LIB): - $(MAKE) -C $(APP_LOADER_DIR)/interface - -$(PASM): - $(MAKE) -C $(PASM_DIR) + for dir in $(SUBDIR-y); do \ + $(MAKE) -C $$dir clean; \ + done -# Include all of the generated dependency files --include .*.o.d diff --git a/Makefile.common b/Makefile.common new file mode 100644 index 00000000..012410a9 --- /dev/null +++ b/Makefile.common @@ -0,0 +1,150 @@ +######### +# +# Common build targets +# +# + +TOP ?= ../.. +OBJDIR ?= $(TOP)/obj +LIBDIR ?= $(TOP)/lib +BINDIR ?= $(TOP)/bin + +all: $(TARGETS-y) + +ifeq ($(shell uname -m),armv7l) +# We are on the BeagleBone Black itself; +# do not cross compile. +export CROSS_COMPILE:= + +else +# We are not on the BeagleBone and might be cross compiling. +# If the environment does not set CROSS_COMPILE, set our +# own. Install a cross compiler with something like: +# +# sudo apt-get install gcc-arm-linux-gnueabi +# +export CROSS_COMPILE?=arm-linux-gnueabi- +endif + +CFLAGS += \ + -std=c99 \ + -W \ + -Wall \ + -D_BSD_SOURCE \ + -Wp,-MMD,$(dir $@).$(notdir $@).d \ + -Wp,-MT,$@ \ + -I. \ + -I$(TOP)/src/ledscape \ + -O2 \ + -mtune=cortex-a8 \ + -march=armv7-a \ + +LDFLAGS += \ + +LDLIBS += \ + -L$(LIBDIR) \ + -lledscape \ + -lpthread \ + -lm \ + +COMPILE.o = $(CROSS_COMPILE)gcc $(CFLAGS) -c -o $@ $< +COMPILE.a = $(CROSS_COMPILE)ar crv $@ $^ +COMPILE.link = $(CROSS_COMPILE)gcc $(LDFLAGS) -o $@ $^ $(LDLIBS) + +$(OBJDIR)/%.o: %.c + $(COMPILE.o) + +$(LIBDIR)/%.a: + $(RM) $@ + $(COMPILE.a) + +$(BINDIR)/%: + $(COMPILE.link) + + +##### +# +# The TI "app_loader" is the userspace library for talking to +# the PRU and mapping memory between it and the ARM. +# +APP_LOADER_DIR ?= $(TOP)/am335x/app_loader +APP_LOADER_LIB := $(APP_LOADER_DIR)/lib/libprussdrv.a +CFLAGS += -I$(APP_LOADER_DIR)/include +LDLIBS += $(APP_LOADER_LIB) + + +##### +# +# The TI PRU assembler looks like it has macros and includes, +# but it really doesn't. So instead we use cpp to pre-process the +# file and then strip out all of the directives that it adds. +# PASM also doesn't handle multiple statements per line, so we +# insert hard newline characters for every ; in the file. +# +PASM_DIR ?= $(TOP)/am335x/pasm +PASM := $(PASM_DIR)/pasm + +$(LIBDIR)/%.bin: %.p $(PASM) + $(CPP) - < $< | perl -p -e 's/^#.*//; s/;/\n/g; s/BYTE\((\d+)\)/t\1/g' > /tmp/$(basename $<).i + $(PASM) -V3 -b /tmp/$(basename $<).i $(basename $@) + $(RM) /tmp/$(basename $<).i + +#$(foreach O,$(TARGETS),$(eval $O: $O.o $(LEDSCAPE_OBJS) $(APP_LOADER_LIB))) + +#$(TARGETS): + #$(COMPILE.link) + + +.PHONY: clean + +# Include all of the generated dependency files +-include .*.o.d + +clean: + rm -rf \ + *.o \ + *.i \ + .*.o.d \ + *~ \ + $(INCDIR_APP_LOADER)/*~ \ + $(TARGETS) \ + *.bin \ + + +########### +# +# The correct way to reserve the GPIO pins on the BBB is with the +# capemgr and a Device Tree file. But it doesn't work. +# +SLOT_FILE=/sys/devices/bone_capemgr.9/slots +DTS=CAPE-BONE-OCTO +DTB=/lib/firmware/$(DTS)-00A0.dtbo + +dts: LEDscape.dts + @SLOT="`grep LEDSCAPE $(SLOT_FILE) | cut -d: -f1`"; \ + if [ ! -z "$$SLOT" ]; then \ + echo "Removing slot $$SLOT"; \ + echo -$$SLOT > $(SLOT_FILE); \ + fi + dtc -O dtb -o /lib/firmware/BB-LEDSCAPE-00A0.dtbo -b 0 -@ LEDscape.dts + echo BB-LEDSCAPE > $(SLOT_FILE) + + + +firmware: $(DTB) + echo $(DTS) > $(SLOT_FILE) + +$(DTB): cape-bone-octo.dts FORCE + dtc -O dtb -o $@ -b 0 -@ $< +FORCE: + +########### +# +# PRU Libraries and PRU assembler are build from their own trees. +# +$(APP_LOADER_LIB): + $(MAKE) -C $(APP_LOADER_DIR)/interface + +$(PASM): + $(MAKE) -C $(PASM_DIR) + diff --git a/src/demos/Makefile b/src/demos/Makefile new file mode 100755 index 00000000..0f1b0f80 --- /dev/null +++ b/src/demos/Makefile @@ -0,0 +1,16 @@ +######### +# +# Build the various demos +# +# +TARGETS-y += $(BINDIR)/fire +TARGETS-y += $(BINDIR)/matrix-test +TARGETS-y += $(BINDIR)/life +TARGETS-y += $(BINDIR)/cube-life + +include ../../Makefile.common + +$(BINDIR)/fire: $(OBJDIR)/fire.o +$(BINDIR)/matrix-test: $(OBJDIR)/matrix-test.o +$(BINDIR)/life: $(OBJDIR)/life.o +$(BINDIR)/cube-life: $(OBJDIR)/cube-life.o diff --git a/src/ledscape/Makefile b/src/ledscape/Makefile new file mode 100755 index 00000000..d2ecd636 --- /dev/null +++ b/src/ledscape/Makefile @@ -0,0 +1,18 @@ +######### +# +# Build the PRU and LEDscape libraries as well as the PRU firmware. +# +# +TARGETS-y += $(LIBDIR)/libledscape.a +TARGETS-y += $(LIBDIR)/matrix.bin +TARGETS-y += $(LIBDIR)/ws281x.bin + +include ../../Makefile.common + +$(LIBDIR)/libledscape.a: \ + $(OBJDIR)/ledscape.o \ + $(OBJDIR)/pru.o \ + $(OBJDIR)/bitslice.o \ + $(OBJDIR)/util.o \ + + diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index 5103d54c..bad5178e 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -354,9 +354,9 @@ ledscape_init( // Initiate the PRU program #ifdef CONFIG_LED_MATRIX - pru_exec(pru, "./matrix.bin"); + pru_exec(pru, "./lib/matrix.bin"); #else - pru_exec(pru, "./ws281x.bin"); + pru_exec(pru, "./lib/ws281x.bin"); #endif // Watch for a done response that indicates a proper startup diff --git a/src/pru/matrix.p b/src/ledscape/matrix.p similarity index 100% rename from src/pru/matrix.p rename to src/ledscape/matrix.p diff --git a/src/pru/pru.c b/src/ledscape/pru.c similarity index 100% rename from src/pru/pru.c rename to src/ledscape/pru.c diff --git a/src/pru/pru.h b/src/ledscape/pru.h similarity index 100% rename from src/pru/pru.h rename to src/ledscape/pru.h diff --git a/src/pru/ws281x.hp b/src/ledscape/ws281x.hp similarity index 100% rename from src/pru/ws281x.hp rename to src/ledscape/ws281x.hp diff --git a/src/pru/ws281x.p b/src/ledscape/ws281x.p similarity index 100% rename from src/pru/ws281x.p rename to src/ledscape/ws281x.p From 66a53298378bdb93a1eabf5e7e3cc66e17e23728 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 Apr 2014 19:07:56 +0000 Subject: [PATCH 228/332] makefiles for each subdir, easier targets --- src/mta/Makefile | 12 ++++++++++++ src/net/Makefile | 15 +++++++++++++++ 2 files changed, 27 insertions(+) create mode 100755 src/mta/Makefile create mode 100755 src/net/Makefile diff --git a/src/mta/Makefile b/src/mta/Makefile new file mode 100755 index 00000000..09cae2c8 --- /dev/null +++ b/src/mta/Makefile @@ -0,0 +1,12 @@ +######### +# +# Build the MTA sign demo +# +# +BIN-y += mta-sign + +mta-sign.srcs += mta-sign.c +mta-sign.srcs += mta-font.c + +include ../../Makefile.common + diff --git a/src/net/Makefile b/src/net/Makefile new file mode 100755 index 00000000..ef217bdb --- /dev/null +++ b/src/net/Makefile @@ -0,0 +1,15 @@ +######### +# +# Build the various network receiving tools +# +# +BIN-y += matrix-udp-rx +BIN-y += opc-rx +BIN-n += udp-rx + +matrix-udp-rx.srcs += matrix-udp-rx.c +opc-rx.srcs += opc-rx.c +udp-rx.srcs += udp-rx.c + +include ../../Makefile.common + From 3d5c5df71937908c6ece5e31fc6f60a3569aa10e Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 Apr 2014 19:28:51 +0000 Subject: [PATCH 229/332] makefile tweaks; things mostly work again --- Makefile | 1 - Makefile.common | 25 ++++++++++++++++--------- src/demos/Makefile | 17 +++++++++-------- src/ledscape/Makefile | 15 ++++++++------- src/mta/mta-font.c | 2 ++ src/mta/mta-sign.c | 2 +- 6 files changed, 36 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 1ed7ea4b..44465096 100755 --- a/Makefile +++ b/Makefile @@ -7,7 +7,6 @@ SUBDIR-y += src/ledscape SUBDIR-y += src/demos SUBDIR-y += src/mta SUBDIR-y += src/net -SUBDIR-y += am335x all: for dir in $(SUBDIR-y); do \ diff --git a/Makefile.common b/Makefile.common index 012410a9..1934d667 100644 --- a/Makefile.common +++ b/Makefile.common @@ -9,7 +9,10 @@ OBJDIR ?= $(TOP)/obj LIBDIR ?= $(TOP)/lib BINDIR ?= $(TOP)/bin -all: $(TARGETS-y) +all: \ + $(TARGETS-y) \ + $(foreach O,$(BIN-y),$(BINDIR)/$O) \ + $(foreach O,$(LIB-y),$(LIBDIR)/$O) \ ifeq ($(shell uname -m),armv7l) # We are on the BeagleBone Black itself; @@ -89,7 +92,14 @@ $(LIBDIR)/%.bin: %.p $(PASM) $(PASM) -V3 -b /tmp/$(basename $<).i $(basename $@) $(RM) /tmp/$(basename $<).i -#$(foreach O,$(TARGETS),$(eval $O: $O.o $(LEDSCAPE_OBJS) $(APP_LOADER_LIB))) +# +# Generate a target for each of the binaries, with dependencies on +# object files for that source. +# +$(foreach O,$(BIN-y),\ + $(eval $(BINDIR)/$O: $(foreach s,$($O.srcs),$(OBJDIR)/$(basename $s).o))) +$(foreach O,$(LIB-y),\ + $(eval $(LIBDIR)/$O: $(foreach s,$($(basename $O).srcs),$(OBJDIR)/$(basename $s).o))) #$(TARGETS): #$(COMPILE.link) @@ -102,13 +112,10 @@ $(LIBDIR)/%.bin: %.p $(PASM) clean: rm -rf \ - *.o \ - *.i \ - .*.o.d \ - *~ \ - $(INCDIR_APP_LOADER)/*~ \ - $(TARGETS) \ - *.bin \ + $(OBJDIR)/*.o \ + $(LIBDIR)/*.a \ + $(OBJDIR)/.*.o.d \ + $(LIBDIR)/*.bin \ ########### diff --git a/src/demos/Makefile b/src/demos/Makefile index 0f1b0f80..b0a33868 100755 --- a/src/demos/Makefile +++ b/src/demos/Makefile @@ -3,14 +3,15 @@ # Build the various demos # # -TARGETS-y += $(BINDIR)/fire -TARGETS-y += $(BINDIR)/matrix-test -TARGETS-y += $(BINDIR)/life -TARGETS-y += $(BINDIR)/cube-life +BIN-y += fire +BIN-y += life +BIN-y += cube-life +BIN-y += matrix-test + +fire.srcs += fire.c +life.srcs += life.c +cube-life.srcs += cube-life.c +matrix-test.srcs += matrix-test.c include ../../Makefile.common -$(BINDIR)/fire: $(OBJDIR)/fire.o -$(BINDIR)/matrix-test: $(OBJDIR)/matrix-test.o -$(BINDIR)/life: $(OBJDIR)/life.o -$(BINDIR)/cube-life: $(OBJDIR)/cube-life.o diff --git a/src/ledscape/Makefile b/src/ledscape/Makefile index d2ecd636..e23996ed 100755 --- a/src/ledscape/Makefile +++ b/src/ledscape/Makefile @@ -3,16 +3,17 @@ # Build the PRU and LEDscape libraries as well as the PRU firmware. # # -TARGETS-y += $(LIBDIR)/libledscape.a TARGETS-y += $(LIBDIR)/matrix.bin TARGETS-y += $(LIBDIR)/ws281x.bin -include ../../Makefile.common +LIB-y += libledscape.a + +libledscape.srcs += \ + ledscape.c \ + pru.c \ + bitslice.c \ + util.c \ -$(LIBDIR)/libledscape.a: \ - $(OBJDIR)/ledscape.o \ - $(OBJDIR)/pru.o \ - $(OBJDIR)/bitslice.o \ - $(OBJDIR)/util.o \ +include ../../Makefile.common diff --git a/src/mta/mta-font.c b/src/mta/mta-font.c index 7d66aabf..e73227cd 100644 --- a/src/mta/mta-font.c +++ b/src/mta/mta-font.c @@ -2,6 +2,8 @@ * Generated font from json file output by * http://www.pentacom.jp/pentacom/bitfontmaker2/ */ +#include + const uint16_t font[][16] = { ['!'] = { 0x0780, diff --git a/src/mta/mta-sign.c b/src/mta/mta-sign.c index c775b3cc..9fadc530 100644 --- a/src/mta/mta-sign.c +++ b/src/mta/mta-sign.c @@ -10,11 +10,11 @@ #include #include #include "ledscape.h" -#include "mta-font.c" const int width = 256; const int height = 32; +extern const uint16_t font[][16]; static int font_write( From 868367f0c874b6ca971c148152b2591d2d176dd7 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 Apr 2014 20:05:23 +0000 Subject: [PATCH 230/332] split strip and matrix code --- src/ledscape/ledscape.c | 153 +++++++++++++++++++++++++++++----------- 1 file changed, 110 insertions(+), 43 deletions(-) diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index bad5178e..a17cb4bd 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -49,6 +49,26 @@ static const uint8_t gpios3[] = { #define ARRAY_COUNT(a) ((sizeof(a) / sizeof(*a))) +/* + * Configure all of our output pins. + * These must have also been set by the device tree overlay. + * If they are not, some things will appear to work, but not + * all the output pins will be correctly configured as outputs. + */ +static void +ledscape_gpio_init(void) +{ + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios0) ; i++) + pru_gpio(0, gpios0[i], 1, 0); + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios1) ; i++) + pru_gpio(1, gpios1[i], 1, 0); + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios2) ; i++) + pru_gpio(2, gpios2[i], 1, 0); + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios3) ; i++) + pru_gpio(3, gpios3[i], 1, 0); +} + + /** Command structure shared with the PRU. * * This is mapped into the PRU data RAM and points to the @@ -163,13 +183,8 @@ ledscape_remap( } -/** Translate the RGBA buffer to the correct output type and - * initiate the transfer of a frame to the LED strips. - * - * Matrix drivers shuffle to have consecutive bits, ws281x do bit slicing. - */ -void -ledscape_draw( +static void +ledscape_matrix_draw( ledscape_t * const leds, const void * const buffer ) @@ -178,7 +193,6 @@ ledscape_draw( const uint32_t * const in = buffer; uint8_t * const out = leds->pru->ddr + leds->frame_size * frame; -#ifdef CONFIG_LED_MATRIX // matrix packed is: // this way the PRU can read all sixteen output pixels in // one LBBO and clock them out. @@ -206,8 +220,26 @@ ledscape_draw( } } leds->ws281x->pixels_dma = leds->pru->ddr_addr + leds->frame_size * frame; + // disable double buffering for now //frame = (frame + 1) & 1; -#else +} + + +/** Translate the RGBA buffer to the correct output type and + * initiate the transfer of a frame to the LED strips. + * + * Matrix drivers shuffle to have consecutive bits, ws281x do bit slicing. + */ +void +ledscape_strip_draw( + ledscape_t * const leds, + const void * const buffer +) +{ + static unsigned frame = 0; + const uint32_t * const in = buffer; + uint8_t * const out = leds->pru->ddr + leds->frame_size * frame; + // Translate the RGBA frame into G R B, sliced by color // only 48 outputs currently supported const unsigned pru_stride = 48; @@ -236,7 +268,6 @@ ledscape_draw( // Send the start command leds->ws281x->command = 1; -#endif } @@ -258,28 +289,14 @@ ledscape_wait( } } - -ledscape_t * -ledscape_init( +static ledscape_t * +ledscape_matrix_init( unsigned width, unsigned height ) { pru_t * const pru = pru_init(0); -#ifdef CONFIG_LED_MATRIX const size_t frame_size = 16 * 8 * width * 3; //LEDSCAPE_NUM_STRIPS * 4; -#else - const size_t frame_size = 48 * width * 8 * 3; -#endif - - printf("frame-size %zu, ddr-size=%zu\n", frame_size, pru->ddr_size); -#if 0 - if (2 *frame_size > pru->ddr_size) - die("Pixel data needs at least 2 * %zu, only %zu in DDR\n", - frame_size, - pru->ddr_size - ); -#endif ledscape_t * const leds = calloc(1, sizeof(*leds)); @@ -292,7 +309,6 @@ ledscape_init( .matrix = calloc(sizeof(*leds->matrix), 1), }; -#ifdef CONFIG_LED_MATRIX *(leds->matrix) = (led_matrix_config_t) { .matrix_width = 256, .matrix_height = 8, @@ -329,7 +345,52 @@ ledscape_init( .command = 0, .response = 0, }; -#else + + ledscape_gpio_init(); + + // Initiate the PRU program + pru_exec(pru, "./lib/matrix.bin"); + + // Watch for a done response that indicates a proper startup + // \todo timeout if it fails + printf("waiting for response\n"); + while (!leds->ws281x->response) + ; + printf("got response\n"); + + return leds; +} + + +static ledscape_t * +ledscape_strips_init( + unsigned width, + unsigned height +) +{ + pru_t * const pru = pru_init(0); + const size_t frame_size = 48 * width * 8 * 3; + + printf("frame-size %zu, ddr-size=%zu\n", frame_size, pru->ddr_size); +#if 0 + if (2 *frame_size > pru->ddr_size) + die("Pixel data needs at least 2 * %zu, only %zu in DDR\n", + frame_size, + pru->ddr_size + ); +#endif + + ledscape_t * const leds = calloc(1, sizeof(*leds)); + + *leds = (ledscape_t) { + .pru = pru, + .width = width, + .height = height, + .ws281x = pru->data_ram, + .frame_size = frame_size, + .matrix = calloc(sizeof(*leds->matrix), 1), + }; + // LED strips, not matrix output *(leds->ws281x) = (ws281x_command_t) { .pixels_dma = 0, // will be set in draw routine @@ -337,27 +398,13 @@ ledscape_init( .command = 0, .response = 0, }; -#endif printf("%d\n", leds->ws281x->num_pixels); - - // Configure all of our output pins. - for (unsigned i = 0 ; i < ARRAY_COUNT(gpios0) ; i++) - pru_gpio(0, gpios0[i], 1, 0); - for (unsigned i = 0 ; i < ARRAY_COUNT(gpios1) ; i++) - pru_gpio(1, gpios1[i], 1, 0); - for (unsigned i = 0 ; i < ARRAY_COUNT(gpios2) ; i++) - pru_gpio(2, gpios2[i], 1, 0); - for (unsigned i = 0 ; i < ARRAY_COUNT(gpios3) ; i++) - pru_gpio(3, gpios3[i], 1, 0); + ledscape_gpio_init(); // Initiate the PRU program -#ifdef CONFIG_LED_MATRIX - pru_exec(pru, "./lib/matrix.bin"); -#else pru_exec(pru, "./lib/ws281x.bin"); -#endif // Watch for a done response that indicates a proper startup // \todo timeout if it fails @@ -370,6 +417,26 @@ ledscape_init( } +ledscape_t * +ledscape_init( + unsigned width, + unsigned height +) +{ + return ledscape_matrix_init(width, height); +} + + +void +ledscape_draw( + ledscape_t * const leds, + const void * const buffer +) +{ + return ledscape_matrix_draw(leds, buffer); +} + + void ledscape_close( ledscape_t * const leds From d427dc35f31dcd8b59e2fdcb02dbfb10a6963908 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 Apr 2014 20:17:21 +0000 Subject: [PATCH 231/332] move matrix config into ledscape.h --- src/ledscape/ledscape.h | 20 ++++++++++++++++++++ src/mta/mta-sign.c | 31 ++++++------------------------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/ledscape/ledscape.h b/src/ledscape/ledscape.h index 5941b794..8fa4d709 100644 --- a/src/ledscape/ledscape.h +++ b/src/ledscape/ledscape.h @@ -18,6 +18,26 @@ #define LEDSCAPE_NUM_STRIPS 32 +typedef struct { + int x; + int y; + int rot; // 0 == none, 1 == left, 2 == right, 3 == flip +} ledscape_matrix_panel_t; + +#define LEDSCAPE_MATRIX_OUTPUTS 8 // number of outputs on the cape +#define LEDSCAPE_MATRIX_PANELS 8 // number of panels chained per output + +typedef struct { + int width; + int height; + int panel_width; + int panel_height; + int leds_width; + int leds_height; + ledscape_matrix_panel_t panels[LEDSCAPE_MATRIX_OUTPUTS][LEDSCAPE_MATRIX_PANELS]; +} ledscape_matrix_config_t; + + /** LEDscape pixel format is BRGA. * * data is laid out with BRGA format, since that is how it will diff --git a/src/mta/mta-sign.c b/src/mta/mta-sign.c index 9fadc530..f6352e81 100644 --- a/src/mta/mta-sign.c +++ b/src/mta/mta-sign.c @@ -99,26 +99,7 @@ font_write( } -typedef struct { - int x; - int y; - int rot; // 0 == none, 1 == left, 2 == right, 3 == flip -} ledscape_panel_t; - -#define LEDSCAPE_OUTPUTS 8 // number of outputs on the cape -#define LEDSCAPE_PANELS 8 // number of panels chained per output - -typedef struct { - int width; - int height; - int panel_width; - int panel_height; - int leds_width; - int leds_height; - ledscape_panel_t panels[LEDSCAPE_OUTPUTS][LEDSCAPE_PANELS]; -} ledscape_config_t; - -static ledscape_config_t ledscape_config = +static ledscape_matrix_config_t ledscape_config = { // frame buffer size .width = 256, @@ -164,7 +145,7 @@ static void framebuffer_copy( uint32_t * const out, const uint32_t * const in, - const ledscape_config_t * const config, + const ledscape_matrix_config_t * const config, const int rot ) { @@ -217,14 +198,14 @@ void framebuffer_fixup( uint32_t * const out, const uint32_t * const in, - const ledscape_config_t * const config + const ledscape_matrix_config_t * const config ) { - for (int i = 0 ; i < LEDSCAPE_OUTPUTS ; i++) + for (int i = 0 ; i < LEDSCAPE_MATRIX_OUTPUTS ; i++) { - for (int j = 0 ; j < LEDSCAPE_PANELS ; j++) + for (int j = 0 ; j < LEDSCAPE_MATRIX_PANELS ; j++) { - const ledscape_panel_t * const panel + const ledscape_matrix_panel_t * const panel = &config->panels[i][j]; int ox = config->panel_width * j; From c5d742dfdd7fbed91949162bd5f4158c35ca52f0 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 Apr 2014 20:25:23 +0000 Subject: [PATCH 232/332] move matrix remap into ledscape.c --- src/ledscape/ledscape.c | 99 ++++++++++++++++++++++++----------------- src/ledscape/ledscape.h | 7 +-- src/mta/mta-sign.c | 96 ++------------------------------------- 3 files changed, 62 insertions(+), 140 deletions(-) diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index a17cb4bd..4cdb5717 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -465,75 +465,90 @@ ledscape_set_color( } + /** Copy a 16x32 region from in to a 32x16 region of out. * If rot == 0, rotate -90, else rotate +90. */ static void -framebuffer_copy( +ledscape_matrix_panel_copy( uint32_t * const out, const uint32_t * const in, - const int rot, - const int leds_width, - const int width + const ledscape_matrix_config_t * const config, + const int rot ) { - for (int x = 0 ; x < 16 ; x++) + for (int x = 0 ; x < config->panel_width ; x++) { - for (int y = 0 ; y < 32 ; y++) + for (int y = 0 ; y < config->panel_height ; y++) { int ox, oy; - if (rot) + if (rot == 0) + { + // no rotation == (0,0) => (0,0) + ox = x; + oy = y; + } else + if (rot == 1) { // rotate +90 (0,0) => (0,15) - ox = y; - oy = 15 - x; - } else { - // rotate -90 (0,0) => (31,0) - ox = 31 - y; + ox = config->panel_height-1 - y; oy = x; + } else + if (rot == 2) + { + // rotate -90 (0,0) => (31,0) + ox = y; + oy = config->panel_width-1 - x; + } else + if (rot == 3) + { + // flip == (0,0) => (31,15) + ox = config->panel_width-1 - x; + oy = config->panel_height-1 - y; + } else + { + // barf + ox = oy = 0; } - out[ox + leds_width*oy] = in[x + width*y]; + out[x + config->leds_width*y] + = in[ox + config->width*oy]; } } } -/** With the panels mounted vertically, adjust the mapping. - * Even panels are rotated -90, odd ones +90. - * Input framebuffer is 256x32 - * Output framebuffer is 128x64 (actually x128, but we are not using the - * other half of it). +/** Remap the matrix framebuffer based on the config. */ void -framebuffer_flip( +ledscape_matrix_remap( uint32_t * const out, const uint32_t * const in, - const int leds_width, - const int leds_height, - const int width, - const int height + const ledscape_matrix_config_t * const config ) { - (void) height; - - for (int x = 0, rot=0 ; x < width ; x += 16, rot = !rot) + for (int i = 0 ; i < LEDSCAPE_MATRIX_OUTPUTS ; i++) { - int ox = (x*2) % leds_width; - int oy = (((x*2)) / leds_width) * 16; - - // if we are more than half-way past the width, - // flip the axis - const uint32_t * p = &in[x]; - - framebuffer_copy( - &out[ox + oy * leds_width], - p, - rot, - leds_width, - width - ); + for (int j = 0 ; j < LEDSCAPE_MATRIX_PANELS ; j++) + { + const ledscape_matrix_panel_t * const panel + = &config->panels[i][j]; + + int ox = config->panel_width * j; + int oy = config->panel_height * i; + //printf("%d,%d => %d,%d <= %d,%d,%d\n", i, j, ox, oy, panel->x, panel->y, panel->rot); + + const uint32_t * const ip + = &in[panel->x + panel->y * config->width]; + uint32_t * const op + = &out[ox + oy * config->leds_width]; + + ledscape_matrix_panel_copy( + op, + ip, + config, + panel->rot + ); + } } } - - diff --git a/src/ledscape/ledscape.h b/src/ledscape/ledscape.h index 8fa4d709..621b9952 100644 --- a/src/ledscape/ledscape.h +++ b/src/ledscape/ledscape.h @@ -104,13 +104,10 @@ ledscape_close( /** Flip a rectangular frame buffer to map the LED matrices */ void -framebuffer_flip( +ledscape_matrix_remap( uint32_t * leds_out, const uint32_t * fb_in, - const int leds_width, - const int leds_height, - const int width, - const int height + const ledscape_matrix_config_t * config ); diff --git a/src/mta/mta-sign.c b/src/mta/mta-sign.c index f6352e81..4a8bd589 100644 --- a/src/mta/mta-sign.c +++ b/src/mta/mta-sign.c @@ -110,8 +110,8 @@ static ledscape_matrix_config_t ledscape_config = .panel_height = 16, // ledscape matrix output size - .leds_width = LEDSCAPE_PANELS*32, // could be less - .leds_height = LEDSCAPE_OUTPUTS*16, + .leds_width = LEDSCAPE_MATRIX_PANELS*32, // could be less + .leds_height = LEDSCAPE_MATRIX_OUTPUTS*16, .panels = { [0] = { @@ -138,96 +138,6 @@ static ledscape_matrix_config_t ledscape_config = }; -/** Copy a 16x32 region from in to a 32x16 region of out. - * If rot == 0, rotate -90, else rotate +90. - */ -static void -framebuffer_copy( - uint32_t * const out, - const uint32_t * const in, - const ledscape_matrix_config_t * const config, - const int rot -) -{ - for (int x = 0 ; x < config->panel_width ; x++) - { - for (int y = 0 ; y < config->panel_height ; y++) - { - int ox, oy; - if (rot == 0) - { - // no rotation == (0,0) => (0,0) - ox = x; - oy = y; - } else - if (rot == 1) - { - // rotate +90 (0,0) => (0,15) - ox = config->panel_height-1 - y; - oy = x; - } else - if (rot == 2) - { - // rotate -90 (0,0) => (31,0) - ox = y; - oy = config->panel_width-1 - x; - } else - if (rot == 3) - { - // flip == (0,0) => (31,15) - ox = config->panel_width-1 - x; - oy = config->panel_height-1 - y; - } else - { - // barf - ox = oy = 0; - } - - out[x + config->leds_width*y] - = in[ox + config->width*oy]; - } - } -} - - -/** With the panels mounted vertically, adjust the mapping. - * Even panels are rotated -90, odd ones +90. - * Input framebuffer is 256x32 - */ -void -framebuffer_fixup( - uint32_t * const out, - const uint32_t * const in, - const ledscape_matrix_config_t * const config -) -{ - for (int i = 0 ; i < LEDSCAPE_MATRIX_OUTPUTS ; i++) - { - for (int j = 0 ; j < LEDSCAPE_MATRIX_PANELS ; j++) - { - const ledscape_matrix_panel_t * const panel - = &config->panels[i][j]; - - int ox = config->panel_width * j; - int oy = config->panel_height * i; - printf("%d,%d => %d,%d <= %d,%d,%d\n", i, j, ox, oy, panel->x, panel->y, panel->rot); - - const uint32_t * const ip - = &in[panel->x + panel->y * config->width]; - uint32_t * const op - = &out[ox + oy * config->leds_width]; - - framebuffer_copy( - op, - ip, - config, - panel->rot - ); - } - } -} - - int main( @@ -260,7 +170,7 @@ main( else scroll_x--; - framebuffer_fixup(fb, p, &ledscape_config); + ledscape_matrix_remap(fb, p, &ledscape_config); ledscape_draw(leds, fb); usleep(20000); From ffb581442a1a605dbf26b2d23105700f4811bec5 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 Apr 2014 20:56:08 +0000 Subject: [PATCH 233/332] import a fixed-width 8px font, cleanup unused bitslicing code --- src/demos/Makefile | 2 + src/demos/identify.c | 17 +- src/ledscape/Makefile | 3 +- src/ledscape/bitpattern.h | 133 ++++++ src/ledscape/bitslice.c | 89 ---- src/ledscape/bitslice.h | 25 -- src/ledscape/fixed-font.c | 866 ++++++++++++++++++++++++++++++++++++++ src/ledscape/ledscape.c | 53 +++ src/ledscape/ledscape.h | 10 + src/ledscape/util.c | 1 - 10 files changed, 1076 insertions(+), 123 deletions(-) create mode 100644 src/ledscape/bitpattern.h delete mode 100644 src/ledscape/bitslice.c delete mode 100644 src/ledscape/bitslice.h create mode 100644 src/ledscape/fixed-font.c diff --git a/src/demos/Makefile b/src/demos/Makefile index b0a33868..5d23ac93 100755 --- a/src/demos/Makefile +++ b/src/demos/Makefile @@ -7,9 +7,11 @@ BIN-y += fire BIN-y += life BIN-y += cube-life BIN-y += matrix-test +BIN-y += identify fire.srcs += fire.c life.srcs += life.c +identify.srcs += identify.c cube-life.srcs += cube-life.c matrix-test.srcs += matrix-test.c diff --git a/src/demos/identify.c b/src/demos/identify.c index 06a5f18f..3c8e89d4 100644 --- a/src/demos/identify.c +++ b/src/demos/identify.c @@ -9,11 +9,11 @@ #include #include #include "ledscape.h" -#include "mta-font.c" const int width = 256; const int height = 128; +/* static int font_write( @@ -86,6 +86,7 @@ font_write( return x; } +*/ int @@ -96,7 +97,6 @@ main( { ledscape_t * const leds = ledscape_init(width, height); - printf("init done\n"); time_t last_time = time(NULL); unsigned last_i = 0; @@ -108,11 +108,16 @@ main( for (int x = 0 ; x < 256 ; x += 32) { - for (int y = 0 ; y < 128 ; y += 16) + for (int y = 0 ; y < 128 ; y += 8) { - char buf[32]; - snprintf(buf, sizeof(buf), "%d,%d", x, y); - font_write(p, 0xFF0000, x, y, buf); + ledscape_printf( + &p[x + width*y], + width, + 0xFF0000, + "%d,%d", + x, + y + ); } } diff --git a/src/ledscape/Makefile b/src/ledscape/Makefile index e23996ed..1132e28a 100755 --- a/src/ledscape/Makefile +++ b/src/ledscape/Makefile @@ -11,9 +11,8 @@ LIB-y += libledscape.a libledscape.srcs += \ ledscape.c \ pru.c \ - bitslice.c \ util.c \ - + fixed-font.c \ include ../../Makefile.common diff --git a/src/ledscape/bitpattern.h b/src/ledscape/bitpattern.h new file mode 100644 index 00000000..b4b9d0d8 --- /dev/null +++ b/src/ledscape/bitpattern.h @@ -0,0 +1,133 @@ +/** \file + * ASCII art for bits. + */ +#pragma once + +#define ________ 0x00 // 0 +#define _______X 0x01 // 1 +#define ______X_ 0x02 // 2 +#define ______XX 0x03 // 3 +#define _____X__ 0x04 // 4 +#define _____X_X 0x05 // 5 +#define _____XX_ 0x06 // 6 +#define _____XXX 0x07 // 7 +#define ____X___ 0x08 // 8 +#define ____X__X 0x09 // 9 +#define ____X_X_ 0x0a // 10 +#define ____X_XX 0x0b // 11 +#define ____XX__ 0x0c // 12 +#define ____XX_X 0x0d // 13 +#define ____XXX_ 0x0e // 14 +#define ____XXXX 0x0f // 15 +#define ___X____ 0x10 // 16 +#define ___X___X 0x11 // 17 +#define ___X__X_ 0x12 // 18 +#define ___X__XX 0x13 // 19 +#define ___X_X__ 0x14 // 20 +#define ___X_X_X 0x15 // 21 +#define ___X_XX_ 0x16 // 22 +#define ___X_XXX 0x17 // 23 +#define ___XX___ 0x18 // 24 +#define ___XX__X 0x19 // 25 +#define ___XX_X_ 0x1a // 26 +#define ___XX_XX 0x1b // 27 +#define ___XXX__ 0x1c // 28 +#define ___XXX_X 0x1d // 29 +#define ___XXXX_ 0x1e // 30 +#define ___XXXXX 0x1f // 31 +#define __X_____ 0x20 // 32 +#define __X____X 0x21 // 33 +#define __X___X_ 0x22 // 34 +#define __X___XX 0x23 // 35 +#define __X__X__ 0x24 // 36 +#define __X__X_X 0x25 // 37 +#define __X__XX_ 0x26 // 38 +#define __X__XXX 0x27 // 39 +#define __X_X___ 0x28 // 40 +#define __X_X__X 0x29 // 41 +#define __X_X_X_ 0x2a // 42 +#define __X_X_XX 0x2b // 43 +#define __X_XX__ 0x2c // 44 +#define __X_XX_X 0x2d // 45 +#define __X_XXX_ 0x2e // 46 +#define __X_XXXX 0x2f // 47 +#define __XX____ 0x30 // 48 +#define __XX___X 0x31 // 49 +#define __XX__X_ 0x32 // 50 +#define __XX__XX 0x33 // 51 +#define __XX_X__ 0x34 // 52 +#define __XX_X_X 0x35 // 53 +#define __XX_XX_ 0x36 // 54 +#define __XX_XXX 0x37 // 55 +#define __XXX___ 0x38 // 56 +#define __XXX__X 0x39 // 57 +#define __XXX_X_ 0x3a // 58 +#define __XXX_XX 0x3b // 59 +#define __XXXX__ 0x3c // 60 +#define __XXXX_X 0x3d // 61 +#define __XXXXX_ 0x3e // 62 +#define __XXXXXX 0x3f // 63 +#define _X______ 0x40 // 64 +#define _X_____X 0x41 // 65 +#define _X____X_ 0x42 // 66 +#define _X____XX 0x43 // 67 +#define _X___X__ 0x44 // 68 +#define _X___X_X 0x45 // 69 +#define _X___XX_ 0x46 // 70 +#define _X___XXX 0x47 // 71 +#define _X__X___ 0x48 // 72 +#define _X__X__X 0x49 // 73 +#define _X__X_X_ 0x4a // 74 +#define _X__X_XX 0x4b // 75 +#define _X__XX__ 0x4c // 76 +#define _X__XX_X 0x4d // 77 +#define _X__XXX_ 0x4e // 78 +#define _X__XXXX 0x4f // 79 +#define _X_X____ 0x50 // 80 +#define _X_X___X 0x51 // 81 +#define _X_X__X_ 0x52 // 82 +#define _X_X__XX 0x53 // 83 +#define _X_X_X__ 0x54 // 84 +#define _X_X_X_X 0x55 // 85 +#define _X_X_XX_ 0x56 // 86 +#define _X_X_XXX 0x57 // 87 +#define _X_XX___ 0x58 // 88 +#define _X_XX__X 0x59 // 89 +#define _X_XX_X_ 0x5a // 90 +#define _X_XX_XX 0x5b // 91 +#define _X_XXX__ 0x5c // 92 +#define _X_XXX_X 0x5d // 93 +#define _X_XXXX_ 0x5e // 94 +#define _X_XXXXX 0x5f // 95 +#define _XX_____ 0x60 // 96 +#define _XX____X 0x61 // 97 +#define _XX___X_ 0x62 // 98 +#define _XX___XX 0x63 // 99 +#define _XX__X__ 0x64 // 100 +#define _XX__X_X 0x65 // 101 +#define _XX__XX_ 0x66 // 102 +#define _XX__XXX 0x67 // 103 +#define _XX_X___ 0x68 // 104 +#define _XX_X__X 0x69 // 105 +#define _XX_X_X_ 0x6a // 106 +#define _XX_X_XX 0x6b // 107 +#define _XX_XX__ 0x6c // 108 +#define _XX_XX_X 0x6d // 109 +#define _XX_XXX_ 0x6e // 110 +#define _XX_XXXX 0x6f // 111 +#define _XXX____ 0x70 // 112 +#define _XXX___X 0x71 // 113 +#define _XXX__X_ 0x72 // 114 +#define _XXX__XX 0x73 // 115 +#define _XXX_X__ 0x74 // 116 +#define _XXX_X_X 0x75 // 117 +#define _XXX_XX_ 0x76 // 118 +#define _XXX_XXX 0x77 // 119 +#define _XXXX___ 0x78 // 120 +#define _XXXX__X 0x79 // 121 +#define _XXXX_X_ 0x7a // 122 +#define _XXXX_XX 0x7b // 123 +#define _XXXXX__ 0x7c // 124 +#define _XXXXX_X 0x7d // 125 +#define _XXXXXX_ 0x7e // 126 +#define _XXXXXXX 0x7f // 127 diff --git a/src/ledscape/bitslice.c b/src/ledscape/bitslice.c deleted file mode 100644 index 931040b2..00000000 --- a/src/ledscape/bitslice.c +++ /dev/null @@ -1,89 +0,0 @@ -/** \file - * Slice an RGB image into an 8-pixel GRB packed format for the Teensy. - * - * Designed to clock data out to USB teensy3 serial devices, which require - * bitslicing into the raw form for the OctoWS2811 firmware. - */ -#include -#include -#include -#include -#include "bitslice.h" - - -/** Extract a ADDRESSING_HORIZONTAL_NORMAL pixel from the image. - * - * This reverses the y since the teensy's are at the bottom of the - * strips, while the image coordinate frame is at the top. - */ -static const uint8_t * -bitmap_pixel( - const uint8_t * const bitmap, - const unsigned width, - const unsigned height, - const unsigned x, - const unsigned y -) -{ - if (1) - return bitmap + ((height - y - 1) * width + x) * 3; - else - return bitmap + ((height - y - 1) + x * height) * 3; -} - - -/** Prepare one Teensy3 worth of image data. - * - * Each Teensy handles 8 rows of data and needs the bits sliced into - * each 8 rows. - * - * Since some of the pixels might have bad single channels, - * allow them to be masked out entirely. - */ -void -bitslice( - uint8_t * const out, - const uint8_t * const bad_pixels, - const uint8_t * in, - const unsigned width, - const unsigned height, - const unsigned x_offset -) -{ - // Reorder from RGB in the input to GRB in the output - static const uint8_t channel_map[] = { 1, 0, 2 }; - - for(unsigned y=0 ; y < height ; y++) - { - for (unsigned channel = 0 ; channel < 3 ; channel++) - { - const uint8_t mapped_channel - = channel_map[channel]; - - for (unsigned bit_num = 0 ; bit_num < 8 ; bit_num++) - { - uint8_t b = 0; - const uint8_t mask = 1 << (7 - bit_num); - - for(unsigned x = 0 ; x < 8 ; x++) - { - const uint8_t bit_pos = 1 << x; - if (bad_pixels - && bad_pixels[y] & bit_pos) - continue; - const uint8_t * const p - = bitmap_pixel(in, width, height, x + x_offset, y); - const uint8_t v = p[channel]; - - // If the bit_num'th bit in v is - // set, then mark that the x'th bit - // in this output byte should be set. - if (v & mask) - b |= bit_pos; - } - - out[24*y + 8*mapped_channel + bit_num] = b; - } - } - } -} diff --git a/src/ledscape/bitslice.h b/src/ledscape/bitslice.h deleted file mode 100644 index da85dd05..00000000 --- a/src/ledscape/bitslice.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _ledscape_bitslice_h_ -#define _ledscape_bitslice_h_ - -#include - - -/** Prepare one Teensy3 worth of image data. - * - * Each Teensy handles 8 rows of data and needs the bits sliced into - * each 8 rows. - * - * Since some of the pixels might have bad single channels, - * allow them to be masked out entirely. - */ -extern void -bitslice( - uint8_t * const out, - const uint8_t * const bad_pixels, - const uint8_t * in, - const unsigned width, - const unsigned height, - const unsigned x_offset -); - -#endif diff --git a/src/ledscape/fixed-font.c b/src/ledscape/fixed-font.c new file mode 100644 index 00000000..0577a673 --- /dev/null +++ b/src/ledscape/fixed-font.c @@ -0,0 +1,866 @@ +/** \file + * Font is encoded as 5 vertical stripes, 7 bits per stripe. + * Array is in ASCII order, with an offset of 0x20 (' '). + * Look at them sideways. + */ +#include +#include "bitpattern.h" + +const uint8_t fixed_font[][5] = { + // Space + { + ________, + ________, + ________, + ________, + ________, + }, + // ! + { + ________, + ________, + _X_XXXXX, + ________, + ________, + }, + // " + { + ________, + ______XX, + ________, + ______XX, + ________, + }, + // # + { + ___X__X_, + __XXXXXX, + ___X__X_, + __XXXXXX, + ___X__X_, + }, + // $ + { + _____X__, + __X_X_X_, + _XXXXXXX, + __X_X_X_, + ___X____, + }, + // % + { + __X___X_, + ___X_X_X, + __X_X_X_, + _X_X_X__, + __X___X_, + }, + // & + { + __XX_XX_, + _X__X__X, + _X_X___X, + __X___X_, + _X_X____, + }, + // ' + { + ________, + ________, + ______XX, + ________, + ________, + }, + // ( + { + ________, + ___XXX__, + __X___X_, + _X_____X, + ________, + }, + // ( + { + ________, + _X_____X, + __X___X_, + ___XXX__, + ________, + }, + // * + { + _____X__, + ___X_X__, + ____XXXX, + ___X_X__, + _____X__, + }, + // + + { + ____X___, + ____X___, + __XXXXX_, + ____X___, + ____X___, + }, + // ' (not sure) + { + ________, + ________, + ______X_, + _______X, + ________, + }, + // - + { + ____X___, + ____X___, + ____X___, + ____X___, + ____X___, + }, + // . + { + ________, + ________, + _X______, + ________, + ________, + }, + // / + { + __X_____, + ___X____, + ____X___, + _____X__, + ______X_, + }, + + // 0 + { + __XXXXX_, + _X_____X, + _X_____X, + _X_____X, + __XXXXX_, + }, + // 1 + { + ________, + _X____X_, + _XXXXXXX, + _X______, + ________, + }, + // 2 + { + _XX___X_, + _X_X___X, + _X__X__X, + _X__X__X, + _X___XX_, + }, + // 3 + { + __X___X_, + _X_____X, + _X__X__X, + _X__X__X, + __XX_XX_, + }, + // 4 + { + _____XXX, + ____X___, + ____X___, + _XXXXXXX, + ____X___, + }, + // 5 + { + __X_XXXX, + _X__X__X, + _X__X__X, + _X__X__X, + __XX___X, + }, + // 6 + { + __XXXXX_, + _X__X__X, + _X__X__X, + _X__X__X, + __XX__X_, + }, + // 7 + { + _X_____X, + __X____X, + ___X___X, + ____X__X, + _____XXX, + }, + // 8 + { + __XX_XX_, + _X__X__X, + _X__X__X, + _X__X__X, + __XX_XX_, + }, + // 9 + { + _____XX_, + ____X__X, + ____X__X, + ____X__X, + _XXXXXX_, + }, + + // : + { + ________, + ________, + __XX_XX_, + ________, + ________, + }, + // ; + { + ________, + _X______, + __XX_XX_, + ________, + ________, + }, + // < + { + ____X___, + ___X_X__, + __X___X_, + _X_____X, + ________, + }, + // = + { + ___X_X__, + ___X_X__, + ___X_X__, + ___X_X__, + ___X_X__, + }, + // > + { + ________, + _X_____X, + __X___X_, + ___X_X__, + ____X___, + }, + // ? + { + _____XX_, + _______X, + _X_X___X, + ____X__X, + _____XX_, + }, + // @ + { + __XXXXX_, + _X_____X, + _X__X__X, + _X_X_X_X, + ____X_X_, + }, + + // A + { + _XXXXX__, + ____X_X_, + ____X__X, + ____X_X_, + _XXXXX__, + }, + // B + { + _XXXXXXX, + _X__X__X, + _X__X__X, + _X__X__X, + __XX_XX_, + }, + // C + { + __XXXXX_, + _X_____X, + _X_____X, + _X_____X, + __X___X_, + }, + // D + { + _XXXXXXX, + _X_____X, + _X_____X, + _X_____X, + __XXXXX_, + }, + // E + { + _XXXXXXX, + _X__X__X, + _X__X__X, + _X__X__X, + _X_____X, + }, + // F + { + _XXXXXXX, + ____X__X, + ____X__X, + ____X__X, + _______X, + }, + // G + { + __XXXXX_, + _X_____X, + _X__X__X, + _X__X__X, + __XX__X_, + }, + // H + { + _XXXXXXX, + ____X___, + ____X___, + ____X___, + _XXXXXXX, + }, + // I was 65,65,127,65,65, + { + ________, + _X_____X, + _XXXXXXX, + _X_____X, + ________, + }, + // J + { + __X_____, + _X______, + _X_____X, + __XXXXXX, + _______X, + }, + // K + { + _XXXXXXX, + ____X___, + ___X_X__, + __X___X_, + _X_____X, + }, + // L + { + _XXXXXXX, + _X______, + _X______, + _X______, + _X______, + }, + // M + { + _XXXXXXX, + ______X_, + _____X__, + ______X_, + _XXXXXXX, + }, + // N + { + _XXXXXXX, + _____X__, + ____X___, + ___X____, + _XXXXXXX, + }, + // O + { + __XXXXX_, + _X_____X, + _X_____X, + _X_____X, + __XXXXX_, + }, + // P + { + _XXXXXXX, + ____X__X, + ____X__X, + ____X__X, + _____XX_, + }, + // Q + { + __XXXXX_, + _X_____X, + _X_X___X, + __X____X, + _X_XXXX_, + }, + // R + { + _XXXXXXX, + ____X__X, + ___XX__X, + __X_X__X, + _X___XX_, + }, + // S + { + __X__XX_, + _X__X__X, + _X__X__X, + _X__X__X, + __XX__X_, + }, + // T + { + _______X, + _______X, + _XXXXXXX, + _______X, + _______X, + }, + // U + { + __XXXXXX, + _X______, + _X______, + _X______, + __XXXXXX, + }, + // V + { + ___XXXXX, + __X_____, + _X______, + __X_____, + ___XXXXX, + }, + // W + { + __XXXXXX, + _X______, + __XX____, + _X______, + __XXXXXX, + }, + // X + { + _XX___XX, + ___X_X__, + ____X___, + ___X_X__, + _XX___XX, + }, + // Y + { + ______XX, + _____X__, + _XXXX___, + _____X__, + ______XX, + }, + // Z + { + _XX____X, + _X_X___X, + _X__X__X, + _X___X_X, + _X____XX, + }, + + // [ + { + ________, + _XXXXXXX, + _X_____X, + _X_____X, + ________, + }, + // back slash + { + ______X_, + _____X__, + ____X___, + ___X____, + __X_____, + }, + // ] + { + ________, + _X_____X, + _X_____X, + _XXXXXXX, + ________, + }, + // ^ + { + ________, + ______X_, + _______X, + ______X_, + ________, + }, + // _ + { + ____X___, + ____X___, + ____X___, + ____X___, + ____X___, + }, + // ` + { + ________, + ________, + _______X, + ______X_, + ________, + }, + + // a + { + _XXX____, + _X__X___, + _X__X___, + __X_X___, + _XXXX___, + }, + // b + { + _XXXXXX_, + __XX____, + _X__X___, + _X__X___, + __XX____, + }, + // c + { + __XX____, + _X__X___, + _X__X___, + _X__X___, + _X__X___, + }, + // d + { + __XX____, + _X__X___, + _X__X___, + __XX____, + _XXXXXX_, + }, + // e + { + __XXX___, + _X_X_X__, + _X_X_X__, + _X_X_X__, + _X_XX___, + }, + // f + { + ________, + ____X___, + _XXXXX__, + ____X_X_, + ________, + }, + // g + { + __X__X__, + _X__X_X_, + _X__X_X_, + _X__X_X_, + __XXXX__, + }, + // h + { + _XXXXXX_, + ____X___, + ____X___, + ____X___, + _XXX____, + }, + // i + { + ________, + ________, + _XXXX_X_, + ________, + ________, + }, + // j + { + __X_____, + _X______, + _X____X_, + __XXXXX_, + ______X_, + }, + // k + { + _XXXXX__, + ___X____, + ___X____, + __X_X___, + _X___X__, + }, + // l + { + ________, + _XXXXX__, + _X______, + _X______, + ________, + }, + // m + { + _XXXX___, + _____X__, + _XXXX___, + _____X__, + _XXXX___, + }, + // n + { + _XXXXX__, + ____X___, + _____X__, + _____X__, + _XXXX___, + }, + // o + { + __XX____, + _X__X___, + _X__X___, + _X__X___, + __XX____, + }, + // p + { + _XXXXXX_, + ___X__X_, + ___X__X_, + ___X__X_, + ____XX__, + }, + // q + { + ____XX__, + ___X__X_, + ___X__X_, + ___X__X_, + _XXXXX__, + }, + // r + { + _XXXXX__, + ____X___, + _____X__, + _____X__, + ____X___, + }, + // s + { + _X__X___, + _X_X_X__, + _X_X_X__, + _X_X_X__, + __X__X__, + }, + // t + { + _____X__, + _____X__, + _XXXXXX_, + _____X__, + _____X__, + }, + // u + { + __XXXX__, + _X______, + _X______, + _X______, + __XXXX__, + }, + // v + { + ___XXX__, + __X_____, + _X______, + __X_____, + ___XXX__, + }, + // w + { + _XXXXX__, + __X_____, + ___X____, + __X_____, + _XXXXX__, + }, + // x + { + _X___X__, + __X_X___, + ___X____, + __X_X___, + _X___X__, + }, + // y + { + _____X__, + ____X___, + _XXX____, + ____X___, + _____X__, + }, + // z + { + _X___X__, + _XX__X__, + _X_X_X__, + _X__XX__, + _X___X__, + }, + + // { + { + ________, + ____X___, + __XX_XX_, + _X_____X, + ________, + }, + // | + { + ________, + ________, + _XXXXXXX, + ________, + ________, + }, + // } + { + ________, + _X_____X, + __XX_XX_, + ____X___, + ________, + }, + // ~ + { + ___X____, + ____X___, + ___XX___, + ___X____, + ____X___, + }, + + // Small Numbers (for adding colon in clock applications) + // 0 + { + ________, + __XXXXX_, + __X___X_, + __XXXXX_, + ________, + }, + // 1 + { + ________, + ________, + __XXXXX_, + ________, + ________, + }, + // 2 + { + ________, + __XXX_X_, + __X_X_X_, + __X_XXX_, + ________, + }, + // 3 + { + ________, + __X_X_X_, + __X_X_X_, + __XXXXX_, + ________, + }, + // 4 + { + ________, + ____XXX_, + ____X___, + __XXXXX_, + ________, + }, + // 5 + { + ________, + __X_XXX_, + __X_X_X_, + __XXX_X_, + ________, + }, + // 6 + { + ________, + __XXXXX_, + __X_X_X_, + __XXX_X_, + ________, + }, + // 7 + { + ________, + ______X_, + ______X_, + __XXXXX_, + ________, + }, + // 8 + { + ________, + __XXXXX_, + __X_X_X_, + __XXXXX_, + ________, + }, + // 9 + { + ________, + ____XXX_, + ____X_X_, + __XXXXX_, + ________, + }, + // : + { + ________, + ________, + ___X_X__, + ________, + ________, + }, +}; diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index 4cdb5717..e8110687 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -552,3 +553,55 @@ ledscape_matrix_remap( } } } + + +extern const uint8_t fixed_font[][5]; + +void +ledscape_draw_char( + uint32_t * px, + const size_t width, + const uint32_t color, + char c +) +{ + if (c < 0x20 || c > 127) + c = '?'; + + const uint8_t* const f = fixed_font[c - 0x20]; + for (int i = 0 ; i < 5 ; i++, px++) + { + uint8_t bits = f[i]; + for (int j = 0 ; j < 7 ; j++, bits >>= 1) + px[j*width] = bits & 1 ? color : 0; + } +} + + +/** Write with a fixed-width 8px font */ +void +ledscape_printf( + uint32_t * px, + const size_t width, + const uint32_t color, + const char * fmt, + ... +) +{ + char buf[128]; + va_list ap; + va_start(ap, fmt); + int len = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + printf("%p => '%s'\n", px, buf); + for (unsigned i = 0 ; i < sizeof(buf) ; i++) + { + char c = buf[i]; + if (!c) + break; + ledscape_draw_char(px, width, color, c); + px += 6; + } +} + diff --git a/src/ledscape/ledscape.h b/src/ledscape/ledscape.h index 621b9952..0270638a 100644 --- a/src/ledscape/ledscape.h +++ b/src/ledscape/ledscape.h @@ -111,4 +111,14 @@ ledscape_matrix_remap( ); +/** Write with a fixed-width 8px font */ +void +ledscape_printf( + uint32_t * px, + const size_t width, + const uint32_t color, + const char * fmt, + ... +); + #endif diff --git a/src/ledscape/util.c b/src/ledscape/util.c index 723043b0..af90c116 100644 --- a/src/ledscape/util.c +++ b/src/ledscape/util.c @@ -17,7 +17,6 @@ #include #include #include "util.h" -#include "bitslice.h" /** Write all the bytes to a fd, even if there is a brief interruption. * \return number of bytes written or -1 on any fatal error. From d57039b478e6cd6e05d33911b633e41836d831ec Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 Apr 2014 22:12:01 +0000 Subject: [PATCH 234/332] make every binary depend on libledscape.a --- Makefile.common | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.common b/Makefile.common index 1934d667..9fb76ad3 100644 --- a/Makefile.common +++ b/Makefile.common @@ -97,7 +97,8 @@ $(LIBDIR)/%.bin: %.p $(PASM) # object files for that source. # $(foreach O,$(BIN-y),\ - $(eval $(BINDIR)/$O: $(foreach s,$($O.srcs),$(OBJDIR)/$(basename $s).o))) + $(eval $(BINDIR)/$O: $(foreach s,$($O.srcs),$(OBJDIR)/$(basename $s).o) $(LIBDIR)/libledscape.a)) + $(foreach O,$(LIB-y),\ $(eval $(LIBDIR)/$O: $(foreach s,$($(basename $O).srcs),$(OBJDIR)/$(basename $s).o))) From 191ef3df1cdb9c0f858312d960ee2e9203c44a2f Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 Apr 2014 22:30:16 +0000 Subject: [PATCH 235/332] rudimentary matrix config parser --- src/demos/fire.c | 79 +++++++++++++++++----------- src/demos/matrix-test.c | 20 +++++-- src/ledscape/Makefile | 1 + src/ledscape/config.c | 113 ++++++++++++++++++++++++++++++++++++++++ src/ledscape/ledscape.h | 6 +++ src/ledscape/matrix.p | 2 +- src/mta/mta-sign.c | 65 +++++++++++++++-------- tall-cylinder.config | 17 ++++++ 8 files changed, 246 insertions(+), 57 deletions(-) create mode 100644 src/ledscape/config.c create mode 100644 tall-cylinder.config diff --git a/src/demos/fire.c b/src/demos/fire.c index 1b8b71a3..0ca38f22 100644 --- a/src/demos/fire.c +++ b/src/demos/fire.c @@ -12,8 +12,8 @@ #include "ledscape.h" // sideways pyramid; 256 height, but 128 wide -#define width 128 -#define height 256 +#define WIDTH 128 +#define HEIGHT 256 static const int leds_width = 256; static const int leds_height = 128; @@ -83,57 +83,57 @@ hsv2rgb( // This will contain the pixels used to calculate the fire effect -static uint8_t fire[width][height]; +static uint8_t fire[WIDTH][HEIGHT]; // Flame colors static uint32_t palette[255]; static float angle; -static uint32_t calc1[width], calc2[height], calc3[width], calc4[width], calc5[height]; +static uint32_t calc1[WIDTH], calc2[HEIGHT], calc3[WIDTH], calc4[WIDTH], calc5[HEIGHT]; static void fire_draw( uint32_t * const frame ) { - memset(frame, 0, width*height*sizeof(*frame)); + memset(frame, 0, WIDTH*HEIGHT*sizeof(*frame)); angle = angle + 0.05; // Randomize the bottom row of the fire buffer - for (int x = 0; x < width; x++) + for (int x = 0; x < WIDTH; x++) { - fire[x][height-1] = random() % 190; + fire[x][HEIGHT-1] = random() % 190; } int counter = 0; // Do the fire calculations for every pixel, from top to bottom - for (int x = 0; x < width; x++) { // up to 128, leds_height - for (int y = 0; y < height; y++) { // up to 256, leds_width + for (int x = 0; x < WIDTH; x++) { // up to 128, leds_height + for (int y = 0; y < HEIGHT; y++) { // up to 256, leds_width // Add pixel values around current pixel fire[x][y] = ((fire[calc3[x]][calc2[y]] + fire[calc1[x]][calc2[y]] + fire[calc4[x]][calc2[y]] - + fire[calc1[x]][calc5[y]]) << 5) / (128+(abs(x-width/2))/4); // 129; + + fire[calc1[x]][calc5[y]]) << 5) / (128+(abs(x-WIDTH/2))/4); // 129; // Output everything to screen using our palette colors const uint32_t c = palette[fire[x][y]]; //frame[counter] = fire[x][y]; // Extract the red value using right shift and bit mask - // equivalent of red(pgTemp.pixels[x+y*width]) + // equivalent of red(pgTemp.pixels[x+y*WIDTH]) // Only map 3D cube 'lit' pixels onto fire array needed for next frame if (((c >> 0) & 0xFF) == 128) fire[x][y] = 128; // skip the bottom few rows #if 1 - if (y > height - leds_width) - frame[y - (height - leds_width) + x*leds_width] = c; + if (y > HEIGHT - leds_width) + frame[y - (HEIGHT - leds_width) + x*leds_width] = c; #else - if (x > height - leds_width) - frame[y - (height - leds_width) + x*leds_width] = c; + if (x > HEIGHT - leds_width) + frame[y - (HEIGHT - leds_width) + x*leds_width] = c; #endif //frame[(leds_width-x-1) + y*leds_height] = c; //frame[counter++] = c; @@ -149,7 +149,7 @@ sparkles( ) { for(int i = 0 ; i < num_sparkles ; i++) - frame[rand() % (width*height)] = 0xFFFFFF; + frame[rand() % (WIDTH*HEIGHT)] = 0xFFFFFF; } static int constrain( @@ -177,30 +177,45 @@ init_pallete(void) // Precalculate which pixel values to add during animation loop // this speeds up the effect by 10fps - for (int x = 0; x < width; x++) { - calc1[x] = x % width; - calc3[x] = (x - 1 + width) % width; - calc4[x] = (x + 1) % width; + for (int x = 0; x < WIDTH; x++) { + calc1[x] = x % WIDTH; + calc3[x] = (x - 1 + WIDTH) % WIDTH; + calc4[x] = (x + 1) % WIDTH; } - for (int y = 0; y < height; y++) { - calc2[y] = (y + 1) % height; - calc5[y] = (y + 2) % height; + for (int y = 0; y < HEIGHT; y++) { + calc2[y] = (y + 1) % HEIGHT; + calc5[y] = (y + 2) % HEIGHT; } } int -main(void) +main( + int argc, + const char ** argv +) { + ledscape_matrix_config_t * config = NULL; + + if (argc > 1) + { + config = ledscape_matrix_config(argv[1]); + if (!config) + return EXIT_FAILURE; + config->width = WIDTH; + config->height = HEIGHT; + } + ledscape_t * const leds = ledscape_init(leds_width,leds_height); + printf("init done\n"); time_t last_time = time(NULL); unsigned last_i = 0; unsigned i = 0; init_pallete(); - uint32_t * const p = calloc(width*height,4); + uint32_t * const p = calloc(WIDTH*HEIGHT,4); uint32_t * const fb = calloc(leds_width*leds_height,4); while (1) @@ -212,12 +227,14 @@ main(void) fire_draw(p); sparkles(p, delta); -#if 0 - framebuffer_flip(fb, p, leds_width, leds_height, width, height); - ledscape_draw(leds, fb); -#else - ledscape_draw(leds, p); -#endif + + if (config) + { + ledscape_matrix_remap(fb, p, config); + ledscape_draw(leds, fb); + } else { + ledscape_draw(leds, p); + } usleep(50000); // wait for the previous frame to finish; diff --git a/src/demos/matrix-test.c b/src/demos/matrix-test.c index 997bfd54..0fee7a78 100644 --- a/src/demos/matrix-test.c +++ b/src/demos/matrix-test.c @@ -185,8 +185,12 @@ gradient( } } + int -main(void) +main( + int argc, + const char ** argv +) { const int width = 256; const int height = 128; @@ -194,6 +198,16 @@ main(void) const int led_height = 128; ledscape_t * const leds = ledscape_init(led_width, led_height); + ledscape_matrix_config_t * config = NULL; + if (argc > 1) + { + config = ledscape_matrix_config(argv[1]); + if (!config) + return EXIT_FAILURE; + config->width = width; + config->height = height; + } + printf("init done\n"); time_t last_time = time(NULL); unsigned last_i = 0; @@ -218,9 +232,9 @@ main(void) else gradient(p, width, height, 10, i++); - if (0) + if (config) { - framebuffer_flip(led_fb, p, led_width, led_height, width, height); + ledscape_matrix_remap(led_fb, p, config); ledscape_draw(leds, led_fb); } else { ledscape_draw(leds, p); diff --git a/src/ledscape/Makefile b/src/ledscape/Makefile index 1132e28a..b9a7a0b6 100755 --- a/src/ledscape/Makefile +++ b/src/ledscape/Makefile @@ -12,6 +12,7 @@ libledscape.srcs += \ ledscape.c \ pru.c \ util.c \ + config.c \ fixed-font.c \ include ../../Makefile.common diff --git a/src/ledscape/config.c b/src/ledscape/config.c new file mode 100644 index 00000000..a5c764a8 --- /dev/null +++ b/src/ledscape/config.c @@ -0,0 +1,113 @@ +/** \file + * Parse a matrix config file. + */ +#include +#include +#include +#include +#include "ledscape.h" + + +// find the end of the line and strip the whitespace +static ssize_t +readline( + FILE * const file, + char * const buf, + const int max_len +) +{ + if (!fgets(buf, max_len, file)) + return -1; + int len = strlen(buf); + if (len >= max_len) + { + buf[max_len-1] = '\0'; + return max_len; + } + + while (len > 0) + { + const char c = buf[len-1]; + if (!isspace(c)) + break; + // strip the whitespace + buf[--len] = '\0'; + } + + printf("read %d bytes '%s'\n", len, buf); + return len; +} + + +ledscape_matrix_config_t * +ledscape_matrix_config( + const char * filename +) +{ + FILE * const file = fopen(filename, "r"); + if (!file) + { + fprintf(stderr, "%s: unable to open\n", filename); + return NULL; + } + + ledscape_matrix_config_t * const config = calloc(1, sizeof(*config)); + if (!config) + return NULL; + + char line[1024]; + int line_num = 1; + + if (readline(file, line, sizeof(line)) < 0) + goto fail; + + if (strcmp(line, "matrix16") != 0) + goto fail; + + config->panel_width = 32; + config->panel_height = 16; + config->leds_width = 256; + config->leds_height = 128; + + while (1) + { + line_num++; + if (readline(file, line, sizeof(line)) < 0) + break; + + int output, panel, x, y; + char orient; + if (sscanf(line, "%d,%d %c %d,%d", &output, &panel, &orient, &x, &y) != 5) + goto fail; + if (output > LEDSCAPE_MATRIX_OUTPUTS) + goto fail; + if (panel > LEDSCAPE_MATRIX_PANELS) + goto fail; + if (x < 0 || y < 0) + goto fail; + + ledscape_matrix_panel_t * const pconfig + = &config->panels[output][panel]; + + pconfig->x = x; + pconfig->y = y; + + switch (orient) + { + case 'N': pconfig->rot = 0; break; + case 'L': pconfig->rot = 1; break; + case 'R': pconfig->rot = 2; break; + case 'U': pconfig->rot = 3; break; + default: goto fail; + } + } + + fclose(file); + return config; + +fail: + fprintf(stderr, "%s: read or parse error on line %d\n", filename, line_num); + fclose(file); + free(config); + return NULL; +} diff --git a/src/ledscape/ledscape.h b/src/ledscape/ledscape.h index 0270638a..e43841e6 100644 --- a/src/ledscape/ledscape.h +++ b/src/ledscape/ledscape.h @@ -121,4 +121,10 @@ ledscape_printf( ... ); +/** Parse a matrix config file */ +ledscape_matrix_config_t * +ledscape_matrix_config( + const char * filename +); + #endif diff --git a/src/ledscape/matrix.p b/src/ledscape/matrix.p index b9fe7031..9b95d8ab 100644 --- a/src/ledscape/matrix.p +++ b/src/ledscape/matrix.p @@ -24,7 +24,7 @@ // higher constants == brighter. // 4 is a ok brightness, 5 is bright, 6 is powerful -#define BRIGHT_SHIFT 5 +#define BRIGHT_SHIFT 4 #define r11_gpio 2 diff --git a/src/mta/mta-sign.c b/src/mta/mta-sign.c index 4a8bd589..5c434880 100644 --- a/src/mta/mta-sign.c +++ b/src/mta/mta-sign.c @@ -99,6 +99,7 @@ font_write( } +#if 0 static ledscape_matrix_config_t ledscape_config = { // frame buffer size @@ -115,27 +116,28 @@ static ledscape_matrix_config_t ledscape_config = .panels = { [0] = { - [0] = { 0, 0, 2 }, - [1] = { 16, 0, 1 }, - [2] = { 32, 0, 2 }, - [3] = { 48, 0, 1 }, - [4] = { 64, 0, 2 }, - [5] = { 80, 0, 1 }, - [6] = { 96, 0, 2 }, - [7] = { 112, 0, 1 }, + [0] = { 0, 0, 1 }, + [1] = { 16, 0, 2 }, + [2] = { 32, 0, 1 }, + [3] = { 48, 0, 2 }, + [4] = { 64, 0, 1 }, + [5] = { 80, 0, 2 }, + [6] = { 96, 0, 1 }, + [7] = { 112, 0, 2 }, }, [1] = { - [7] = { 128, 0, 2 }, - [6] = { 144, 0, 1 }, - [5] = { 160, 0, 2 }, - [4] = { 176, 0, 1 }, - [3] = { 192, 0, 2 }, - [2] = { 208, 0, 1 }, - [1] = { 224, 0, 2 }, - [0] = { 240, 0, 1 }, + [0] = { 128, 0, 1 }, + [1] = { 144, 0, 2 }, + [2] = { 160, 0, 1 }, + [3] = { 176, 0, 2 }, + [4] = { 192, 0, 1 }, + [5] = { 208, 0, 2 }, + [6] = { 224, 0, 1 }, + [7] = { 240, 0, 2 }, }, }, }; +#endif @@ -145,8 +147,22 @@ main( char ** argv ) { + const int leds_width = 256; + const int leds_height = 128; + const int width = 256; + const int height = 32; ledscape_t * const leds - = ledscape_init(ledscape_config.leds_width, ledscape_config.leds_height); + = ledscape_init(leds_width, leds_height); + ledscape_matrix_config_t * config = NULL; + + if (argc > 1) + { + config = ledscape_matrix_config(argv[1]); + if (!config) + return EXIT_FAILURE; + config->width = width; + config->height = height; + } printf("init done\n"); @@ -154,8 +170,8 @@ main( unsigned last_i = 0; unsigned i = 0; - uint32_t * const p = calloc(ledscape_config.width*ledscape_config.height, 4); - uint32_t * const fb = calloc(ledscape_config.leds_width*ledscape_config.leds_height,4); + uint32_t * const p = calloc(width*height, 4); + uint32_t * const fb = calloc(leds_width*leds_height,4); int scroll_x = 256; while (1) @@ -164,14 +180,19 @@ main( font_write(p, 0xFF0000, 11, 0, "!"); font_write(p, 0x00FF00, 224, 0, "8min"); - int end_x = font_write(p, 0xFF4000, scroll_x, 16, argc > 1 ? argv[1] : ""); + int end_x = font_write(p, 0xFF4000, scroll_x, 16, argc > 2 ? argv[2] : ""); if (end_x <= 0) scroll_x = width; else scroll_x--; - ledscape_matrix_remap(fb, p, &ledscape_config); - ledscape_draw(leds, fb); + if (config) + { + ledscape_matrix_remap(fb, p, config); + ledscape_draw(leds, fb); + } else { + ledscape_draw(leds, p); + } usleep(20000); // wait for the previous frame to finish; diff --git a/tall-cylinder.config b/tall-cylinder.config new file mode 100644 index 00000000..8de6e6ec --- /dev/null +++ b/tall-cylinder.config @@ -0,0 +1,17 @@ +matrix16 +0,0 L 0,0 +0,1 R 16,0 +0,2 L 32,0 +0,3 R 48,0 +0,4 L 64,0 +0,5 R 80,0 +0,6 L 96,0 +0,7 R 112,0 +1,0 L 128,0 +1,1 R 144,0 +1,2 L 160,0 +1,3 R 176,0 +1,4 L 192,0 +1,5 R 208,0 +1,6 L 224,0 +1,7 R 240,0 From ae21c3c6c7f6818811ee21dc4393797478102c40 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 14 Apr 2014 00:25:23 +0000 Subject: [PATCH 236/332] use config system --- src/demos/life.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/demos/life.c b/src/demos/life.c index b0e9d1cd..61b80a23 100644 --- a/src/demos/life.c +++ b/src/demos/life.c @@ -196,10 +196,24 @@ copy_to_fb( int -main(void) +main( + int argc, + const char ** argv +) { const int leds_width = 128; const int leds_height = 256; + + ledscape_matrix_config_t * config = NULL; + if (argc > 1) + { + config = ledscape_matrix_config(argv[1]); + if (!config) + return EXIT_FAILURE; + config->width = HEIGHT; + config->height = WIDTH; + } + ledscape_t * const leds = ledscape_init(leds_width, leds_height); printf("init done\n"); time_t last_time = time(NULL); @@ -207,6 +221,7 @@ main(void) unsigned i = 0; uint32_t * const p = calloc(leds_width*leds_height,4); + uint32_t * const fb = calloc(WIDTH*HEIGHT,4); srand(getpid()); @@ -226,7 +241,13 @@ main(void) copy_to_fb(p, leds_width, leds_height, &board); - ledscape_draw(leds, p); + if (config) + { + ledscape_matrix_remap(fb, p, config); + ledscape_draw(leds, fb); + } else { + ledscape_draw(leds, p); + } usleep(1000); } From d4b58742c9690f81ea97a4c95633073a4ba7f2f6 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 14 Apr 2014 01:38:05 +0000 Subject: [PATCH 237/332] remove last deps on bitslice.h --- Makefile.common | 2 +- src/net/matrix-udp-rx.c | 1 - src/net/opc-rx.c | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Makefile.common b/Makefile.common index 9fb76ad3..e97498e1 100644 --- a/Makefile.common +++ b/Makefile.common @@ -100,7 +100,7 @@ $(foreach O,$(BIN-y),\ $(eval $(BINDIR)/$O: $(foreach s,$($O.srcs),$(OBJDIR)/$(basename $s).o) $(LIBDIR)/libledscape.a)) $(foreach O,$(LIB-y),\ - $(eval $(LIBDIR)/$O: $(foreach s,$($(basename $O).srcs),$(OBJDIR)/$(basename $s).o))) + $(eval $(LIBDIR)/$O: $(foreach s,$($(basename $O).srcs),$(OBJDIR)/$(basename $s).o) $(APP_LOADER_LIB))) #$(TARGETS): #$(COMPILE.link) diff --git a/src/net/matrix-udp-rx.c b/src/net/matrix-udp-rx.c index 691c19b0..a04e7d7e 100644 --- a/src/net/matrix-udp-rx.c +++ b/src/net/matrix-udp-rx.c @@ -22,7 +22,6 @@ #include #include #include "util.h" -#include "bitslice.h" #include "ledscape.h" diff --git a/src/net/opc-rx.c b/src/net/opc-rx.c index c6a46794..d4987439 100644 --- a/src/net/opc-rx.c +++ b/src/net/opc-rx.c @@ -17,7 +17,6 @@ #include #include #include "util.h" -#include "bitslice.h" #include "ledscape.h" typedef struct From 87400e279303b6edc65e2279083f9ceedc767e9b Mon Sep 17 00:00:00 2001 From: root Date: Mon, 14 Apr 2014 01:46:26 +0000 Subject: [PATCH 238/332] empty dir files --- lib/.empty | 0 obj/.empty | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 lib/.empty create mode 100644 obj/.empty diff --git a/lib/.empty b/lib/.empty new file mode 100644 index 00000000..e69de29b diff --git a/obj/.empty b/obj/.empty new file mode 100644 index 00000000..e69de29b From 96dcad3a9b7d0a78dabce15630e53ca639ab04bf Mon Sep 17 00:00:00 2001 From: root Date: Mon, 14 Apr 2014 02:27:59 +0000 Subject: [PATCH 239/332] abort if a subdir fails --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 44465096..9d977c5e 100755 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ SUBDIR-y += src/net all: for dir in $(SUBDIR-y); do \ - $(MAKE) -C $$dir; \ + $(MAKE) -C $$dir || exit 1; \ done clean: From a1d732dd3e84143dfb561382d11111f60d1afb63 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 14 Apr 2014 22:48:54 +0000 Subject: [PATCH 240/332] top half of single pass remapping works --- default.config | 17 +++ src/demos/Makefile | 6 +- src/demos/identify.c | 13 +- src/demos/matrix-test.c | 20 +-- src/ledscape/config.c | 101 +++++++++++--- src/ledscape/ledscape.c | 290 ++++++++++++++++++++++++---------------- src/ledscape/ledscape.h | 28 +++- 7 files changed, 317 insertions(+), 158 deletions(-) create mode 100644 default.config diff --git a/default.config b/default.config new file mode 100644 index 00000000..617fac21 --- /dev/null +++ b/default.config @@ -0,0 +1,17 @@ +matrix16 +0,0 N 0,0 +0,1 N 32,0 +0,2 N 64,0 +0,3 N 96,0 +0,4 N 128,0 +0,5 N 160,0 +0,6 N 192,0 +0,7 N 224,0 +1,0 N 0,16 +1,1 N 32,16 +1,2 N 64,16 +1,3 N 96,16 +1,4 N 128,16 +1,5 N 160,16 +1,6 N 192,16 +1,7 N 224,16 diff --git a/src/demos/Makefile b/src/demos/Makefile index 5d23ac93..131f7ef3 100755 --- a/src/demos/Makefile +++ b/src/demos/Makefile @@ -3,9 +3,9 @@ # Build the various demos # # -BIN-y += fire -BIN-y += life -BIN-y += cube-life +BIN-n += fire +BIN-n += life +BIN-n += cube-life BIN-y += matrix-test BIN-y += identify diff --git a/src/demos/identify.c b/src/demos/identify.c index 3c8e89d4..dc58d847 100644 --- a/src/demos/identify.c +++ b/src/demos/identify.c @@ -108,14 +108,21 @@ main( for (int x = 0 ; x < 256 ; x += 32) { - for (int y = 0 ; y < 128 ; y += 8) + for (int y = 0 ; y < 128 ; y += 16) { ledscape_printf( &p[x + width*y], width, 0xFF0000, - "%d,%d", - x, + "x=%d", + x + ); + + ledscape_printf( + &p[x + width*(y+8)], + width, + 0xFF0000, + "y=%d", y ); } diff --git a/src/demos/matrix-test.c b/src/demos/matrix-test.c index 0fee7a78..ebce00ee 100644 --- a/src/demos/matrix-test.c +++ b/src/demos/matrix-test.c @@ -196,18 +196,19 @@ main( const int height = 128; const int led_width = 256; const int led_height = 128; - ledscape_t * const leds = ledscape_init(led_width, led_height); - ledscape_matrix_config_t * config = NULL; + ledscape_config_t * config = NULL; if (argc > 1) { - config = ledscape_matrix_config(argv[1]); + config = ledscape_config(argv[1]); if (!config) return EXIT_FAILURE; - config->width = width; - config->height = height; + config->matrix_config.width = width; + config->matrix_config.height = height; } + ledscape_t * const leds = ledscape_init(config); + printf("init done\n"); time_t last_time = time(NULL); unsigned last_i = 0; @@ -223,7 +224,6 @@ main( unsigned i = 0; uint32_t * const p = calloc(width*height,4); - uint32_t * const led_fb = calloc(led_width*led_height,4); while (1) { @@ -232,13 +232,7 @@ main( else gradient(p, width, height, 10, i++); - if (config) - { - ledscape_matrix_remap(led_fb, p, config); - ledscape_draw(leds, led_fb); - } else { - ledscape_draw(leds, p); - } + ledscape_draw(leds, p); usleep(20000); diff --git a/src/ledscape/config.c b/src/ledscape/config.c index a5c764a8..fb3e681b 100644 --- a/src/ledscape/config.c +++ b/src/ledscape/config.c @@ -39,36 +39,27 @@ readline( } -ledscape_matrix_config_t * +ledscape_config_t * ledscape_matrix_config( - const char * filename + const char * const filename, + FILE * const file ) { - FILE * const file = fopen(filename, "r"); - if (!file) - { - fprintf(stderr, "%s: unable to open\n", filename); - return NULL; - } - - ledscape_matrix_config_t * const config = calloc(1, sizeof(*config)); - if (!config) + ledscape_config_t * const config_union + = calloc(1, sizeof(*config_union)); + if (!config_union) return NULL; + ledscape_matrix_config_t * const config = &config_union->matrix_config; - char line[1024]; - int line_num = 1; - - if (readline(file, line, sizeof(line)) < 0) - goto fail; - - if (strcmp(line, "matrix16") != 0) - goto fail; - + config->type = LEDSCAPE_MATRIX; config->panel_width = 32; config->panel_height = 16; config->leds_width = 256; config->leds_height = 128; + char line[1024]; + int line_num = 1; + while (1) { line_num++; @@ -103,7 +94,7 @@ ledscape_matrix_config( } fclose(file); - return config; + return config_union; fail: fprintf(stderr, "%s: read or parse error on line %d\n", filename, line_num); @@ -111,3 +102,71 @@ ledscape_matrix_config( free(config); return NULL; } + + +ledscape_config_t * +ledscape_strip_config( + const char * const filename, + FILE * const file +) +{ + ledscape_config_t * const config_union + = calloc(1, sizeof(*config_union)); + if (!config_union) + return NULL; + ledscape_strip_config_t * const config = &config_union->strip_config; + + config->type = LEDSCAPE_STRIP; + + char line[1024]; + int line_num = 2; + + if (readline(file, line, sizeof(line)) < 0) + goto fail; + + // maybe do this better to handle mappings + int width, height; + if (sscanf(line, "%d,%d", &width, &height) != 2) + goto fail; + config->leds_width = width; + config->leds_height = height; + + return config_union; + +fail: + fprintf(stderr, "%s: line %d: parse error\n", filename, line_num); + +} + + +ledscape_config_t * +ledscape_config( + const char * filename +) +{ + FILE * const file = fopen(filename, "r"); + if (!file) + { + fprintf(stderr, "%s: unable to open\n", filename); + return NULL; + } + + char line[1024]; + + if (readline(file, line, sizeof(line)) < 0) + goto fail; + + if (strcmp(line, "matrix16") == 0) + return ledscape_matrix_config(filename, file); + if (strcmp(line, "ws2812") == 0) + return ledscape_strip_config(filename, file); + + fprintf(stderr, "%s: unknown output type '%s'\n", filename, line); + fclose(file); + return NULL; + +fail: + fclose(file); + return NULL; +} + diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index e8110687..5fa0106d 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -92,6 +92,7 @@ typedef struct volatile unsigned response; } __attribute__((__packed__)) ws281x_command_t; +#if 0 typedef struct { uint32_t x_offset; @@ -106,6 +107,7 @@ typedef struct uint32_t matrix_height; // number of rows per-output (8 or 16) led_matrix_t matrix[NUM_MATRIX]; } led_matrix_config_t; +#endif @@ -116,7 +118,7 @@ struct ledscape unsigned width; unsigned height; unsigned frame_size; - led_matrix_config_t * matrix; + ledscape_config_t * config; }; @@ -153,7 +155,7 @@ ledscape_remap( unsigned y ) { -#define CONFIG_ZIGZAG +#undef CONFIG_ZIGZAG #ifdef CONFIG_ZIGZAG (void) leds; @@ -179,11 +181,72 @@ ledscape_remap( return &frame[(panel_num*128 + panel_offset)*48*3 + output_line]; #else + (void) leds; return &frame[x*48*3 + y]; #endif } +/** Copy a 16x32 region from in to a 32x16 region of out. + * If rot == 0, rotate -90, else rotate +90. + */ +static void +ledscape_matrix_panel_copy( + uint8_t * const out, + const uint32_t * const in, + const ledscape_matrix_config_t * const config, + const int rot +) +{ + const size_t row_stride = LEDSCAPE_MATRIX_OUTPUTS*2*3; + const size_t row_len = config->leds_width*row_stride; + + for (int x = 0 ; x < config->panel_width ; x++) + { + for (int y = 0 ; y < config->panel_height/2 ; y++) + { + int ix, iy; + if (rot == 0) + { + // no rotation == (0,0) => (0,0) + ix = x; + iy = y; + } else + if (rot == 1) + { + // rotate +90 (0,0) => (0,15) + ix = config->panel_height-1 - y; + iy = x; + } else + if (rot == 2) + { + // rotate -90 (0,0) => (31,0) + ix = y; + iy = config->panel_width-1 - x; + } else + if (rot == 3) + { + // flip == (0,0) => (31,15) + ix = config->panel_width-1 - x; + iy = config->panel_height-1 - y; + } else + { + // barf + ix = iy = 0; + } + + const uint32_t * const col_ptr = &in[ix + config->width*iy]; + const uint32_t col = *col_ptr; + uint8_t * const pix = &out[x*row_stride + y*row_len]; + pix[0] = (col >> 16) & 0xFF; + pix[1] = (col >> 8) & 0xFF; + pix[2] = (col >> 0) & 0xFF; + //printf("%d,%d => %p %p %08x\n", x, y, pix, col_ptr, col); + } + } +} + + static void ledscape_matrix_draw( ledscape_t * const leds, @@ -194,32 +257,94 @@ ledscape_matrix_draw( const uint32_t * const in = buffer; uint8_t * const out = leds->pru->ddr + leds->frame_size * frame; - // matrix packed is: + // matrix is re-packed such that a 6-byte read will bring in + // the brightness values for all six outputs of a given panel. + // this means that the rows stride 16 * 3 pixels at a time. + // // this way the PRU can read all sixteen output pixels in // one LBBO and clock them out. - // there is an array of NUM_MATRIX output coordinates (one for each of - // the sixteen drivers). - for (unsigned i = 0 ; i < NUM_MATRIX ; i++) + // while there are eight output chains, there are two simultaneous + // per output chain. + const ledscape_matrix_config_t * const config + = &leds->config->matrix_config; + + for (unsigned i = 0 ; i < LEDSCAPE_MATRIX_OUTPUTS ; i++) { - const led_matrix_t * const m = &leds->matrix->matrix[i]; + for (unsigned j = 0 ; j < LEDSCAPE_MATRIX_PANELS ; j++) + { + const ledscape_matrix_panel_t * const panel + = &config->panels[i][j]; + + //int ox = config->panel_width * j; + //int oy = config->panel_height * i; + + //printf("%d,%d => %d,%d <= %d,%d,%d\n", i, j, ox, oy, panel->x, panel->y, panel->rot); + + // the start of the panel in the input + // is defined by the panel's xy coordinate + // and the width of the input image. + const uint32_t * const ip + = &in[panel->x + panel->y * config->width]; + + // the start of the panel's output is defined + // by the current output panel number and the total + // number of panels in the chain. + // 0,0 => 0+0 + // 0,1 => 0+panel->width * 16 * 3 + // 1,0 => 6+0 + // 1,1 => 6+panel->width * 16 * 3 + uint8_t * const op + = &out[6*i + j*config->panel_width*2*3*LEDSCAPE_MATRIX_OUTPUTS]; + + ledscape_matrix_panel_copy( + op, + ip, + config, + panel->rot + ); + } + +#if 0 + // copy the top half of the panel + for (unsigned y = 0 ; y < config->panel_height/2 ; y++) + { + const uint32_t * const in_row + = &in[(y+y_off) * config->leds_width]; + + uint8_t * const out_row + = &out[y * 3 * 2 * LEDSCAPE_MATRIX_OUTPUTS * config->leds_width]; - for (uint32_t y = 0 ; y < leds->matrix->matrix_height ; y++) + for (uint32_t x = 0 ; x < config->leds_width ; x++) + { + const uint8_t * const rgb = (const void*) &in_row[x]; + uint8_t * const out_rgb = &out_row[(i*2 + x * LEDSCAPE_MATRIX_OUTPUTS*2)*3]; + out_rgb[0] = bright_map(rgb[0]); + out_rgb[1] = bright_map(rgb[1]); + out_rgb[2] = bright_map(rgb[2]); + } + } + + // copy the bottom half of the panel + for (unsigned y = config->panel_height/2 ; y < config->panel_height; y++) { const uint32_t * const in_row - = &in[(y+m->y_offset) * leds->width]; + = &in[(y+y_off) * config->leds_width]; + uint8_t * const out_row - = &out[y * leds->matrix->matrix_width * 3 * NUM_MATRIX]; + = &out[((y-config->panel_height/2) * 3 * 2 * LEDSCAPE_MATRIX_OUTPUTS + 1) * config->leds_width]; - for (uint32_t x = 0 ; x < leds->matrix->matrix_width ; x++) + for (uint32_t x = 0 ; x < config->leds_width ; x++) { - const uint8_t * const rgb = (const void*) &in_row[x + m->x_offset]; - uint8_t * const out_rgb = &out_row[(i + x * NUM_MATRIX)*3]; + const uint8_t * const rgb = (const void*) &in_row[x]; + uint8_t * const out_rgb = &out_row[(i*2 + x * LEDSCAPE_MATRIX_OUTPUTS*2)*3]; out_rgb[0] = bright_map(rgb[0]); out_rgb[1] = bright_map(rgb[1]); out_rgb[2] = bright_map(rgb[2]); } } +#endif } + leds->ws281x->pixels_dma = leds->pru->ddr_addr + leds->frame_size * frame; // disable double buffering for now //frame = (frame + 1) & 1; @@ -292,57 +417,27 @@ ledscape_wait( static ledscape_t * ledscape_matrix_init( - unsigned width, - unsigned height + ledscape_config_t * const config_union ) { + ledscape_matrix_config_t * const config = &config_union->matrix_config; pru_t * const pru = pru_init(0); - const size_t frame_size = 16 * 8 * width * 3; //LEDSCAPE_NUM_STRIPS * 4; + const size_t frame_size = config->panel_width * config->panel_height * 3 * LEDSCAPE_MATRIX_OUTPUTS * LEDSCAPE_MATRIX_PANELS; ledscape_t * const leds = calloc(1, sizeof(*leds)); *leds = (ledscape_t) { + .config = config_union, .pru = pru, - .width = width, - .height = height, + .width = config->leds_width, + .height = config->leds_height, .ws281x = pru->data_ram, .frame_size = frame_size, - .matrix = calloc(sizeof(*leds->matrix), 1), - }; - - *(leds->matrix) = (led_matrix_config_t) { - .matrix_width = 256, - .matrix_height = 8, - .matrix = { - { 0, 0 }, - { 0, 8 }, - - { 0, 16 }, - { 0, 24 }, - - { 0, 32 }, - { 0, 40 }, - - { 0, 48 }, - { 0, 56 }, - - { 0, 64 }, - { 0, 72 }, - - { 0, 80 }, - { 0, 88 }, - - { 0, 96 }, - { 0, 104 }, - - { 0, 112 }, - { 0, 120 }, - }, }; *(leds->ws281x) = (ws281x_command_t) { .pixels_dma = 0, // will be set in draw routine - .num_pixels = (leds->matrix->matrix_width * 3) * 16, + .num_pixels = (config->leds_width * 3) * 16, .command = 0, .response = 0, }; @@ -364,13 +459,13 @@ ledscape_matrix_init( static ledscape_t * -ledscape_strips_init( - unsigned width, - unsigned height +ledscape_strip_init( + ledscape_config_t * const config_union ) { + ledscape_strip_config_t * const config = &config_union->strip_config; pru_t * const pru = pru_init(0); - const size_t frame_size = 48 * width * 8 * 3; + const size_t frame_size = 48 * config->leds_width * 8 * 3; printf("frame-size %zu, ddr-size=%zu\n", frame_size, pru->ddr_size); #if 0 @@ -385,17 +480,16 @@ ledscape_strips_init( *leds = (ledscape_t) { .pru = pru, - .width = width, - .height = height, + .width = config->leds_width, + .height = config->leds_height, .ws281x = pru->data_ram, .frame_size = frame_size, - .matrix = calloc(sizeof(*leds->matrix), 1), }; // LED strips, not matrix output *(leds->ws281x) = (ws281x_command_t) { .pixels_dma = 0, // will be set in draw routine - .num_pixels = width * 8, // panel height + .num_pixels = config->leds_width * 8, // panel height .command = 0, .response = 0, }; @@ -420,11 +514,19 @@ ledscape_strips_init( ledscape_t * ledscape_init( - unsigned width, - unsigned height + ledscape_config_t * const config ) { - return ledscape_matrix_init(width, height); + switch (config->type) + { + case LEDSCAPE_MATRIX: + return ledscape_matrix_init(config); + case LEDSCAPE_STRIP: + return ledscape_strip_init(config); + default: + fprintf(stderr, "unknown config type %d\n", config->type); + return NULL; + } } @@ -434,7 +536,18 @@ ledscape_draw( const void * const buffer ) { - return ledscape_matrix_draw(leds, buffer); + switch (leds->config->type) + { + case LEDSCAPE_MATRIX: + ledscape_matrix_draw(leds, buffer); + break; + case LEDSCAPE_STRIP: + ledscape_strip_draw(leds, buffer); + break; + default: + fprintf(stderr, "unknown config type %d\n", leds->config->type); + break; + } } @@ -467,58 +580,8 @@ ledscape_set_color( -/** Copy a 16x32 region from in to a 32x16 region of out. - * If rot == 0, rotate -90, else rotate +90. - */ -static void -ledscape_matrix_panel_copy( - uint32_t * const out, - const uint32_t * const in, - const ledscape_matrix_config_t * const config, - const int rot -) -{ - for (int x = 0 ; x < config->panel_width ; x++) - { - for (int y = 0 ; y < config->panel_height ; y++) - { - int ox, oy; - if (rot == 0) - { - // no rotation == (0,0) => (0,0) - ox = x; - oy = y; - } else - if (rot == 1) - { - // rotate +90 (0,0) => (0,15) - ox = config->panel_height-1 - y; - oy = x; - } else - if (rot == 2) - { - // rotate -90 (0,0) => (31,0) - ox = y; - oy = config->panel_width-1 - x; - } else - if (rot == 3) - { - // flip == (0,0) => (31,15) - ox = config->panel_width-1 - x; - oy = config->panel_height-1 - y; - } else - { - // barf - ox = oy = 0; - } - - out[x + config->leds_width*y] - = in[ox + config->width*oy]; - } - } -} - +#if 0 /** Remap the matrix framebuffer based on the config. */ void @@ -553,6 +616,7 @@ ledscape_matrix_remap( } } } +#endif extern const uint8_t fixed_font[][5]; diff --git a/src/ledscape/ledscape.h b/src/ledscape/ledscape.h index e43841e6..34a06654 100644 --- a/src/ledscape/ledscape.h +++ b/src/ledscape/ledscape.h @@ -17,6 +17,9 @@ */ #define LEDSCAPE_NUM_STRIPS 32 +#define LEDSCAPE_MATRIX 1 +#define LEDSCAPE_STRIP 2 + typedef struct { int x; @@ -28,6 +31,7 @@ typedef struct { #define LEDSCAPE_MATRIX_PANELS 8 // number of panels chained per output typedef struct { + int type; int width; int height; int panel_width; @@ -38,6 +42,20 @@ typedef struct { } ledscape_matrix_config_t; +typedef struct { + int type; + int leds_width; // length of the longest strip + int leds_height; // number of output strips +} ledscape_strip_config_t; + + +typedef union { + int type; + ledscape_matrix_config_t matrix_config; + ledscape_strip_config_t strip_config; +} ledscape_config_t; + + /** LEDscape pixel format is BRGA. * * data is laid out with BRGA format, since that is how it will @@ -67,8 +85,7 @@ typedef struct ledscape ledscape_t; extern ledscape_t * ledscape_init( - unsigned width, - unsigned height + ledscape_config_t * config ); @@ -121,9 +138,10 @@ ledscape_printf( ... ); -/** Parse a matrix config file */ -ledscape_matrix_config_t * -ledscape_matrix_config( + +/** Parse a config file */ +ledscape_config_t * +ledscape_config( const char * filename ); From db29360c224e3beabb90ab42698ab4b110961dde Mon Sep 17 00:00:00 2001 From: root Date: Mon, 14 Apr 2014 22:58:09 +0000 Subject: [PATCH 241/332] removed dead code in matrix draw --- src/ledscape/ledscape.c | 109 +++++++--------------------------------- 1 file changed, 17 insertions(+), 92 deletions(-) diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index 5fa0106d..d34ecfc6 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -191,7 +191,7 @@ ledscape_remap( * If rot == 0, rotate -90, else rotate +90. */ static void -ledscape_matrix_panel_copy( +ledscape_matrix_panel_copy_half( uint8_t * const out, const uint32_t * const in, const ledscape_matrix_config_t * const config, @@ -268,6 +268,8 @@ ledscape_matrix_draw( const ledscape_matrix_config_t * const config = &leds->config->matrix_config; + const size_t panel_stride = config->panel_width*2*3*LEDSCAPE_MATRIX_OUTPUTS; + for (unsigned i = 0 ; i < LEDSCAPE_MATRIX_OUTPUTS ; i++) { for (unsigned j = 0 ; j < LEDSCAPE_MATRIX_PANELS ; j++) @@ -275,74 +277,35 @@ ledscape_matrix_draw( const ledscape_matrix_panel_t * const panel = &config->panels[i][j]; - //int ox = config->panel_width * j; - //int oy = config->panel_height * i; - - //printf("%d,%d => %d,%d <= %d,%d,%d\n", i, j, ox, oy, panel->x, panel->y, panel->rot); - // the start of the panel in the input // is defined by the panel's xy coordinate // and the width of the input image. const uint32_t * const ip - = &in[panel->x + panel->y * config->width]; + = &in[panel->x + panel->y*config->width]; // the start of the panel's output is defined // by the current output panel number and the total // number of panels in the chain. - // 0,0 => 0+0 - // 0,1 => 0+panel->width * 16 * 3 - // 1,0 => 6+0 - // 1,1 => 6+panel->width * 16 * 3 - uint8_t * const op - = &out[6*i + j*config->panel_width*2*3*LEDSCAPE_MATRIX_OUTPUTS]; + uint8_t * const op = &out[6*i + j*panel_stride]; - ledscape_matrix_panel_copy( + // copy the top half of this matrix + ledscape_matrix_panel_copy_half( op, ip, config, panel->rot ); - } - -#if 0 - // copy the top half of the panel - for (unsigned y = 0 ; y < config->panel_height/2 ; y++) - { - const uint32_t * const in_row - = &in[(y+y_off) * config->leds_width]; - uint8_t * const out_row - = &out[y * 3 * 2 * LEDSCAPE_MATRIX_OUTPUTS * config->leds_width]; - - for (uint32_t x = 0 ; x < config->leds_width ; x++) - { - const uint8_t * const rgb = (const void*) &in_row[x]; - uint8_t * const out_rgb = &out_row[(i*2 + x * LEDSCAPE_MATRIX_OUTPUTS*2)*3]; - out_rgb[0] = bright_map(rgb[0]); - out_rgb[1] = bright_map(rgb[1]); - out_rgb[2] = bright_map(rgb[2]); - } - } - - // copy the bottom half of the panel - for (unsigned y = config->panel_height/2 ; y < config->panel_height; y++) - { - const uint32_t * const in_row - = &in[(y+y_off) * config->leds_width]; - - uint8_t * const out_row - = &out[((y-config->panel_height/2) * 3 * 2 * LEDSCAPE_MATRIX_OUTPUTS + 1) * config->leds_width]; - - for (uint32_t x = 0 ; x < config->leds_width ; x++) - { - const uint8_t * const rgb = (const void*) &in_row[x]; - uint8_t * const out_rgb = &out_row[(i*2 + x * LEDSCAPE_MATRIX_OUTPUTS*2)*3]; - out_rgb[0] = bright_map(rgb[0]); - out_rgb[1] = bright_map(rgb[1]); - out_rgb[2] = bright_map(rgb[2]); - } + // and the bottom half, which is stored next in + // the output bitstream, but occurs half a panel + // height later in the input image. + ledscape_matrix_panel_copy_half( + op + 3, + ip + config->width*config->panel_height/2, + config, + panel->rot + ); } -#endif } leds->ws281x->pixels_dma = leds->pru->ddr_addr + leds->frame_size * frame; @@ -415,6 +378,7 @@ ledscape_wait( } } + static ledscape_t * ledscape_matrix_init( ledscape_config_t * const config_union @@ -580,45 +544,6 @@ ledscape_set_color( - -#if 0 -/** Remap the matrix framebuffer based on the config. - */ -void -ledscape_matrix_remap( - uint32_t * const out, - const uint32_t * const in, - const ledscape_matrix_config_t * const config -) -{ - for (int i = 0 ; i < LEDSCAPE_MATRIX_OUTPUTS ; i++) - { - for (int j = 0 ; j < LEDSCAPE_MATRIX_PANELS ; j++) - { - const ledscape_matrix_panel_t * const panel - = &config->panels[i][j]; - - int ox = config->panel_width * j; - int oy = config->panel_height * i; - //printf("%d,%d => %d,%d <= %d,%d,%d\n", i, j, ox, oy, panel->x, panel->y, panel->rot); - - const uint32_t * const ip - = &in[panel->x + panel->y * config->width]; - uint32_t * const op - = &out[ox + oy * config->leds_width]; - - ledscape_matrix_panel_copy( - op, - ip, - config, - panel->rot - ); - } - } -} -#endif - - extern const uint8_t fixed_font[][5]; void From eedcc3fc55efbc9bd48efa5aadb0cd7a3a90742c Mon Sep 17 00:00:00 2001 From: root Date: Mon, 14 Apr 2014 23:07:39 +0000 Subject: [PATCH 242/332] added default matrix config --- src/demos/identify.c | 2 +- src/ledscape/ledscape.c | 35 +++++++++++++++++++++++++++++++++++ src/ledscape/ledscape.h | 2 ++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/demos/identify.c b/src/demos/identify.c index dc58d847..5e86e54b 100644 --- a/src/demos/identify.c +++ b/src/demos/identify.c @@ -95,7 +95,7 @@ main( char ** argv ) { - ledscape_t * const leds = ledscape_init(width, height); + ledscape_t * const leds = ledscape_init(&ledscape_matrix_default); printf("init done\n"); time_t last_time = time(NULL); diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index d34ecfc6..10bbd3da 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -582,6 +582,7 @@ ledscape_printf( va_start(ap, fmt); int len = vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); + (void) len; printf("%p => '%s'\n", px, buf); for (unsigned i = 0 ; i < sizeof(buf) ; i++) @@ -594,3 +595,37 @@ ledscape_printf( } } + +/** Default ledscape config */ +#define DEFAULT_MATRIX(i) { \ + { 0*16, i*16, 0 }, \ + { 1*16, i*16, 0 }, \ + { 2*16, i*16, 0 }, \ + { 3*16, i*16, 0 }, \ + { 4*16, i*16, 0 }, \ + { 5*16, i*16, 0 }, \ + { 6*16, i*16, 0 }, \ + { 7*16, i*16, 0 }, \ + } \ + +ledscape_config_t ledscape_matrix_default = { + .matrix_config = { + .type = LEDSCAPE_MATRIX, + .width = 256, + .height = 18, + .panel_width = 32, + .panel_height = 16, + .leds_width = 256, + .leds_height = 128, + .panels = { + DEFAULT_MATRIX(0), + DEFAULT_MATRIX(1), + DEFAULT_MATRIX(2), + DEFAULT_MATRIX(3), + DEFAULT_MATRIX(4), + DEFAULT_MATRIX(5), + DEFAULT_MATRIX(6), + DEFAULT_MATRIX(7), + }, + }, +}; diff --git a/src/ledscape/ledscape.h b/src/ledscape/ledscape.h index 34a06654..5267bb36 100644 --- a/src/ledscape/ledscape.h +++ b/src/ledscape/ledscape.h @@ -83,6 +83,8 @@ typedef struct { typedef struct ledscape ledscape_t; +extern ledscape_config_t ledscape_matrix_default; + extern ledscape_t * ledscape_init( ledscape_config_t * config From 64fb1e07cfc2f580d91b9ff496fcec9db17f0272 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 14 Apr 2014 23:14:30 +0000 Subject: [PATCH 243/332] default matrix config --- src/demos/matrix-test.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/demos/matrix-test.c b/src/demos/matrix-test.c index ebce00ee..2f867df8 100644 --- a/src/demos/matrix-test.c +++ b/src/demos/matrix-test.c @@ -197,16 +197,17 @@ main( const int led_width = 256; const int led_height = 128; - ledscape_config_t * config = NULL; + ledscape_config_t * config = &ledscape_matrix_default; if (argc > 1) { config = ledscape_config(argv[1]); if (!config) return EXIT_FAILURE; - config->matrix_config.width = width; - config->matrix_config.height = height; } + config->matrix_config.width = width; + config->matrix_config.height = height; + ledscape_t * const leds = ledscape_init(config); printf("init done\n"); From bc6fb5f3a067ef5a07e2daef38af56d10e5d838e Mon Sep 17 00:00:00 2001 From: root Date: Mon, 14 Apr 2014 23:21:04 +0000 Subject: [PATCH 244/332] off-by-16 error --- src/ledscape/ledscape.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index 10bbd3da..2d734323 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -598,14 +598,14 @@ ledscape_printf( /** Default ledscape config */ #define DEFAULT_MATRIX(i) { \ - { 0*16, i*16, 0 }, \ - { 1*16, i*16, 0 }, \ - { 2*16, i*16, 0 }, \ - { 3*16, i*16, 0 }, \ - { 4*16, i*16, 0 }, \ - { 5*16, i*16, 0 }, \ - { 6*16, i*16, 0 }, \ - { 7*16, i*16, 0 }, \ + { 0*32, i*16, 0 }, \ + { 1*32, i*16, 0 }, \ + { 2*32, i*16, 0 }, \ + { 3*32, i*16, 0 }, \ + { 4*32, i*16, 0 }, \ + { 5*32, i*16, 0 }, \ + { 6*32, i*16, 0 }, \ + { 7*32, i*16, 0 }, \ } \ ledscape_config_t ledscape_matrix_default = { From 829bc6f7d8d19dc41f56d952656583d119207e25 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 14 Apr 2014 23:57:53 +0000 Subject: [PATCH 245/332] include all panel outputs --- default.config | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/default.config b/default.config index 617fac21..8b00ac5c 100644 --- a/default.config +++ b/default.config @@ -15,3 +15,51 @@ matrix16 1,5 N 160,16 1,6 N 192,16 1,7 N 224,16 +2,0 N 0,32 +2,1 N 32,32 +2,2 N 64,32 +2,3 N 96,32 +2,4 N 128,32 +2,5 N 160,32 +2,6 N 192,32 +2,7 N 224,32 +3,0 N 0,48 +3,1 N 32,48 +3,2 N 64,48 +3,3 N 96,48 +3,4 N 128,48 +3,5 N 160,48 +3,6 N 192,48 +3,7 N 224,48 +4,0 N 0,64 +4,1 N 32,64 +4,2 N 64,64 +4,3 N 96,64 +4,4 N 128,64 +4,5 N 160,64 +4,6 N 192,64 +4,7 N 224,64 +5,0 N 0,80 +5,1 N 32,80 +5,2 N 64,80 +5,3 N 96,80 +5,4 N 128,80 +5,5 N 160,80 +5,6 N 192,80 +5,7 N 224,80 +6,0 N 0,96 +6,1 N 32,96 +6,2 N 64,96 +6,3 N 96,96 +6,4 N 128,96 +6,5 N 160,96 +6,6 N 192,96 +6,7 N 224,96 +7,0 N 0,112 +7,1 N 32,112 +7,2 N 64,112 +7,3 N 96,112 +7,4 N 128,112 +7,5 N 160,112 +7,6 N 192,112 +7,7 N 224,112 From 16131ad983a19c7e82224f4b432dede00c978641 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 14 Apr 2014 23:58:00 +0000 Subject: [PATCH 246/332] everything builds again --- src/demos/Makefile | 6 +-- src/demos/cube-life.c | 7 ++- src/demos/fire.c | 19 +++----- src/demos/identify.c | 101 +++++----------------------------------- src/demos/life.c | 38 +++++++-------- src/ledscape/ledscape.c | 2 +- src/mta/mta-sign.c | 69 +++------------------------ src/net/matrix-udp-rx.c | 3 +- src/net/opc-rx.c | 3 +- 9 files changed, 56 insertions(+), 192 deletions(-) diff --git a/src/demos/Makefile b/src/demos/Makefile index 131f7ef3..5d23ac93 100755 --- a/src/demos/Makefile +++ b/src/demos/Makefile @@ -3,9 +3,9 @@ # Build the various demos # # -BIN-n += fire -BIN-n += life -BIN-n += cube-life +BIN-y += fire +BIN-y += life +BIN-y += cube-life BIN-y += matrix-test BIN-y += identify diff --git a/src/demos/cube-life.c b/src/demos/cube-life.c index ebd549dd..c8eb5894 100644 --- a/src/demos/cube-life.c +++ b/src/demos/cube-life.c @@ -1,5 +1,7 @@ /** \file * Play the game of life on the matrix cube. + * + * \todo this is broken until the matrix.p can handle different heights */ #include #include @@ -375,7 +377,10 @@ main(void) { const int width = 128; const int height = 128; - ledscape_t * const leds = ledscape_init(width, height); + ledscape_config_t * const config = &ledscape_matrix_default; + config->matrix_config.panel_height = 32; + + ledscape_t * const leds = ledscape_init(config); printf("init done\n"); time_t last_time = time(NULL); unsigned last_i = 0; diff --git a/src/demos/fire.c b/src/demos/fire.c index 0ca38f22..d0c07f38 100644 --- a/src/demos/fire.c +++ b/src/demos/fire.c @@ -196,18 +196,18 @@ main( const char ** argv ) { - ledscape_matrix_config_t * config = NULL; + ledscape_matrix_config_t * config = &ledscape_matrix_default; if (argc > 1) { - config = ledscape_matrix_config(argv[1]); + config = ledscape_config(argv[1]); if (!config) return EXIT_FAILURE; - config->width = WIDTH; - config->height = HEIGHT; } - ledscape_t * const leds = ledscape_init(leds_width,leds_height); + config->width = WIDTH; + config->height = HEIGHT; + ledscape_t * const leds = ledscape_init(config); printf("init done\n"); time_t last_time = time(NULL); @@ -216,7 +216,6 @@ main( unsigned i = 0; init_pallete(); uint32_t * const p = calloc(WIDTH*HEIGHT,4); - uint32_t * const fb = calloc(leds_width*leds_height,4); while (1) { @@ -228,13 +227,7 @@ main( fire_draw(p); sparkles(p, delta); - if (config) - { - ledscape_matrix_remap(fb, p, config); - ledscape_draw(leds, fb); - } else { - ledscape_draw(leds, p); - } + ledscape_draw(leds, p); usleep(50000); // wait for the previous frame to finish; diff --git a/src/demos/identify.c b/src/demos/identify.c index 5e86e54b..0e82cb03 100644 --- a/src/demos/identify.c +++ b/src/demos/identify.c @@ -10,84 +10,6 @@ #include #include "ledscape.h" -const int width = 256; -const int height = 128; - -/* - -static int -font_write( - uint32_t * const buf, - const uint32_t color, - const int x0, - const int y0, - const char * s -) -{ - int x = x0; - int y = y0; - - while (1) - { - char c = *s++; - if (!c) - break; - - if (c == '\n') - { - x = x0; - y += 16 * width; - continue; - } - - const uint16_t * ch = font[(uint8_t) c]; - int max_width = 0; - - if (c == ' ' || c == '.') - max_width = 3; - else - for (int h = 0 ; h < 16 ; h++) - { - int width = 0; - uint16_t row = ch[h] >> 2; - while (row) - { - row >>= 1; - width++; - } - - if (width > max_width) - max_width = width; - } - - // add space after the character - max_width++; - - for (int h = 0 ; h < 16 ; h++) - { - uint16_t row = ch[h] >> 2; - for (int j = 0 ; j < max_width ; j++, row >>= 1) - { - uint32_t pixel_color = (row & 1) ? color : 0; - if (x + j >= width || x + j < 0) - continue; - if (y + h >= height || y + h < 0) - continue; - - uint8_t * pix = (uint8_t*) &buf[(y+h)*width + x + j]; - pix[0] = pixel_color >> 16; - pix[1] = pixel_color >> 8; - pix[2] = pixel_color >> 0; - } - } - - x += max_width; - } - - return x; -} -*/ - int main( @@ -95,33 +17,34 @@ main( char ** argv ) { + ledscape_matrix_config_t * const config = &ledscape_matrix_default.matrix_config; ledscape_t * const leds = ledscape_init(&ledscape_matrix_default); - printf("init done\n"); + printf("init done %d,%d\n", config->width, config->height); time_t last_time = time(NULL); unsigned last_i = 0; unsigned i = 0; - uint32_t * const p = calloc(width*height,4); + uint32_t * const p = calloc(config->width*config->height,4); int scroll_x = 128; - memset(p, 0x10, width*height*4); + memset(p, 0x10, config->width*config->height*4); - for (int x = 0 ; x < 256 ; x += 32) + for (int x = 0 ; x < config->width ; x += 32) { - for (int y = 0 ; y < 128 ; y += 16) + for (int y = 0 ; y < config->height ; y += 16) { ledscape_printf( - &p[x + width*y], - width, - 0xFF0000, + &p[x + config->width*y], + config->width, + 0x00FF00, // green "x=%d", x ); ledscape_printf( - &p[x + width*(y+8)], - width, - 0xFF0000, + &p[x + config->width*(y+8)], + config->width, + 0xFF00FF, // red "y=%d", y ); diff --git a/src/demos/life.c b/src/demos/life.c index 61b80a23..b863abc1 100644 --- a/src/demos/life.c +++ b/src/demos/life.c @@ -21,8 +21,8 @@ #define DELTA_G 30 #define DELTA_B 80 -#define WIDTH 128 -#define HEIGHT 256 +#define WIDTH 256 +#define HEIGHT 128 typedef struct { @@ -188,7 +188,14 @@ copy_to_fb( b = (b * SMOOTH_B) / (SMOOTH_B+1); } - *pix_ptr = (r << 0) | (g << 8) | (b << 16); + if (r > 255) r = 255; + if (g > 255) g = 255; + if (b > 255) b = 255; + if (r < 0) r = 0; + if (g < 0) g = 0; + if (b < 0) b = 0; + + *pix_ptr = ((r << 16) | (g << 8) | (b << 0)); } } } @@ -201,27 +208,24 @@ main( const char ** argv ) { - const int leds_width = 128; - const int leds_height = 256; - - ledscape_matrix_config_t * config = NULL; + ledscape_matrix_config_t * config = &ledscape_matrix_default; if (argc > 1) { config = ledscape_matrix_config(argv[1]); if (!config) return EXIT_FAILURE; - config->width = HEIGHT; - config->height = WIDTH; } - ledscape_t * const leds = ledscape_init(leds_width, leds_height); + config->width = WIDTH; + config->height = HEIGHT; + + ledscape_t * const leds = ledscape_init(config); printf("init done\n"); time_t last_time = time(NULL); unsigned last_i = 0; unsigned i = 0; - uint32_t * const p = calloc(leds_width*leds_height,4); - uint32_t * const fb = calloc(WIDTH*HEIGHT,4); + uint32_t * const p = calloc(config->width*config->height,4); srand(getpid()); @@ -239,15 +243,9 @@ main( play_game(&board); } - copy_to_fb(p, leds_width, leds_height, &board); + copy_to_fb(p, config->width, config->height, &board); - if (config) - { - ledscape_matrix_remap(fb, p, config); - ledscape_draw(leds, fb); - } else { - ledscape_draw(leds, p); - } + ledscape_draw(leds, p); usleep(1000); } diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index 2d734323..520441b8 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -612,7 +612,7 @@ ledscape_config_t ledscape_matrix_default = { .matrix_config = { .type = LEDSCAPE_MATRIX, .width = 256, - .height = 18, + .height = 128, .panel_width = 32, .panel_height = 16, .leds_width = 256, diff --git a/src/mta/mta-sign.c b/src/mta/mta-sign.c index 5c434880..7061bbfc 100644 --- a/src/mta/mta-sign.c +++ b/src/mta/mta-sign.c @@ -12,7 +12,7 @@ #include "ledscape.h" const int width = 256; -const int height = 32; +const int height = 128; extern const uint16_t font[][16]; @@ -99,71 +99,21 @@ font_write( } -#if 0 -static ledscape_matrix_config_t ledscape_config = -{ - // frame buffer size - .width = 256, - .height = 32, - - // panel size - .panel_width = 32, - .panel_height = 16, - - // ledscape matrix output size - .leds_width = LEDSCAPE_MATRIX_PANELS*32, // could be less - .leds_height = LEDSCAPE_MATRIX_OUTPUTS*16, - - .panels = { - [0] = { - [0] = { 0, 0, 1 }, - [1] = { 16, 0, 2 }, - [2] = { 32, 0, 1 }, - [3] = { 48, 0, 2 }, - [4] = { 64, 0, 1 }, - [5] = { 80, 0, 2 }, - [6] = { 96, 0, 1 }, - [7] = { 112, 0, 2 }, - }, - [1] = { - [0] = { 128, 0, 1 }, - [1] = { 144, 0, 2 }, - [2] = { 160, 0, 1 }, - [3] = { 176, 0, 2 }, - [4] = { 192, 0, 1 }, - [5] = { 208, 0, 2 }, - [6] = { 224, 0, 1 }, - [7] = { 240, 0, 2 }, - }, - }, -}; -#endif - - - int main( int argc, char ** argv ) { - const int leds_width = 256; - const int leds_height = 128; - const int width = 256; - const int height = 32; - ledscape_t * const leds - = ledscape_init(leds_width, leds_height); - ledscape_matrix_config_t * config = NULL; - + ledscape_config_t * config = &ledscape_matrix_default; if (argc > 1) { - config = ledscape_matrix_config(argv[1]); + config = ledscape_config(argv[1]); if (!config) return EXIT_FAILURE; - config->width = width; - config->height = height; } + ledscape_t * const leds = ledscape_init(config); printf("init done\n"); time_t last_time = time(NULL); @@ -171,8 +121,7 @@ main( unsigned i = 0; uint32_t * const p = calloc(width*height, 4); - uint32_t * const fb = calloc(leds_width*leds_height,4); - int scroll_x = 256; + int scroll_x = width; while (1) { @@ -186,13 +135,7 @@ main( else scroll_x--; - if (config) - { - ledscape_matrix_remap(fb, p, config); - ledscape_draw(leds, fb); - } else { - ledscape_draw(leds, p); - } + ledscape_draw(leds, p); usleep(20000); // wait for the previous frame to finish; diff --git a/src/net/matrix-udp-rx.c b/src/net/matrix-udp-rx.c index a04e7d7e..316dce51 100644 --- a/src/net/matrix-udp-rx.c +++ b/src/net/matrix-udp-rx.c @@ -70,7 +70,8 @@ main( fprintf(stderr, "%u x %u, UDP port %u\n", width, height, port); - ledscape_t * const leds = ledscape_init(leds_width, leds_height); + ledscape_config_t * config = &ledscape_matrix_default; + ledscape_t * const leds = ledscape_init(config); const unsigned report_interval = 10; unsigned last_report = 0; diff --git a/src/net/opc-rx.c b/src/net/opc-rx.c index d4987439..f03566a2 100644 --- a/src/net/opc-rx.c +++ b/src/net/opc-rx.c @@ -72,7 +72,8 @@ main( fprintf(stderr, "%u x %u, TCP port %u\n", width, height, port); - ledscape_t * const leds = ledscape_init(width, height); + ledscape_config_t * config = &ledscape_matrix_default; + ledscape_t * const leds = ledscape_init(config); const unsigned report_interval = 10; unsigned last_report = 0; From 0355dcabad5248fda1b88723122ac56c89311aa5 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 14 Apr 2014 23:58:16 +0000 Subject: [PATCH 247/332] comment color alignment --- src/ledscape/ledscape.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index 2d734323..21172663 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -238,9 +238,9 @@ ledscape_matrix_panel_copy_half( const uint32_t * const col_ptr = &in[ix + config->width*iy]; const uint32_t col = *col_ptr; uint8_t * const pix = &out[x*row_stride + y*row_len]; - pix[0] = (col >> 16) & 0xFF; - pix[1] = (col >> 8) & 0xFF; - pix[2] = (col >> 0) & 0xFF; + pix[0] = (col >> 16) & 0xFF; // red + pix[1] = (col >> 8) & 0xFF; // green + pix[2] = (col >> 0) & 0xFF; // blue //printf("%d,%d => %p %p %08x\n", x, y, pix, col_ptr, col); } } From 9148a2dda73a432e39cf6e97b0ab51befe141270 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 15 Apr 2014 01:32:52 +0000 Subject: [PATCH 248/332] add -g --- Makefile.common | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.common b/Makefile.common index e97498e1..775d880b 100644 --- a/Makefile.common +++ b/Makefile.common @@ -30,6 +30,7 @@ export CROSS_COMPILE?=arm-linux-gnueabi- endif CFLAGS += \ + -g \ -std=c99 \ -W \ -Wall \ From 1240d29095af1c8d8be0c75caf1e11955cd40a9c Mon Sep 17 00:00:00 2001 From: root Date: Tue, 15 Apr 2014 01:33:10 +0000 Subject: [PATCH 249/332] change colors, allow config --- src/demos/identify.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/demos/identify.c b/src/demos/identify.c index 0e82cb03..fd820993 100644 --- a/src/demos/identify.c +++ b/src/demos/identify.c @@ -17,33 +17,43 @@ main( char ** argv ) { - ledscape_matrix_config_t * const config = &ledscape_matrix_default.matrix_config; - ledscape_t * const leds = ledscape_init(&ledscape_matrix_default); + ledscape_config_t * config = &ledscape_matrix_default; + if (argc > 1) + { + config = ledscape_config(argv[1]); + if (!config) + return EXIT_FAILURE; + } + + ledscape_t * const leds = ledscape_init(config); + + const int width = 256; + const int height = 128; - printf("init done %d,%d\n", config->width, config->height); + //printf("init done %d,%d\n", width, height); time_t last_time = time(NULL); unsigned last_i = 0; unsigned i = 0; - uint32_t * const p = calloc(config->width*config->height,4); + uint32_t * const p = calloc(width*height,4); int scroll_x = 128; - memset(p, 0x10, config->width*config->height*4); + memset(p, 0x10, width*height*4); - for (int x = 0 ; x < config->width ; x += 32) + for (int x = 0 ; x < width ; x += 32) { - for (int y = 0 ; y < config->height ; y += 16) + for (int y = 0 ; y < height ; y += 16) { ledscape_printf( - &p[x + config->width*y], - config->width, + &p[x + width*y], + width, 0x00FF00, // green "x=%d", x ); ledscape_printf( - &p[x + config->width*(y+8)], - config->width, + &p[x + width*(y+8)], + width, 0xFF00FF, // red "y=%d", y From becec3d010d644b537d450616ab4fbcc2a9c2621 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 15 Apr 2014 01:33:31 +0000 Subject: [PATCH 250/332] fail cleanly --- src/ledscape/config.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ledscape/config.c b/src/ledscape/config.c index fb3e681b..40bf978a 100644 --- a/src/ledscape/config.c +++ b/src/ledscape/config.c @@ -131,11 +131,13 @@ ledscape_strip_config( config->leds_width = width; config->leds_height = height; + printf("strips: %d,%d\n", width, height); return config_union; fail: fprintf(stderr, "%s: line %d: parse error\n", filename, line_num); - + free(config_union); + return NULL; } From 5270a495dd91d24b1f38019bdb55a621e8fa8d90 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 15 Apr 2014 01:33:52 +0000 Subject: [PATCH 251/332] ws2812 strips work again, although first pixel is noisy --- src/ledscape/ledscape.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index a270a332..c4e55ac1 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -339,7 +339,7 @@ ledscape_strip_draw( { uint8_t * const row_out = ledscape_remap(leds, out, x, y); - const uint32_t p = row_in[x]; + uint32_t p = row_in[x]; row_out[0*pru_stride] = (p >> 8) & 0xFF; // green row_out[1*pru_stride] = (p >> 0) & 0xFF; // red row_out[2*pru_stride] = (p >> 16) & 0xFF; // blue @@ -443,9 +443,10 @@ ledscape_strip_init( ledscape_t * const leds = calloc(1, sizeof(*leds)); *leds = (ledscape_t) { + .config = config_union, .pru = pru, .width = config->leds_width, - .height = config->leds_height, + .height = 48, // only 48 are supported, config->leds_height, .ws281x = pru->data_ram, .frame_size = frame_size, }; @@ -453,12 +454,12 @@ ledscape_strip_init( // LED strips, not matrix output *(leds->ws281x) = (ws281x_command_t) { .pixels_dma = 0, // will be set in draw routine - .num_pixels = config->leds_width * 8, // panel height + .num_pixels = config->leds_width, // * leds->height, .command = 0, .response = 0, }; - printf("%d\n", leds->ws281x->num_pixels); + printf("pixels: %d\n", leds->ws281x->num_pixels); ledscape_gpio_init(); @@ -584,7 +585,7 @@ ledscape_printf( va_end(ap); (void) len; - printf("%p => '%s'\n", px, buf); + //printf("%p => '%s'\n", px, buf); for (unsigned i = 0 ; i < sizeof(buf) ; i++) { char c = buf[i]; From a43d9f8269253e72b29026965827d511947a90cd Mon Sep 17 00:00:00 2001 From: root Date: Tue, 15 Apr 2014 01:34:38 +0000 Subject: [PATCH 252/332] config cleanup --- config.txt | 6 ------ strips.config | 2 ++ 2 files changed, 2 insertions(+), 6 deletions(-) delete mode 100644 config.txt create mode 100644 strips.config diff --git a/config.txt b/config.txt deleted file mode 100644 index 91b90bc0..00000000 --- a/config.txt +++ /dev/null @@ -1,6 +0,0 @@ -9999 # UDP port number -64,210 # width,height in pixels (only 32 of the width are on this machine) -14401,0 -14389,8,1:1,2:3,3:3,4:4 -8987,16,1:4,2:3,3:2 -8998,24,4:4 diff --git a/strips.config b/strips.config new file mode 100644 index 00000000..54779db2 --- /dev/null +++ b/strips.config @@ -0,0 +1,2 @@ +ws2812 +64,48 From 34b2d418e593e6f7a5348cd29c954c1ab58ec1d1 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 15 Apr 2014 21:44:11 +0000 Subject: [PATCH 253/332] resize for strip test --- src/demos/matrix-test.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/demos/matrix-test.c b/src/demos/matrix-test.c index 2f867df8..343ccf0d 100644 --- a/src/demos/matrix-test.c +++ b/src/demos/matrix-test.c @@ -192,10 +192,8 @@ main( const char ** argv ) { - const int width = 256; - const int height = 128; - const int led_width = 256; - const int led_height = 128; + int width = 64; // 256; + int height = 48; //128; ledscape_config_t * config = &ledscape_matrix_default; if (argc > 1) @@ -205,11 +203,12 @@ main( return EXIT_FAILURE; } - config->matrix_config.width = width; - config->matrix_config.height = height; + //config->matrix_config.width = width; + //config->matrix_config.height = height; ledscape_t * const leds = ledscape_init(config); + printf("init done\n"); time_t last_time = time(NULL); unsigned last_i = 0; From 77336778b65eaabd350fa86cf0bf684ebd786f55 Mon Sep 17 00:00:00 2001 From: Matthew Mets Date: Sat, 19 Apr 2014 02:20:08 +0000 Subject: [PATCH 254/332] Add init.d script for starting/stopping LEDscape --- debian/LEDscape | 34 ++++++++++++++++++++++++++++++++++ run_ledscape | 4 ++++ 2 files changed, 38 insertions(+) create mode 100755 debian/LEDscape create mode 100755 run_ledscape diff --git a/debian/LEDscape b/debian/LEDscape new file mode 100755 index 00000000..c37853ff --- /dev/null +++ b/debian/LEDscape @@ -0,0 +1,34 @@ +#! /bin/sh +# /etc/init.d/LEDscape + +### BEGIN INIT INFO +# Provides: LEDscape +# Required-Start: +# Required-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Run the LEDscape scuplture +# Description: loads the correct DTS file and then the LEDscape +### END INIT INFO + +# If you want a command to always run, put it here + +# Carry out specific functions when asked to by the system +case "$1" in + start) + echo "Starting LEDscape" + # run application you want to start + bash -c 'cd /home/ubuntu/LEDscape/; ./run_ledscape' + ;; + stop) + echo "Stopping LEDscape" + # kill application you want to stop + killall matrix-test + ;; + *) + echo "Usage: /etc/init.d/LEDscape {start|stop}" + exit 1 + ;; +esac + +exit 0 diff --git a/run_ledscape b/run_ledscape new file mode 100755 index 00000000..bcc623ce --- /dev/null +++ b/run_ledscape @@ -0,0 +1,4 @@ +#!/bin/bash + +echo "CAPE-BONE-OCTO" > /sys/devices/bone_capemgr.9/slots +./bin/matrix-test strips.config From bf2b191e054877df82e52aae9b4fba4e95ee49f0 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 20 Apr 2014 12:25:58 -0400 Subject: [PATCH 255/332] 32-sided plate layout --- pcb/octoscroller.scad | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pcb/octoscroller.scad b/pcb/octoscroller.scad index ee17659a..badf8d02 100644 --- a/pcb/octoscroller.scad +++ b/pcb/octoscroller.scad @@ -4,9 +4,7 @@ * Horizontal or vertical connections are possible. * The spacing between the holes differs for each. */ -sides = 16; -orientation = 1; - +sides = 32; // horizontal has 13 mm from edge to center of hole. module horizontal_bracket() @@ -41,11 +39,11 @@ module vertical_bracket() } -for (i = [0:3]) +for (i = [0:7]) { for (j = [0:3]) { - translate([i*21, j*37,0]) + translate([i*15, j*37,0]) rotate([0,0,90]) vertical_bracket(); } From 7713c43ce6e051a69434721e372c1a08f5743960 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 20 Apr 2014 13:03:30 -0400 Subject: [PATCH 256/332] tall brackets --- brackets/octoscroller.scad | 40 +++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/brackets/octoscroller.scad b/brackets/octoscroller.scad index badf8d02..f76cfb60 100644 --- a/brackets/octoscroller.scad +++ b/brackets/octoscroller.scad @@ -22,7 +22,7 @@ module horizontal_bracket() } } -// vetical has only 10mm +// vertical has only 10mm module vertical_bracket() { rotate([0,0,-360/sides/2]) @@ -38,7 +38,41 @@ module vertical_bracket() } } +// combo bracket has only 10mm, with 13*2 mm spacing +module vertical_bracket2() +{ + rotate([0,0,-360/sides/2]) + render() difference() { + translate([-16,0,]) cube([16,8,26+5+5]); + translate([-10,15,5]) rotate([90,0,0]) cylinder(r=3.5/2,h=20, $fs=1); + translate([-10,15,26+5]) rotate([90,0,0]) cylinder(r=3.5/2,h=20, $fs=1); + } + rotate([0,0,+360/sides/2]) + render() difference() { + translate([0,0,]) cube([16,8,26+5+5]); + translate([10,15,5]) rotate([90,0,0]) cylinder(r=3.5/2,h=20, $fs=1); + translate([10,15,26+5]) rotate([90,0,0]) cylinder(r=3.5/2,h=20, $fs=1); + } + + translate([-7,3.5,0]) cube([14,5,26+5+5]); +} + + +module vertical_bracket3() +{ + linear_extrude(height=8) polygon([ + [0,0], + //[20,cos(360/sides/2)*10], + [-20,10], + [20,10], + //[-cos(360/sides/2)*10,10], + ]); +} + + +if (0) +{ for (i = [0:7]) { for (j = [0:3]) @@ -48,3 +82,7 @@ for (i = [0:7]) vertical_bracket(); } } +} else { + vertical_bracket2(); + //vertical_bracket3(); +} From 646fda2dd92f0b11dde160231f96910725743af8 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 20 Apr 2014 19:06:21 +0000 Subject: [PATCH 257/332] firmware loader --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 76889d39..c14e8d26 100755 --- a/Makefile +++ b/Makefile @@ -19,3 +19,7 @@ clean: $(MAKE) -C $$dir clean; \ done + +firmware: + echo CAPE-BONE-OCTO > /sys/devices/bone_capemgr.8/slots + From 3e28bcd42e811f68c977f00eaf3e6c74a8f844e6 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 20 Apr 2014 19:06:41 +0000 Subject: [PATCH 258/332] remove timer code, move reading from stdin into a separate thread --- src/perlin/perlin-ledscape.cpp | 71 ++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/src/perlin/perlin-ledscape.cpp b/src/perlin/perlin-ledscape.cpp index b0818657..36b39841 100644 --- a/src/perlin/perlin-ledscape.cpp +++ b/src/perlin/perlin-ledscape.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include using namespace std; @@ -57,6 +58,35 @@ void BlankDisplay (void); void WriteLevels (void); void timer_handler (int signum); + +static void * +read_thread( + void * arg +) +{ + char line[128]; + float new_size; + printf("read thread waiting\n"); + + while (1) + { + if (fgets(line, sizeof(line), stdin) == NULL) + break; + printf("read '%s'\n", line); + int rc = sscanf(line, "%f", &new_size); + if (rc != 1) + { + printf("scanf failed: %d\n", rc); + continue; + } + printf("old size %f new size %f\n", gPattern->getZStep(), new_size); + gPattern->setZStep(new_size); + } + + fprintf(stderr, "read thread exiting\n"); + return NULL; +} + int main (int argc, char *argv[]) { struct sigaction sa; @@ -98,32 +128,24 @@ int main (int argc, char *argv[]) hue_options ); + // spin off a thread to read size, speed and other settings + pthread_t read_id; + if (pthread_create(&read_id, NULL, read_thread, NULL) < 0) + return EXIT_FAILURE; + // create a new pattern object -- perlin noise, mode 1 short repeat // gPattern = new Perlin (DISPLAY_WIDTH, DISPLAY_HEIGHT, 1, 8.0/64.0, 0.0125, 1.0, 0.2); // reset to first frame gPattern->init (); - // install timer handler - memset (&sa, 0, sizeof (sa)); - sa.sa_handler = &timer_handler; - sigaction (SIGALRM, &sa, NULL); - - // configure the timer to expire after 20 msec - timer.it_value.tv_sec = 0; - timer.it_value.tv_usec = 20000; + while (1) { + WriteLevels (); - // and every 20 msec after that. - timer.it_interval.tv_sec = 0; - timer.it_interval.tv_usec = 20000; - - // start the timer - setitimer (ITIMER_REAL, &timer, NULL); - - // wait forever - while (1) { - sleep (1); - } + // calculate next frame in animation + gPattern->next (); + usleep(1000); + } // delete pattern object delete gPattern; @@ -157,14 +179,3 @@ void WriteLevels (void) ledscape_draw(leds, gLevels); } - -void timer_handler (int signum) -{ - // write levels to display - WriteLevels (); - - // calculate next frame in animation - if (gPattern != NULL) { - bool patternComplete = gPattern->next (); - } -} From 8d2975d61a6ea4e4f335ebbf344bf254357f31c2 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 20 Apr 2014 16:57:34 -0400 Subject: [PATCH 259/332] knob controller for the perlin noise box --- src/perlin/knobs/knobs.ino | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/perlin/knobs/knobs.ino diff --git a/src/perlin/knobs/knobs.ino b/src/perlin/knobs/knobs.ino new file mode 100644 index 00000000..280fcaf0 --- /dev/null +++ b/src/perlin/knobs/knobs.ino @@ -0,0 +1,32 @@ +/** \file + * Teensy 2.0 firmware to read four analog knobs and print + * their values periodically. + */ + +#define LED_PIN 11 + +void setup(void) +{ + Serial.begin(9600); + pinMode(LED_PIN, OUTPUT); +} + +void loop(void) +{ + digitalWrite(LED_PIN, HIGH); + uint16_t p1 = analogRead(A3); + uint16_t p2 = analogRead(A2); + uint16_t p3 = analogRead(A5); + uint16_t p4 = analogRead(A4); + digitalWrite(LED_PIN, LOW); + + Serial.print(p1); + Serial.print(' '); + Serial.print(p2); + Serial.print(' '); + Serial.print(p3); + Serial.print(' '); + Serial.println(p4); + + delay(100); +} From db07a0ddb90e7147de65d3e1067299d595ed112c Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 20 Apr 2014 16:57:48 -0400 Subject: [PATCH 260/332] smaller plate for vertical bracket --- brackets/octoscroller.scad | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/brackets/octoscroller.scad b/brackets/octoscroller.scad index f76cfb60..e195062b 100644 --- a/brackets/octoscroller.scad +++ b/brackets/octoscroller.scad @@ -71,15 +71,15 @@ module vertical_bracket3() } -if (0) +if (1) { -for (i = [0:7]) +for (i = [0:3]) { for (j = [0:3]) { translate([i*15, j*37,0]) rotate([0,0,90]) - vertical_bracket(); + vertical_bracket2(); } } } else { From 2c32df0967290cdbd3cf06fbefbd8775a7792588 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 20 Apr 2014 22:27:14 -0400 Subject: [PATCH 261/332] vertical attachment brackets, too --- brackets/octoscroller.scad | 46 +++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/brackets/octoscroller.scad b/brackets/octoscroller.scad index e195062b..b88fbf4a 100644 --- a/brackets/octoscroller.scad +++ b/brackets/octoscroller.scad @@ -23,18 +23,18 @@ module horizontal_bracket() } // vertical has only 10mm -module vertical_bracket() +module vertical_bracket(depth) { rotate([0,0,-360/sides/2]) render() difference() { - translate([-16,0,]) cube([16,8,10]); - translate([-10,15,5]) rotate([90,0,0]) cylinder(r=2,h=20, $fs=1); + translate([-16,0,]) cube([16,depth,10]); + translate([-10,1+depth,5]) rotate([90,0,0]) cylinder(r=3/2+0.4,h=depth+2, $fs=1); } rotate([0,0,+360/sides/2]) render() difference() { - translate([0,0,]) cube([16,8,10]); - translate([10,15,5]) rotate([90,0,0]) cylinder(r=2,h=20, $fs=1); + translate([0,0,]) cube([16,depth,10]); + translate([10,1+depth,5]) rotate([90,0,0]) cylinder(r=3/2+0.4,h=depth+2, $fs=1); } } @@ -59,19 +59,35 @@ module vertical_bracket2() } +// bracket 3 has the normal vertical bracket, with an additional +// bit to secure the 15mm extrusion. module vertical_bracket3() { - linear_extrude(height=8) polygon([ - [0,0], - //[20,cos(360/sides/2)*10], - [-20,10], - [20,10], - //[-cos(360/sides/2)*10,10], - ]); + vertical_bracket(12); + + render() difference() { + union() { + rotate([0,0,+360/sides/2]) translate([0,0,9.9]) cube([16,12,13+5+15-10]); + rotate([0,0,-360/sides/2]) translate([-16,0,10]) cube([16,12,13+5+15-10]); + } + + // subtract the extrusion + translate([-15/2,-10,5+13]) cube([15,50,25]); + + // m3 screw holes to secure the extrusion to the bracket + translate([+18,7,13+15/2+5]) rotate([0,90,180]) union() { + cylinder(r=3/2+0.4, h=12, $fs=1); + cylinder(r=6/2+0.4, h=4, $fs=1); + } + translate([-18,7,13+15/2+5]) rotate([0,90,0]) union() { + cylinder(r=3/2+0.4, h=12, $fs=1); + cylinder(r=6/2+0.4, h=4, $fs=1); + } + } } -if (1) +if (0) { for (i = [0:3]) { @@ -83,6 +99,6 @@ for (i = [0:3]) } } } else { - vertical_bracket2(); - //vertical_bracket3(); + //vertical_bracket2(); + vertical_bracket3(); } From 73572b42772f6fd3b0ba5d64fd23edb6d0951d92 Mon Sep 17 00:00:00 2001 From: Matthew Mets Date: Mon, 21 Apr 2014 22:45:01 +0000 Subject: [PATCH 262/332] Hacks and kludges to get the WS2812B working again. --- src/demos/matrix-test.c | 6 +++--- src/ledscape/ledscape.c | 5 ++++- src/ledscape/ws281x.p | 2 +- src/net/matrix-udp-rx.c | 30 +++++++++--------------------- strips.config | 2 +- 5 files changed, 18 insertions(+), 27 deletions(-) diff --git a/src/demos/matrix-test.c b/src/demos/matrix-test.c index 343ccf0d..aaff8f5c 100644 --- a/src/demos/matrix-test.c +++ b/src/demos/matrix-test.c @@ -98,7 +98,7 @@ rainbow( ) { const unsigned color = cycle % 180; - const unsigned dim = 128; + const unsigned dim = 127; for (unsigned x=0; x < width; x++) { for (unsigned y=0; y < height; y++) { @@ -192,8 +192,8 @@ main( const char ** argv ) { - int width = 64; // 256; - int height = 48; //128; + int width = 240; // 256; + int height = 64; //128; ledscape_config_t * config = &ledscape_matrix_default; if (argc > 1) diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index c4e55ac1..0f8401f8 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -340,6 +340,9 @@ ledscape_strip_draw( uint8_t * const row_out = ledscape_remap(leds, out, x, y); uint32_t p = row_in[x]; + row_out[0*pru_stride] = 0xFF; // green + row_out[1*pru_stride] = 0x00; // red + row_out[2*pru_stride] = 0x00; // blue row_out[0*pru_stride] = (p >> 8) & 0xFF; // green row_out[1*pru_stride] = (p >> 0) & 0xFF; // red row_out[2*pru_stride] = (p >> 16) & 0xFF; // blue @@ -353,7 +356,7 @@ ledscape_strip_draw( // Update the pixel data and send the start leds->ws281x->pixels_dma = leds->pru->ddr_addr + leds->frame_size * frame; - frame = (frame + 1) & 1; +// frame = (frame + 1) & 1; // Send the start command leds->ws281x->command = 1; diff --git a/src/ledscape/ws281x.p b/src/ledscape/ws281x.p index 51d51523..0cd4a207 100644 --- a/src/ledscape/ws281x.p +++ b/src/ledscape/ws281x.p @@ -445,7 +445,7 @@ WORD_LOOP: // Wait until the length of the one bits WAITNS 650+600, wait_one_time - //SLEEPNS 350, 1, wait_one_time + SLEEPNS 500, 1, sleep_one_time // Turn all the bits off SBBO gpio0_led_mask, r10, 0, 4 diff --git a/src/net/matrix-udp-rx.c b/src/net/matrix-udp-rx.c index 316dce51..be5e2daa 100644 --- a/src/net/matrix-udp-rx.c +++ b/src/net/matrix-udp-rx.c @@ -57,10 +57,8 @@ main( if (sock < 0) die("socket port %d failed: %s\n", port, strerror(errno)); - const unsigned width = 256; - const unsigned height = 64; - const unsigned leds_width = 256; - const unsigned leds_height = 128; + const unsigned width = 240; + const unsigned height = 48; const size_t image_size = width * height * 3; // largest possible UDP packet @@ -71,6 +69,12 @@ main( fprintf(stderr, "%u x %u, UDP port %u\n", width, height, port); ledscape_config_t * config = &ledscape_matrix_default; + if (argc > 1) + { + config = ledscape_config(argv[1]); + if (!config) + return EXIT_FAILURE; + } ledscape_t * const leds = ledscape_init(config); const unsigned report_interval = 10; @@ -79,8 +83,6 @@ main( unsigned frames = 0; uint32_t * const fb = calloc(width*height,4); - uint32_t * const leds_fb = calloc(leds_width*leds_height,4); - ledscape_draw(leds, leds_fb); while (1) { @@ -128,29 +130,15 @@ main( { for (unsigned y = 0 ; y < height ; y++) // 64 { - uint8_t * out = (void*) &fb[y*2*leds_width + x]; + uint8_t * out = (void*) &fb[y*width + x]; const uint8_t * const in = &buf[1 + 3*(x*height + (width - y - 1))]; out[0] = in[0]; out[1] = in[1];// / 2; out[2] = in[2];// / 2; - - if (0) { - // double the pixels? - out += leds_width * 4; - out[0] = in[0]; - out[1] = in[1] / 2; - out[2] = in[2] / 2; - } } } -#if 0 - // the panel is 256x128, the pyramid was 256x64. - framebuffer_flip(leds_fb, fb + width*0, leds_width, leds_height, width, height-16); - ledscape_draw(leds, leds_fb); -#else ledscape_draw(leds, fb); -#endif gettimeofday(&stop_tv, NULL); timersub(&stop_tv, &start_tv, &delta_tv); diff --git a/strips.config b/strips.config index 54779db2..b901cb7d 100644 --- a/strips.config +++ b/strips.config @@ -1,2 +1,2 @@ ws2812 -64,48 +240,48 From 6fc884faa7e94e950913e3db7387a7c77acaea69 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Mon, 21 Apr 2014 19:40:34 -0400 Subject: [PATCH 263/332] T-bracket for center section --- brackets/octoscroller.scad | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/brackets/octoscroller.scad b/brackets/octoscroller.scad index b88fbf4a..9d2ad124 100644 --- a/brackets/octoscroller.scad +++ b/brackets/octoscroller.scad @@ -87,6 +87,35 @@ module vertical_bracket3() } +// the T-bracket is for securing the center struts +module t_bracket() +{ + render() difference() + { + translate([0,0,5/2]) + union() { + intersection() { + rotate([0,0,45]) cube([50,50,5], center=true); + cube([50,50,5], center=true); + } + rotate([0,0,0]) translate([0,0,10]) cube([21,50,20], center=true); + rotate([0,0,90]) translate([0,0,10]) cube([21,50,20], center=true); + rotate([0,0,45]) translate([0,0,10]) cube([35,35,20], center=true); + } + + translate([0,0,20/2+5]) rotate([0,0,90]) cube([100,15,20], center=true); + translate([0,0,20/2+5]) rotate([0,0,0]) cube([100,15,20], center=true); + + // and the screw holes + translate([-20,+20,15/2+5]) rotate([0,90,0]) cylinder(r=3/2+0.4, h=40, $fs=1); + translate([-20,-20,15/2+5]) rotate([0,90,0]) cylinder(r=3/2+0.4, h=40, $fs=1); + translate([-20,-20,15/2+5]) rotate([0,90,90]) cylinder(r=3/2+0.4, h=40, $fs=1); + translate([+20,-20,15/2+5]) rotate([0,90,90]) cylinder(r=3/2+0.4, h=40, $fs=1); + } + +} + + if (0) { for (i = [0:3]) @@ -100,5 +129,6 @@ for (i = [0:3]) } } else { //vertical_bracket2(); - vertical_bracket3(); + //vertical_bracket3(); + t_bracket(); } From d32c54817c847ccfd1584a493d2fb0795adcf81b Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Mon, 21 Apr 2014 19:40:43 -0400 Subject: [PATCH 264/332] life works again --- src/demos/life.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/demos/life.c b/src/demos/life.c index b863abc1..ceb9f86e 100644 --- a/src/demos/life.c +++ b/src/demos/life.c @@ -21,8 +21,8 @@ #define DELTA_G 30 #define DELTA_B 80 -#define WIDTH 256 -#define HEIGHT 128 +#define WIDTH 512 +#define HEIGHT 64 typedef struct { @@ -208,16 +208,19 @@ main( const char ** argv ) { - ledscape_matrix_config_t * config = &ledscape_matrix_default; + ledscape_config_t * config = &ledscape_matrix_default; if (argc > 1) { - config = ledscape_matrix_config(argv[1]); + config = ledscape_config(argv[1]); if (!config) return EXIT_FAILURE; } - config->width = WIDTH; - config->height = HEIGHT; + if (config->type == LEDSCAPE_MATRIX) + { + config->matrix_config.width = WIDTH; + config->matrix_config.height = HEIGHT; + } ledscape_t * const leds = ledscape_init(config); printf("init done\n"); @@ -225,7 +228,7 @@ main( unsigned last_i = 0; unsigned i = 0; - uint32_t * const p = calloc(config->width*config->height,4); + uint32_t * const p = calloc(WIDTH*HEIGHT,4); srand(getpid()); @@ -243,7 +246,7 @@ main( play_game(&board); } - copy_to_fb(p, config->width, config->height, &board); + copy_to_fb(p, WIDTH, HEIGHT, &board); ledscape_draw(leds, p); usleep(1000); From d891d445f9876d2c2af8b3baf029540518f9944e Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Mon, 21 Apr 2014 19:40:59 -0400 Subject: [PATCH 265/332] read four arguments from serial port --- src/perlin/pattern.cpp | 9 ++++++--- src/perlin/perlin-ledscape.cpp | 19 +++++++++++++------ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/perlin/pattern.cpp b/src/perlin/pattern.cpp index bd0fee54..95021854 100644 --- a/src/perlin/pattern.cpp +++ b/src/perlin/pattern.cpp @@ -54,9 +54,12 @@ uint32_t Pattern::translateHue (int32_t hue) case 5: r = 0xff, g = 0xff-lo, b = 0; break; } //printf("hue=%d=%d,%d: %d,%d,%d\n", hue, hi, lo, r, g, b); - r = gammaLut[r] << 3; - g = gammaLut[g] << 3; - b = gammaLut[b] << 3; + //r = gammaLut[r] << 3; + //g = gammaLut[g] << 3; + //b = gammaLut[b] << 3; + r /= 2; + b /= 2; + g /= 2; #else b = hue; r = 0; diff --git a/src/perlin/perlin-ledscape.cpp b/src/perlin/perlin-ledscape.cpp index 36b39841..dd4dba5b 100644 --- a/src/perlin/perlin-ledscape.cpp +++ b/src/perlin/perlin-ledscape.cpp @@ -67,20 +67,27 @@ read_thread( char line[128]; float new_size; printf("read thread waiting\n"); + int old_p0 = -1; + int old_p1 = -1; + int old_p2 = -1; + int old_p3 = -1; while (1) { if (fgets(line, sizeof(line), stdin) == NULL) break; - printf("read '%s'\n", line); - int rc = sscanf(line, "%f", &new_size); - if (rc != 1) + //printf("read '%s'\n", line); + int p0, p1, p2, p3; + int rc = sscanf(line, "%d %d %d %d", &p0, p1, p2, p3); + if (rc != 4) { - printf("scanf failed: %d\n", rc); + printf("scanf failed: %d: '%s'\n", rc, line); continue; } - printf("old size %f new size %f\n", gPattern->getZStep(), new_size); - gPattern->setZStep(new_size); + + if (p0 != old_p0) + gPattern->setScale(p0 / 1024.0); + old_p0 = p0; } fprintf(stderr, "read thread exiting\n"); From 75f37627c408e43d549f8b09af8b74ac4901430c Mon Sep 17 00:00:00 2001 From: root Date: Tue, 22 Apr 2014 00:20:08 +0000 Subject: [PATCH 266/332] identify does panel/output numbers --- src/demos/identify.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/demos/identify.c b/src/demos/identify.c index bb1014e6..0b7f26d2 100644 --- a/src/demos/identify.c +++ b/src/demos/identify.c @@ -45,25 +45,31 @@ main( int scroll_x = 128; memset(p, 0x10, width*height*4); - for (int x = 0 ; x < width ; x += 32) + for (int i = 0 ; i < 8 ; i++) { - for (int y = 0 ; y < height ; y += 16) + for (int j = 0 ; j < 8 ; j++) { ledscape_printf( - &p[x + width*y], + &p[8+j*32 + width*i*16], + width, + 0xFF0000, // red + "%d-%d", + i, + j + ); + ledscape_printf( + &p[1+j*32 + width*i*16], width, 0x00FF00, // green - "x=%d", - x + "^" ); - ledscape_printf( - &p[x + width*(y+8)], + &p[1+j*32 + width*(i*16+8)], width, - 0xFF00FF, // red - "y=%d", - y + 0x0000FF, // blue + "|" ); + p[j*32+width*i*16] = 0xFFFF00; } } From 2c061ab2f51cea4796986768614807351a1da898 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 22 Apr 2014 00:31:25 +0000 Subject: [PATCH 267/332] mapped tall cylinder --- tall-cylinder.config | 96 ++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/tall-cylinder.config b/tall-cylinder.config index 5022a84b..150a7f3f 100644 --- a/tall-cylinder.config +++ b/tall-cylinder.config @@ -7,30 +7,30 @@ matrix16 0,5 R 80,0 0,6 L 96,0 0,7 R 112,0 -1,0 L 128,0 -1,1 R 144,0 -1,2 L 160,0 -1,3 R 176,0 -1,4 L 192,0 -1,5 R 208,0 -1,6 L 224,0 -1,7 R 240,0 -2,0 L 256,0 -2,1 R 272,0 -2,2 L 288,0 -2,3 R 304,0 -2,4 L 320,0 -2,5 R 336,0 -2,6 L 352,0 -2,7 R 368,0 -3,0 L 384,0 -3,1 R 400,0 -3,2 L 416,0 -3,3 R 432,0 -3,4 L 448,0 -3,5 R 464,0 -3,6 L 480,0 -3,7 R 496,0 +3,0 L 128,0 +3,1 R 144,0 +3,2 L 160,0 +3,3 R 176,0 +3,4 L 192,0 +3,5 R 208,0 +3,6 L 224,0 +3,7 R 240,0 +2,7 L 256,0 +2,6 R 272,0 +2,5 L 288,0 +2,4 R 304,0 +2,3 L 320,0 +2,2 R 336,0 +2,1 L 352,0 +2,0 R 368,0 +1,7 L 384,0 +1,6 R 400,0 +1,5 L 416,0 +1,4 R 432,0 +1,3 L 448,0 +1,2 R 464,0 +1,1 L 480,0 +1,0 R 496,0 4,0 L 0,32 4,1 R 16,32 4,2 L 32,32 @@ -39,27 +39,27 @@ matrix16 4,5 R 80,32 4,6 L 96,32 4,7 R 112,32 -5,0 L 128,32 -5,1 R 144,32 -5,2 L 160,32 -5,3 R 176,32 -5,4 L 192,32 -5,5 R 208,32 -5,6 L 224,32 -5,7 R 240,32 -6,0 L 256,32 -6,1 R 272,32 -6,2 L 288,32 -6,3 R 304,32 -6,4 L 320,32 -6,5 R 336,32 -6,6 L 352,32 -6,7 R 368,32 -7,0 L 384,32 -7,1 R 400,32 -7,2 L 416,32 -7,3 R 432,32 -7,4 L 448,32 -7,5 R 464,32 -7,6 L 480,32 -7,7 R 496,32 +7,0 L 128,32 +7,1 R 144,32 +7,2 L 160,32 +7,3 R 176,32 +7,4 L 192,32 +7,5 R 208,32 +7,6 L 224,32 +7,7 R 240,32 +6,7 L 256,32 +6,6 R 272,32 +6,5 L 288,32 +6,4 R 304,32 +6,3 L 320,32 +6,2 R 336,32 +6,1 L 352,32 +6,0 R 368,32 +5,7 L 384,32 +5,6 R 400,32 +5,5 L 416,32 +5,4 R 432,32 +5,3 L 448,32 +5,2 R 464,32 +5,1 L 480,32 +5,0 R 496,32 From d0e2c8f448d04a6f59a3980a5fa2500667bd021f Mon Sep 17 00:00:00 2001 From: root Date: Tue, 22 Apr 2014 01:05:14 +0000 Subject: [PATCH 268/332] update matrix test; this should be an option --- src/demos/matrix-test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/demos/matrix-test.c b/src/demos/matrix-test.c index 29892b88..da281e38 100644 --- a/src/demos/matrix-test.c +++ b/src/demos/matrix-test.c @@ -192,8 +192,8 @@ main( const char ** argv ) { - int width = 256; - int height = 128; + int width = 512; + int height = 64; ledscape_config_t * config = &ledscape_matrix_default; if (argc > 1) From dc35361e0ec7f34362754265a1965337949793d8 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 22 Apr 2014 01:05:26 +0000 Subject: [PATCH 269/332] wrap on the cylinder --- src/demos/life.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/demos/life.c b/src/demos/life.c index ceb9f86e..6d3bb01a 100644 --- a/src/demos/life.c +++ b/src/demos/life.c @@ -89,6 +89,15 @@ get_space( if (x >= 0 && y >= 0 && x < WIDTH && y < HEIGHT) return b->board[y][x] & 1; + if (y < 0 || y >= HEIGHT) + return 0; + + // map the x to a cylinder + if (x < 0) + return b->board[y][WIDTH - x] & 1; + if (x >= WIDTH) + return b->board[y][x - WIDTH] & 1; + return 0; } From cb12d2ca627bbf347a877fa8fb03b77e406c2313 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 22 Apr 2014 02:21:38 +0000 Subject: [PATCH 270/332] matrix-udp-rx works with transmitter code (half the panels) --- src/net/matrix-udp-rx.c | 48 +++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/src/net/matrix-udp-rx.c b/src/net/matrix-udp-rx.c index 316dce51..68eda5bf 100644 --- a/src/net/matrix-udp-rx.c +++ b/src/net/matrix-udp-rx.c @@ -57,21 +57,36 @@ main( if (sock < 0) die("socket port %d failed: %s\n", port, strerror(errno)); - const unsigned width = 256; + const unsigned width = 512; const unsigned height = 64; - const unsigned leds_width = 256; - const unsigned leds_height = 128; const size_t image_size = width * height * 3; // largest possible UDP packet - uint8_t buf[65536]; + uint8_t buf[width*height*4]; +#if 0 if (sizeof(buf) < image_size + 1) die("%u x %u too large for UDP\n", width, height); +#endif fprintf(stderr, "%u x %u, UDP port %u\n", width, height, port); ledscape_config_t * config = &ledscape_matrix_default; + if (argc > 1) + { + config = ledscape_config(argv[1]); + if (!config) + return EXIT_FAILURE; + } + + if (config->type == LEDSCAPE_MATRIX) + { + config->matrix_config.width = width; + config->matrix_config.height = height; + } + ledscape_t * const leds = ledscape_init(config); + if (!leds) + return EXIT_FAILURE; const unsigned report_interval = 10; unsigned last_report = 0; @@ -79,8 +94,7 @@ main( unsigned frames = 0; uint32_t * const fb = calloc(width*height,4); - uint32_t * const leds_fb = calloc(leds_width*leds_height,4); - ledscape_draw(leds, leds_fb); + ledscape_draw(leds, fb); while (1) { @@ -89,6 +103,7 @@ main( die("recv failed: %s\n", strerror(errno)); warn_once("received %zu bytes\n", rlen); + /* if (buf[0] == 2) { // image type @@ -108,6 +123,7 @@ main( ); continue; } + */ if ((size_t) rlen != image_size + 1) { @@ -126,31 +142,17 @@ main( // and turn onto the side for (unsigned x = 0 ; x < width ; x++) // 256 { - for (unsigned y = 0 ; y < height ; y++) // 64 + for (unsigned y = 0 ; y < 32 ; y++) // 64 { - uint8_t * out = (void*) &fb[y*2*leds_width + x]; - const uint8_t * const in = &buf[1 + 3*(x*height + (width - y - 1))]; + uint8_t * out = (void*) &fb[(y+16)*width + x]; + const uint8_t * const in = &buf[1 + 3*(y*width + x)]; out[0] = in[0]; out[1] = in[1];// / 2; out[2] = in[2];// / 2; - - if (0) { - // double the pixels? - out += leds_width * 4; - out[0] = in[0]; - out[1] = in[1] / 2; - out[2] = in[2] / 2; - } } } -#if 0 - // the panel is 256x128, the pyramid was 256x64. - framebuffer_flip(leds_fb, fb + width*0, leds_width, leds_height, width, height-16); - ledscape_draw(leds, leds_fb); -#else ledscape_draw(leds, fb); -#endif gettimeofday(&stop_tv, NULL); timersub(&stop_tv, &start_tv, &delta_tv); From 1da26cf416e55299f82fde85f67154d26ed2e735 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 22 Apr 2014 02:21:51 +0000 Subject: [PATCH 271/332] include dependency files --- Makefile.common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.common b/Makefile.common index d52a2816..b593402c 100644 --- a/Makefile.common +++ b/Makefile.common @@ -119,7 +119,7 @@ $(foreach O,$(LIB-y),\ .PHONY: clean # Include all of the generated dependency files --include .*.o.d +-include $(OBJDIR)/.*.o.d clean: rm -rf \ From ddfc997c3f52198cd2c5fff9262a26c4b30fe575 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 22 Apr 2014 02:26:20 +0000 Subject: [PATCH 272/332] parameters for cylinder; need to make these runtime --- src/perlin/globals.h | 4 ++-- src/perlin/pattern.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/perlin/globals.h b/src/perlin/globals.h index 73ef57ee..df6a574b 100644 --- a/src/perlin/globals.h +++ b/src/perlin/globals.h @@ -22,8 +22,8 @@ #ifndef __globals_h_ #define __globals_h_ -#define DISPLAY_WIDTH 256 -#define DISPLAY_HEIGHT 128 +#define DISPLAY_WIDTH 512 +#define DISPLAY_HEIGHT 64 extern uint32_t gLevels[DISPLAY_HEIGHT][DISPLAY_WIDTH]; diff --git a/src/perlin/pattern.cpp b/src/perlin/pattern.cpp index 95021854..59007bac 100644 --- a/src/perlin/pattern.cpp +++ b/src/perlin/pattern.cpp @@ -57,9 +57,9 @@ uint32_t Pattern::translateHue (int32_t hue) //r = gammaLut[r] << 3; //g = gammaLut[g] << 3; //b = gammaLut[b] << 3; - r /= 2; - b /= 2; - g /= 2; + r /= 4; + b /= 4; + g /= 4; #else b = hue; r = 0; From 5489677069a61fe0e99ccdfff450af640bb86f5c Mon Sep 17 00:00:00 2001 From: root Date: Fri, 25 Apr 2014 01:06:51 +0000 Subject: [PATCH 273/332] dual frame reception (compatible with megaScrollerTransmitter) --- src/net/matrix-udp-rx.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/net/matrix-udp-rx.c b/src/net/matrix-udp-rx.c index 68eda5bf..5785ca71 100644 --- a/src/net/matrix-udp-rx.c +++ b/src/net/matrix-udp-rx.c @@ -124,6 +124,12 @@ main( continue; } */ + const unsigned frame_part = buf[0]; + if (frame_part != 0 && frame_part != 1) + { + printf("bad type %d\n", frame_part); + continue; + } if ((size_t) rlen != image_size + 1) { @@ -144,15 +150,18 @@ main( { for (unsigned y = 0 ; y < 32 ; y++) // 64 { - uint8_t * out = (void*) &fb[(y+16)*width + x]; + uint32_t * out = (void*) &fb[(y+32*frame_part)*width + x]; const uint8_t * const in = &buf[1 + 3*(y*width + x)]; - out[0] = in[0]; - out[1] = in[1];// / 2; - out[2] = in[2];// / 2; + uint32_t r = in[0]; + uint32_t g = in[1]; + uint32_t b = in[2]; + *out = (r << 16) | (g << 8) | (b << 0); } } - ledscape_draw(leds, fb); + // only draw after the second frame + if (frame_part == 1) + ledscape_draw(leds, fb); gettimeofday(&stop_tv, NULL); timersub(&stop_tv, &start_tv, &delta_tv); From 53e56a431185604ad66748aabc8d8c667b28aaeb Mon Sep 17 00:00:00 2001 From: root Date: Fri, 25 Apr 2014 01:58:48 +0000 Subject: [PATCH 274/332] fire works on the mega scroller --- src/demos/fire.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/demos/fire.c b/src/demos/fire.c index d0c07f38..56a01067 100644 --- a/src/demos/fire.c +++ b/src/demos/fire.c @@ -12,11 +12,8 @@ #include "ledscape.h" // sideways pyramid; 256 height, but 128 wide -#define WIDTH 128 -#define HEIGHT 256 - -static const int leds_width = 256; -static const int leds_height = 128; +#define WIDTH 512 +#define HEIGHT 64 // Borrowed by OctoWS2811 rainbow test @@ -78,7 +75,7 @@ hsv2rgb( green = h2rgb(var1, var2, hue) * 255 / 600000; blue = h2rgb(var1, var2, (hue >= 120) ? hue - 120 : hue + 240) * 255 / 600000; } - return (blue << 16) | (green << 8) | red; + return (red << 16) | (green << 8) | (blue << 0); } @@ -128,6 +125,7 @@ fire_draw( fire[x][y] = 128; // skip the bottom few rows + /* #if 1 if (y > HEIGHT - leds_width) frame[y - (HEIGHT - leds_width) + x*leds_width] = c; @@ -135,7 +133,8 @@ fire_draw( if (x > HEIGHT - leds_width) frame[y - (HEIGHT - leds_width) + x*leds_width] = c; #endif - //frame[(leds_width-x-1) + y*leds_height] = c; +*/ + frame[WIDTH*y + x] = c; //frame[counter++] = c; } } From d8e4df6a2de009a90a658b4446f888a95188ba47 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Mon, 5 May 2014 21:10:23 -0400 Subject: [PATCH 275/332] v1.3 of boards (as ordered) --- pcb/octoscroller.brd | 681 ++++++++++++++++++------------- pcb/octoscroller.sch | 939 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 1303 insertions(+), 317 deletions(-) diff --git a/pcb/octoscroller.brd b/pcb/octoscroller.brd index 8871cee0..d0192b9e 100644 --- a/pcb/octoscroller.brd +++ b/pcb/octoscroller.brd @@ -123,9 +123,11 @@ -Octoscroller^2 -http://trmm.net/Octoscroller -2014-01-07 +Octoscroller^2 v1.3 +http://trmm.net/Octoscroller +2014-05-05 +GND +GND @@ -797,6 +799,73 @@ + +<b>Molex Connectors</b><p> +<author>Created by librarian@cadsoft.de</author> + + +<b>MOLEX 2.54mm KK CONNECTOR</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +1 +2 +>VALUE + + + + + + +<b>Test Pins/Pads</b><p> +Cream on SMD OFF.<br> +new: Attribute TP_SIGNAL_NAME<br> +<author>Created by librarian@cadsoft.de</author> + + +<b>TEST PAD</b> + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + + + @@ -992,7 +1061,22 @@ design rules under a new name. - + + + + + + + + + + + + + + + + @@ -1039,19 +1123,18 @@ design rules under a new name. - - + + + + + + - - - - - @@ -1067,7 +1150,8 @@ design rules under a new name. - + + @@ -1075,36 +1159,39 @@ design rules under a new name. - - - - + + + - - - - + + + - - + + - - - - - + + + + + - - - - - + + + + + + + + + + @@ -1135,7 +1222,7 @@ design rules under a new name. - + @@ -1146,9 +1233,9 @@ design rules under a new name. - - - + + + @@ -1189,28 +1276,32 @@ design rules under a new name. - - - - - - + + + + + + + + - - + + - - - + + + + + - - + + @@ -1235,29 +1326,38 @@ design rules under a new name. - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + @@ -1284,32 +1384,41 @@ design rules under a new name. - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1338,28 +1447,31 @@ design rules under a new name. - - - - - + + + + + + + + + - - - - - - + + + + + - + @@ -1384,35 +1496,35 @@ design rules under a new name. - - - - - - - - - - + + + + + + + + + + + - - - - - - - + + + + + + - - + + @@ -1422,99 +1534,96 @@ design rules under a new name. - + - - - - - + + + + + - + - - - - - - - - + + + + + - + - - - - - - - - - + + + + + + + + - - - - - - - - - + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + - - + + - - - + + + + - - - - - - + + + - + @@ -1544,9 +1653,9 @@ design rules under a new name. - - - + + + @@ -1588,18 +1697,15 @@ design rules under a new name. - - - + + - - - - - - + + + + @@ -1608,11 +1714,10 @@ design rules under a new name. - - - - - + + + + @@ -1671,69 +1776,65 @@ design rules under a new name. - - - - - - + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + - - - - - - - - - + + + + + + @@ -1742,47 +1843,42 @@ design rules under a new name. - - - - + + + + - - - - - - - - - + + + + + + + + + + - - - - - - - - - - + + + + + + + + - - - - - - + + @@ -1792,20 +1888,17 @@ design rules under a new name. - - - - - - - - - - - + + + + + + + + - + @@ -2085,9 +2178,9 @@ design rules under a new name. - - - + + + @@ -2114,12 +2207,20 @@ design rules under a new name. - - - - - - + + + + + + + + + + + + + + diff --git a/pcb/octoscroller.sch b/pcb/octoscroller.sch index 40ab640f..064275db 100644 --- a/pcb/octoscroller.sch +++ b/pcb/octoscroller.sch @@ -8,20 +8,20 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + @@ -30,8 +30,8 @@ - - + + @@ -39,17 +39,17 @@ - - - - - - - - - - - + + + + + + + + + + + @@ -1557,6 +1557,857 @@ + +<b>Molex Connectors</b><p> +<author>Created by librarian@cadsoft.de</author> + + +<b>MOLEX 2.54mm KK RA CONNECTOR</b> +<br>Fixed Orientation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +1 +2 +>VALUE + + + + + + +<b>MOLEX 2.54mm KK CONNECTOR</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +1 +2 +>VALUE + + + + + + + +>NAME +>VALUE + + + + +>NAME + + + + + +<b>CONNECTOR</b><p> +wire to board 2.54 mm (.1 inch) pitch header + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Test Pins/Pads</b><p> +Cream on SMD OFF.<br> +new: Attribute TP_SIGNAL_NAME<br> +<author>Created by librarian@cadsoft.de</author> + + +<b>TEST PAD</b> + + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + + + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + + +<b>TEST PAD</b> + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + + +<b>TEST PAD</b> + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + + +<b>TEST PAD</b> + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + + +<b>TEST PAD</b> + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + + +<b>TEST PAD</b> + + +>NAME +>VALUE +>TP_SIGNAL_NAME + + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + +<b>TEST PAD</b> + +>NAME +>VALUE +>TP_SIGNAL_NAME + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>TP_SIGNAL_NAME + + + + + + +<b>TEST PIN</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1586,6 +2437,9 @@ + + + @@ -1612,6 +2466,10 @@ + + + + @@ -2030,6 +2888,16 @@ From a76db639863869287c6f7031c9d6429f4ce94d25 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 7 May 2014 00:05:26 +0000 Subject: [PATCH 276/332] make the fire rotate --- src/demos/fire.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/demos/fire.c b/src/demos/fire.c index 56a01067..3ec42a76 100644 --- a/src/demos/fire.c +++ b/src/demos/fire.c @@ -92,6 +92,8 @@ fire_draw( uint32_t * const frame ) { + static int rotate_offset = 0; + memset(frame, 0, WIDTH*HEIGHT*sizeof(*frame)); angle = angle + 0.05; @@ -134,10 +136,12 @@ fire_draw( frame[y - (HEIGHT - leds_width) + x*leds_width] = c; #endif */ - frame[WIDTH*y + x] = c; + frame[WIDTH*y + (x + rotate_offset / 16) % WIDTH] = c; //frame[counter++] = c; } } + + rotate_offset++; } From 24b98ba70146fabf12453ff603192ac5df334afe Mon Sep 17 00:00:00 2001 From: root Date: Wed, 7 May 2014 00:05:33 +0000 Subject: [PATCH 277/332] brighter! --- src/ledscape/matrix.p | 2 +- src/perlin/pattern.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ledscape/matrix.p b/src/ledscape/matrix.p index 7c8f6002..b9fe7031 100644 --- a/src/ledscape/matrix.p +++ b/src/ledscape/matrix.p @@ -24,7 +24,7 @@ // higher constants == brighter. // 4 is a ok brightness, 5 is bright, 6 is powerful -#define BRIGHT_SHIFT 6 +#define BRIGHT_SHIFT 5 #define r11_gpio 2 diff --git a/src/perlin/pattern.cpp b/src/perlin/pattern.cpp index 59007bac..95021854 100644 --- a/src/perlin/pattern.cpp +++ b/src/perlin/pattern.cpp @@ -57,9 +57,9 @@ uint32_t Pattern::translateHue (int32_t hue) //r = gammaLut[r] << 3; //g = gammaLut[g] << 3; //b = gammaLut[b] << 3; - r /= 4; - b /= 4; - g /= 4; + r /= 2; + b /= 2; + g /= 2; #else b = hue; r = 0; From 10a362c6445e0500021594caaf38cc8a82c8abbc Mon Sep 17 00:00:00 2001 From: root Date: Wed, 7 May 2014 01:05:43 +0000 Subject: [PATCH 278/332] getoptified stuff --- src/net/matrix-udp-rx.c | 80 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 6 deletions(-) diff --git a/src/net/matrix-udp-rx.c b/src/net/matrix-udp-rx.c index 5785ca71..d4f1facb 100644 --- a/src/net/matrix-udp-rx.c +++ b/src/net/matrix-udp-rx.c @@ -21,9 +21,11 @@ #include #include #include +#include #include "util.h" #include "ledscape.h" +static int verbose; static int udp_socket( @@ -45,6 +47,26 @@ udp_socket( return sock; } +static struct option long_options[] = +{ + /* These options set a flag. */ + {"verbose", no_argument, 0, 1}, + {"port", required_argument, 0, 'p'}, + {"width", required_argument, 0, 'W'}, + {"height", required_argument, 0, 'H'}, + {"config", required_argument, 0, 'c'}, + {"timeout", required_argument, 0, 't'}, + {"message", required_argument, 0, 'm'}, + {0, 0, 0, 0} +}; + + +static void usage(void) +{ + fprintf(stderr, "usage not yet written\n"); + exit(EXIT_FAILURE); +} + int main( @@ -52,17 +74,61 @@ main( char ** argv ) { - const int port = 9999; + /* getopt_long stores the option index here. */ + int option_index = 0; + int port = 9999; + const char * config_file = NULL; + const char * startup_message = ""; + int timeout = 60; + unsigned width = 512; + unsigned height = 64; + + while (1) + { + const int c = getopt_long( + argc, + argv, + "vp:c:t:W:H:m:", + long_options, + &option_index + ); + + if (c == -1) + break; + switch (c) + { + case 'v': + verbose++; + break; + case 'c': + config_file = optarg; + break; + case 't': + timeout = atoi(optarg); + break; + case 'W': + width = atoi(optarg); + break; + case 'H': + height = atoi(optarg); + break; + case 'm': + startup_message = optarg; + break; + default: + usage(); + return -1; + } + } + const int sock = udp_socket(port); if (sock < 0) die("socket port %d failed: %s\n", port, strerror(errno)); - const unsigned width = 512; - const unsigned height = 64; const size_t image_size = width * height * 3; // largest possible UDP packet - uint8_t buf[width*height*4]; + uint8_t *buf = calloc(width*height,4); #if 0 if (sizeof(buf) < image_size + 1) die("%u x %u too large for UDP\n", width, height); @@ -71,9 +137,9 @@ main( fprintf(stderr, "%u x %u, UDP port %u\n", width, height, port); ledscape_config_t * config = &ledscape_matrix_default; - if (argc > 1) + if (config_file) { - config = ledscape_config(argv[1]); + config = ledscape_config(config_file); if (!config) return EXIT_FAILURE; } @@ -94,6 +160,8 @@ main( unsigned frames = 0; uint32_t * const fb = calloc(width*height,4); + ledscape_printf(fb, width, 0xFF0000, "%s", startup_message); + ledscape_printf(fb+16*width, width, 0x00FF00, "%dx%d UDP port %d", width, height, port); ledscape_draw(leds, fb); while (1) From f41fb4097fc9df1ceb2d23f202ced930c36e2087 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 7 May 2014 01:27:25 +0000 Subject: [PATCH 279/332] timeout works --- src/net/matrix-udp-rx.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/net/matrix-udp-rx.c b/src/net/matrix-udp-rx.c index d4f1facb..6e627546 100644 --- a/src/net/matrix-udp-rx.c +++ b/src/net/matrix-udp-rx.c @@ -47,6 +47,21 @@ udp_socket( return sock; } + +static int +wait_socket( + int fd, + int msec_timeout +) +{ + struct timeval tv = { msec_timeout / 1000, msec_timeout % 1000 }; + fd_set fds; + FD_ZERO(&fds); + FD_SET(fd, &fds); + return select(fd+1, &fds, NULL, NULL, &tv); +} + + static struct option long_options[] = { /* These options set a flag. */ @@ -166,6 +181,25 @@ main( while (1) { + int rc = wait_socket(sock, timeout*1000); + if (rc < 0) + { + // something failed + memset(fb, 0, width*height*4); + ledscape_printf(fb, width, 0xFF0000, "read failed?"); + ledscape_draw(leds, fb); + exit(EXIT_FAILURE); + } + + if (rc == 0) + { + // go into timeout mode + memset(fb, 0, width*height*4); + ledscape_printf(fb, width, 0xFF0000, "timeout"); + ledscape_draw(leds, fb); + continue; + } + const ssize_t rlen = recv(sock, buf, sizeof(buf), 0); if (rlen < 0) die("recv failed: %s\n", strerror(errno)); From af7505c45b2e4ce94a080b1b1acd86c74cff36b6 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 7 May 2014 01:36:24 +0000 Subject: [PATCH 280/332] option to not call pru_exec() if things are already running --- src/demos/cube-life.c | 2 +- src/demos/fire.c | 2 +- src/demos/identify.c | 2 +- src/demos/life.c | 2 +- src/demos/matrix-test.c | 2 +- src/ledscape/ledscape.c | 19 ++++++++++++------- src/ledscape/ledscape.h | 3 ++- src/mta/mta-sign.c | 2 +- src/net/matrix-udp-rx.c | 9 +++++++-- src/net/opc-rx.c | 2 +- src/perlin/perlin-ledscape.cpp | 2 +- 11 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/demos/cube-life.c b/src/demos/cube-life.c index c8eb5894..94a9ec7d 100644 --- a/src/demos/cube-life.c +++ b/src/demos/cube-life.c @@ -380,7 +380,7 @@ main(void) ledscape_config_t * const config = &ledscape_matrix_default; config->matrix_config.panel_height = 32; - ledscape_t * const leds = ledscape_init(config); + ledscape_t * const leds = ledscape_init(config, 0); printf("init done\n"); time_t last_time = time(NULL); unsigned last_i = 0; diff --git a/src/demos/fire.c b/src/demos/fire.c index 3ec42a76..8e0b9673 100644 --- a/src/demos/fire.c +++ b/src/demos/fire.c @@ -210,7 +210,7 @@ main( config->width = WIDTH; config->height = HEIGHT; - ledscape_t * const leds = ledscape_init(config); + ledscape_t * const leds = ledscape_init(config, 0); printf("init done\n"); time_t last_time = time(NULL); diff --git a/src/demos/identify.c b/src/demos/identify.c index 0b7f26d2..ef89d240 100644 --- a/src/demos/identify.c +++ b/src/demos/identify.c @@ -34,7 +34,7 @@ main( config->matrix_config.height = height; } - ledscape_t * const leds = ledscape_init(config); + ledscape_t * const leds = ledscape_init(config, 0); //printf("init done %d,%d\n", width, height); time_t last_time = time(NULL); diff --git a/src/demos/life.c b/src/demos/life.c index 6d3bb01a..762bef3e 100644 --- a/src/demos/life.c +++ b/src/demos/life.c @@ -231,7 +231,7 @@ main( config->matrix_config.height = HEIGHT; } - ledscape_t * const leds = ledscape_init(config); + ledscape_t * const leds = ledscape_init(config, 0); printf("init done\n"); time_t last_time = time(NULL); unsigned last_i = 0; diff --git a/src/demos/matrix-test.c b/src/demos/matrix-test.c index da281e38..ffbee6cf 100644 --- a/src/demos/matrix-test.c +++ b/src/demos/matrix-test.c @@ -209,7 +209,7 @@ main( config->matrix_config.height = height; } - ledscape_t * const leds = ledscape_init(config); + ledscape_t * const leds = ledscape_init(config, 0); printf("init done\n"); diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index 072a73c1..01600bfe 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -376,7 +376,8 @@ ledscape_wait( static ledscape_t * ledscape_matrix_init( - ledscape_config_t * const config_union + ledscape_config_t * const config_union, + int no_pru_init ) { ledscape_matrix_config_t * const config = &config_union->matrix_config; @@ -404,7 +405,8 @@ ledscape_matrix_init( ledscape_gpio_init(); // Initiate the PRU program - pru_exec(pru, "./lib/matrix.bin"); + if (!no_pru_init) + pru_exec(pru, "./lib/matrix.bin"); // Watch for a done response that indicates a proper startup // \todo timeout if it fails @@ -419,7 +421,8 @@ ledscape_matrix_init( static ledscape_t * ledscape_strip_init( - ledscape_config_t * const config_union + ledscape_config_t * const config_union, + int no_pru_init ) { ledscape_strip_config_t * const config = &config_union->strip_config; @@ -459,7 +462,8 @@ ledscape_strip_init( ledscape_gpio_init(); // Initiate the PRU program - pru_exec(pru, "./lib/ws281x.bin"); + if (!no_pru_init) + pru_exec(pru, "./lib/ws281x.bin"); // Watch for a done response that indicates a proper startup // \todo timeout if it fails @@ -474,15 +478,16 @@ ledscape_strip_init( ledscape_t * ledscape_init( - ledscape_config_t * const config + ledscape_config_t * const config, + int no_pru_init ) { switch (config->type) { case LEDSCAPE_MATRIX: - return ledscape_matrix_init(config); + return ledscape_matrix_init(config, no_pru_init); case LEDSCAPE_STRIP: - return ledscape_strip_init(config); + return ledscape_strip_init(config, no_pru_init); default: fprintf(stderr, "unknown config type %d\n", config->type); return NULL; diff --git a/src/ledscape/ledscape.h b/src/ledscape/ledscape.h index da6234df..f3f19aad 100644 --- a/src/ledscape/ledscape.h +++ b/src/ledscape/ledscape.h @@ -91,7 +91,8 @@ extern ledscape_config_t ledscape_matrix_default; extern ledscape_t * ledscape_init( - ledscape_config_t * config + ledscape_config_t * config, + int no_init_pru ); diff --git a/src/mta/mta-sign.c b/src/mta/mta-sign.c index 7061bbfc..180d685c 100644 --- a/src/mta/mta-sign.c +++ b/src/mta/mta-sign.c @@ -113,7 +113,7 @@ main( return EXIT_FAILURE; } - ledscape_t * const leds = ledscape_init(config); + ledscape_t * const leds = ledscape_init(config, 0); printf("init done\n"); time_t last_time = time(NULL); diff --git a/src/net/matrix-udp-rx.c b/src/net/matrix-udp-rx.c index 6e627546..8599f8e5 100644 --- a/src/net/matrix-udp-rx.c +++ b/src/net/matrix-udp-rx.c @@ -72,6 +72,7 @@ static struct option long_options[] = {"config", required_argument, 0, 'c'}, {"timeout", required_argument, 0, 't'}, {"message", required_argument, 0, 'm'}, + {"noinit", no_argument, 0, 'n'}, {0, 0, 0, 0} }; @@ -97,13 +98,14 @@ main( int timeout = 60; unsigned width = 512; unsigned height = 64; + int no_init = 0; while (1) { const int c = getopt_long( argc, argv, - "vp:c:t:W:H:m:", + "vp:c:t:W:H:m:n", long_options, &option_index ); @@ -115,6 +117,9 @@ main( case 'v': verbose++; break; + case 'n': + no_init++; + break; case 'c': config_file = optarg; break; @@ -165,7 +170,7 @@ main( config->matrix_config.height = height; } - ledscape_t * const leds = ledscape_init(config); + ledscape_t * const leds = ledscape_init(config, no_init); if (!leds) return EXIT_FAILURE; diff --git a/src/net/opc-rx.c b/src/net/opc-rx.c index f03566a2..5896003b 100644 --- a/src/net/opc-rx.c +++ b/src/net/opc-rx.c @@ -73,7 +73,7 @@ main( fprintf(stderr, "%u x %u, TCP port %u\n", width, height, port); ledscape_config_t * config = &ledscape_matrix_default; - ledscape_t * const leds = ledscape_init(config); + ledscape_t * const leds = ledscape_init(config, 0); const unsigned report_interval = 10; unsigned last_report = 0; diff --git a/src/perlin/perlin-ledscape.cpp b/src/perlin/perlin-ledscape.cpp index dd4dba5b..591529c6 100644 --- a/src/perlin/perlin-ledscape.cpp +++ b/src/perlin/perlin-ledscape.cpp @@ -116,7 +116,7 @@ int main (int argc, char *argv[]) config->matrix_config.width = DISPLAY_WIDTH; config->matrix_config.height = DISPLAY_HEIGHT; - leds = ledscape_init(config); + leds = ledscape_init(config, 0); ledscape_printf((uint32_t*)(uintptr_t)gLevels, DISPLAY_WIDTH, 0xFF0000, "Perlin noise by Glen Akins"); ledscape_draw(leds, gLevels); From ee64ff7ec06ab52e3da31861eff1d54fcc11718b Mon Sep 17 00:00:00 2001 From: root Date: Wed, 7 May 2014 01:44:28 +0000 Subject: [PATCH 281/332] fix newline handling in ledscape_printf --- src/ledscape/ledscape.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index 01600bfe..45fd53ab 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -584,13 +584,20 @@ ledscape_printf( int len = vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); (void) len; + uint32_t * start = px; - //printf("%p => '%s'\n", px, buf); + printf("%p => '%s'\n", px, buf); for (unsigned i = 0 ; i < sizeof(buf) ; i++) { char c = buf[i]; if (!c) break; + if (c == '\n') + { + px = start = start + 8 * width; + continue; + } + ledscape_draw_char(px, width, color, c); px += 6; } From d94d5e92e12a048f45d11dd6c39196db8c6bfd02 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 7 May 2014 01:45:00 +0000 Subject: [PATCH 282/332] silence ledscape_printf --- src/ledscape/ledscape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index 45fd53ab..abd72b9f 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -586,7 +586,7 @@ ledscape_printf( (void) len; uint32_t * start = px; - printf("%p => '%s'\n", px, buf); + //printf("%p => '%s'\n", px, buf); for (unsigned i = 0 ; i < sizeof(buf) ; i++) { char c = buf[i]; From ae2327d4ef084f7b60c8ea204a1a279a6590b2d6 Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Sat, 17 May 2014 11:32:47 +0800 Subject: [PATCH 283/332] Add missing receiver pcb design --- pcb/receiver.brd | 6490 +++++++++++++++++++++++++++++++++++++ pcb/receiver.sch | 8072 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 14562 insertions(+) create mode 100644 pcb/receiver.brd create mode 100644 pcb/receiver.sch diff --git a/pcb/receiver.brd b/pcb/receiver.brd new file mode 100644 index 00000000..33643358 --- /dev/null +++ b/pcb/receiver.brd @@ -0,0 +1,6490 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +- + D +- + D +- + D +- + D +- + D +- + D +- + D +- + D +- + ++ - +- + +- - +- - +RS485 LED driver +Rev A 2013-08-05 +@cibomahto + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Small Outline Package</b> + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CHIPLED</b><p> +Source: http://www.osram.convergy.de/ ... LG_R971.pdf + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>EAGLE Design Rules</b> +<p> +Die Standard-Design-Rules sind so gewählt, dass sie für +die meisten Anwendungen passen. Sollte ihre Platine +besondere Anforderungen haben, treffen Sie die erforderlichen +Einstellungen hier und speichern die Design Rules unter +einem neuen Namen ab. +<b>Laen's PCB Order Design Rules</b> +<p> +Please make sure your boards conform to these design rules. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Since Version 6.2.2 text objects can contain more than one line, +which will not be processed correctly with this version. + + + diff --git a/pcb/receiver.sch b/pcb/receiver.sch new file mode 100644 index 00000000..1b9b7d1d --- /dev/null +++ b/pcb/receiver.sch @@ -0,0 +1,8072 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find non-functional items- supply symbols, logos, notations, frame blocks, etc.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + + + + +>VALUE + + + + + +>VALUE + + + + + +<b>SUPPLY SYMBOL</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Small Outline Package</b> + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + +<b>Dual In Line Package</b> + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>Small Outline Package</b> .150 SIOC<p> +Source: http://www.maxim-ic.com/package_drawings/21-0041B.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +B1 +A1 +B2 +A2 +B3 +A3 +B4 +A4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>±15kV ESD-Protected, 10Mbps, 3V/5V, Quad RS-422/RS-485 Receivers</b><p> +Source: http://pdfserv.maxim-ic.com/en/ds/MAX3095-MAX3096.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + +This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place. +You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line). +This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace" +to hold the component in place. 0.005 has proven to be the perfect amount of "off-center" position when using our standard breakaway headers. +Although looks a little odd when you look at the bare footprint, once you have a header in there, the alteration is very hard to notice. Also, +if you push a header all the way into place, it is covered up entirely on the bottom side. This idea of altering the position of holes to aid alignment +will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins. + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + +>NAME +>VALUE + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + +>Name +>Value ++ +- +S + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + +>Name +>Value + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + +>Value +>Name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + + +<b>Header 3</b> +Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08232 with associated crimp pins and housings. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +MELF 0.10 W + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +MELF 0.25 W + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +MELF 0.12 W + + + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +MELF 0.10 W + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +MELF 0.25 W + + + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +MELF 0.25 W + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +MELF 0.12 W + + + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +MELF 0.25 W + + + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +type 0204, grid 5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0204, grid 7.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0207, grid 10 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0207, grid 12 mm + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + +<b>RESISTOR</b><p> +type 0207, grid 15mm + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + +<b>RESISTOR</b><p> +type 0207, grid 2.5 mm + + + + + + + +>NAME +>VALUE + + +<b>RESISTOR</b><p> +type 0207, grid 5 mm + + + + + + + +>NAME +>VALUE + + +<b>RESISTOR</b><p> +type 0207, grid 7.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0309, grid 10mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0309, grid 12.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0411, grid 12.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0411, grid 15 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0411, grid 3.81 mm + + + + + + +>NAME +>VALUE + + + +<b>RESISTOR</b><p> +type 0414, grid 15 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0414, grid 5 mm + + + + + + +>NAME +>VALUE + + + +<b>RESISTOR</b><p> +type 0617, grid 17.5 mm + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0617, grid 22.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0617, grid 5 mm + + + + + + +>NAME +>VALUE + + + +<b>RESISTOR</b><p> +type 0922, grid 22.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + +<b>RESISTOR</b><p> +type 0613, grid 5 mm + + + + + + +>NAME +>VALUE + + + +<b>RESISTOR</b><p> +type 0613, grid 15 mm + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0817, grid 22.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +0817 + + + + +<b>RESISTOR</b><p> +type 0817, grid 6.35 mm + + + + + + +>NAME +>VALUE +0817 + + + +<b>RESISTOR</b><p> +type V234, grid 12.5 mm + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type V235, grid 17.78 mm + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type V526-0, grid 2.5 mm + + + + + + + + + + +>NAME +>VALUE + + +<b>Mini MELF 0102 Axial</b> + + + + +>NAME +>VALUE + + + +<b>RESISTOR</b><p> +type 0922, grid 7.5 mm + + + + + + +>NAME +>VALUE +0922 + + + +<b>CECC Size RC2211</b> Reflow Soldering<p> +source Beyschlag + + + + + + +>NAME +>VALUE + + +<b>CECC Size RC2211</b> Wave Soldering<p> +source Beyschlag + + + + + + +>NAME +>VALUE + + +<b>CECC Size RC3715</b> Reflow Soldering<p> +source Beyschlag + + + + + + +>NAME +>VALUE + + +<b>CECC Size RC3715</b> Wave Soldering<p> +source Beyschlag + + + + + + +>NAME +>VALUE + + +<b>CECC Size RC6123</b> Reflow Soldering<p> +source Beyschlag + + + + + + +>NAME +>VALUE + + +<b>CECC Size RC6123</b> Wave Soldering<p> +source Beyschlag + + + + + + +>NAME +>VALUE + + +<b>RESISTOR</b><p> +type RDH, grid 15 mm + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +RDH + + + + +<b>RESISTOR</b><p> +type 0204, grid 2.5 mm + + + + + + +>NAME +>VALUE + + +<b>RESISTOR</b><p> +type 0309, grid 2.5 mm + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 2.4 x 4.4 mm + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 2.5 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 3 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 4 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 5 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 6 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm + 5 mm, outline 2.4 x 7 mm + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 + 5 mm, outline 2.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 + 5 mm, outline 3.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 + 5 mm, outline 4.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 + 5 mm, outline 5.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 2.4 x 4.4 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 2.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 4.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 3 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 5.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 7.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +Horizontal, grid 5 mm, outline 7.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>CAPACITOR</b><p> +grid 7.5 mm, outline 3.2 x 10.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 7.5 mm, outline 4.2 x 10.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 7.5 mm, outline 5.2 x 10.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 10.2 mm, outline 4.3 x 13.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 10.2 mm, outline 5.4 x 13.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 10.2 mm, outline 6.4 x 13.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 10.2 mm + 15.2 mm, outline 6.2 x 18.4 mm + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 5.4 x 18.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 6.4 x 18.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 7.2 x 18.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 8.4 x 18.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 9.1 x 18.2 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 6.2 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 7.4 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 8.7 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 10.8 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 11.3 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 9.3 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 11.3 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 13.4 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 20.5 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 32.5 mm, outline 13.7 x 37.4 mm + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 32.5 mm, outline 16.2 x 37.4 mm + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 32.5 mm, outline 18.2 x 37.4 mm + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 37.5 mm, outline 19.2 x 41.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 37.5 mm, outline 20.3 x 41.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 3.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 37.5 mm, outline 15.5 x 41.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 7.5 mm, outline 6.3 x 10.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 15.4 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 17.3 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>Ceramic Chip Capacitor KEMET 0204 Reflow solder</b><p> +Metric Code Size 1005 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 0603 Reflow solder</b><p> +Metric Code Size 1608 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 0805 Reflow solder</b><p> +Metric Code Size 2012 + + + + + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 1206 Reflow solder</b><p> +Metric Code Size 3216 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 1210 Reflow solder</b><p> +Metric Code Size 3225 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 1812 Reflow solder</b><p> +Metric Code Size 4532 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 1825 Reflow solder</b><p> +Metric Code Size 4564 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 2220 Reflow solder</b><p> +Metric Code Size 5650 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 2225 Reflow solder</b><p> +Metric Code Size 5664 + + + + +>NAME +>VALUE + + + + +<b>CHICAGO MINIATURE LAMP, INC.</b><p> +7022X Series SMT LEDs 1206 Package Size + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + +<B>LED</B><p> +5 mm, square, Siemens + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<B>LED</B><p> +2 x 5 mm, rectangle + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + +<B>LED</B><p> +3 mm, round + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<B>LED</B><p> +5 mm, round + + + + + + + + + + + +>NAME +>VALUE + + +<B>LED</B><p> +1 mm, round, Siemens + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<B>LED BLOCK</B><p> +1 LED, Siemens + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>LED HOLDER</b><p> +Siemens + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>LED HOLDER</b><p> +Siemens + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>LED HOLDER</b><p> +Siemens + + + + + + + + + + + + + + + + + +A+ +K- +>NAME +>VALUE + + + + + +<b>LED HOLDER</b><p> +Siemens + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE ++ +- + + +<B>IR LED</B><p> +infrared emitting diode, Infineon +TO-18, lead spacing 2.54 mm, cathode marking<p> +Inifineon + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<B>IR LED</B><p> +infrared emitting diode, Infineon +TO-18, lead spacing 2.54 mm, cathode marking<p> +Inifineon + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<B>LED</B><p> +rectangle, 5.7 x 3.2 mm + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<B>IR LED</B><p> +IR transmitter Siemens + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>TOPLED® High-optical Power LED (HOP)</b><p> +Source: http://www.osram.convergy.de/ ... ls_t675.pdf + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +A +C + + + + + + + +<b>BLUE LINETM Hyper Mini TOPLED® Hyper-Bright LED</b><p> +Source: http://www.osram.convergy.de/ ... LB M676.pdf + + + + + + + + + + + + + + +A +C +>NAME +>VALUE + + + + + + + +<b>Super SIDELED® High-Current LED</b><p> +LG A672, LP A672 <br> +Source: http://www.osram.convergy.de/ ... LG_LP_A672.pdf (2004.05.13) + + + + + + + + + + + + + + + + + + + +C +A +>NAME +>VALUE + + + + + + + +<b>SmartLEDTM Hyper-Bright LED</b><p> +Source: http://www.osram.convergy.de/ ... LA_LO_LS_LY L896.pdf + + + + + + + +>NAME +>VALUE + + + + + +<b>Hyper TOPLED® RG Hyper-Bright LED</b><p> +Source: http://www.osram.convergy.de/ ... LA_LO_LS_LY T776.pdf + + + + + + + + + + + + + + + + +>NAME +>VALUE +A +C + + + + + + + + + + +<b>Hyper Micro SIDELED®</b><p> +Source: http://www.osram.convergy.de/ ... LA_LO_LS_LY Y876.pdf + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + +<b>Power TOPLED®</b><p> +Source: http://www.osram.convergy.de/ ... LA_LO_LA_LY E67B.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +C +A +C +C + + + + + + + + + + + +<b>Hyper CHIPLED Hyper-Bright LED</b><p> +LB Q993<br> +Source: http://www.osram.convergy.de/ ... Lb_q993.pdf + + + + +>NAME +>VALUE + + + + + + + +<b>Hyper CHIPLED Hyper-Bright LED</b><p> +LB R99A<br> +Source: http://www.osram.convergy.de/ ... lb_r99a.pdf + + + + +>NAME +>VALUE ++ + + + + + + + +<b>Mini TOPLED Santana®</b><p> +Source: http://www.osram.convergy.de/ ... LG M470.pdf + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + +<b>CHIPLED</b><p> +Source: http://www.osram.convergy.de/ ... LG_R971.pdf + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + +<b>CHIPLED</b><p> +Source: http://www.osram.convergy.de/ ... LG_LY N971.pdf + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + +<b>CHIPLED</b><p> +Source: http://www.osram.convergy.de/ ... LG_LY Q971.pdf + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + +<b>CHIPLED-0603</b><p> +Recommended Solder Pad useable for SmartLEDTM and Chipled - Package 0603<br> +Package able to withstand TTW-soldering heat<br> +Package suitable for TTW-soldering<br> +Source: http://www.osram.convergy.de/ ... LO_LS_LY L89K.pdf + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + +<b>SmartLED TTW</b><p> +Recommended Solder Pad useable for SmartLEDTM and Chipled - Package 0603<br> +Package able to withstand TTW-soldering heat<br> +Package suitable for TTW-soldering<br> +Source: http://www.osram.convergy.de/ ... LO_LS_LY L89K.pdf + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +A +K + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + +<B>RESISTOR</B>, American symbol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<B>CAPACITOR</B>, American symbol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>LED</b><p> +<u>OSRAM</u>:<br> + +- <u>CHIPLED</u><br> +LG R971, LG N971, LY N971, LG Q971, LY Q971, LO R971, LY R971 +LH N974, LH R974<br> +LS Q976, LO Q976, LY Q976<br> +LO Q996<br> + + +- <u>Hyper CHIPLED</u><br> +LW Q18S<br> +LB Q993, LB Q99A, LB R99A<br> + +- <u>SideLED</u><br> +LS A670, LO A670, LY A670, LG A670, LP A670<br> +LB A673, LV A673, LT A673, LW A673<br> +LH A674<br> +LY A675<br> +LS A676, LA A676, LO A676, LY A676, LW A676<br> +LS A679, LY A679, LG A679<br> + +- <u>Hyper Micro SIDELED®</u><br> +LS Y876, LA Y876, LO Y876, LY Y876<br> +LT Y87S<br> + +- <u>SmartLED</u><br> +LW L88C, LW L88S<br> +LB L89C, LB L89S, LG L890<br> +LS L89K, LO L89K, LY L89K<br> +LS L896, LA L896, LO L896, LY L896<br> + +- <u>TOPLED</u><br> +LS T670, LO T670, LY T670, LG T670, LP T670<br> +LSG T670, LSP T670, LSY T670, LOP T670, LYG T670<br> +LG T671, LOG T671, LSG T671<br> +LB T673, LV T673, LT T673, LW T673<br> +LH T674<br> +LS T676, LA T676, LO T676, LY T676, LB T676, LH T676, LSB T676, LW T676<br> +LB T67C, LV T67C, LT T67C, LS T67K, LO T67K, LY T67K, LW E67C<br> +LS E67B, LA E67B, LO E67B, LY E67B, LB E67C, LV E67C, LT E67C<br> +LW T67C<br> +LS T679, LY T679, LG T679<br> +LS T770, LO T770, LY T770, LG T770, LP T770<br> +LB T773, LV T773, LT T773, LW T773<br> +LH T774<br> +LS E675, LA E675, LY E675, LS T675<br> +LS T776, LA T776, LO T776, LY T776, LB T776<br> +LHGB T686<br> +LT T68C, LB T68C<br> + +- <u>Hyper Mini TOPLED®</u><br> +LB M676<br> + +- <u>Mini TOPLED Santana®</u><br> +LG M470<br> +LS M47K, LO M47K, LY M47K<br> + +<p> +Source: http://www.osram.convergy.de/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>Name +>Value ++ +- + + +2mm SMD side-entry connector. tDocu layer indicates the actual physical plastic housing. +/- indicate SparkFun standard batteries and wiring. + + + + + + + + + + + + + +>Name +>Value ++ +- + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + +>Name +>Value + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + +>Name +>Value ++ +- + + +<H3>JST-2-PTH-KIT</h3> +2-Pin JST, through-hole connector<br> +<br> +<b>Warning:</b> This is the KIT version of this package. This package has a smaller diameter top stop mask, which doesn't cover the diameter of the pad. This means only the bottom side of the pads' copper will be exposed. You'll only be able to solder to the bottom side. + + + + + + + + + +>Name +>Value ++ +- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place. +You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line). +This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace" +to hold the component in place. 0.005 has proven to be the perfect amount of "off-center" position when using our standard breakaway headers. +Although looks a little odd when you look at the bare footprint, once you have a header in there, the alteration is very hard to notice. Also, +if you push a header all the way into place, it is covered up entirely on the bottom side. This idea of altering the position of holes to aid alignment +will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins. + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + +<b>Header 2</b> +Standard 2-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08233 with associated crimp pins and housings. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 1b400af39712ec6b95c93e5cc231c2f4c9418da8 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 24 May 2014 14:33:53 +0000 Subject: [PATCH 284/332] increase startup delay --- bin/run-ledscape | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/run-ledscape b/bin/run-ledscape index 95b97f99..5df23386 100755 --- a/bin/run-ledscape +++ b/bin/run-ledscape @@ -3,6 +3,6 @@ DIRNAME="`dirname "$0"`" cd "$DIRNAME/.." echo CAPE-BONE-OCTO > /sys/devices/bone_capemgr.8/slots -sleep 4 +sleep 10 exec ./bin/matrix-test From 04e7676591c6cf8d94c8371c904e0bf890a98b2f Mon Sep 17 00:00:00 2001 From: root Date: Sat, 24 May 2014 14:40:13 +0000 Subject: [PATCH 285/332] default to a 256x128 arrangement --- src/demos/matrix-test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/demos/matrix-test.c b/src/demos/matrix-test.c index ffbee6cf..f9a9559e 100644 --- a/src/demos/matrix-test.c +++ b/src/demos/matrix-test.c @@ -192,8 +192,8 @@ main( const char ** argv ) { - int width = 512; - int height = 64; + int width = 256; + int height = 128; ledscape_config_t * config = &ledscape_matrix_default; if (argc > 1) From 990e1b2dd2ff4db798bbc196921a4da1ce0181e8 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 24 May 2014 14:45:01 +0000 Subject: [PATCH 286/332] install script for angstrom --- bin/install | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100755 bin/install diff --git a/bin/install b/bin/install new file mode 100755 index 00000000..a8a8a0f0 --- /dev/null +++ b/bin/install @@ -0,0 +1,19 @@ +#!/bin/sh -x +# +# Install the device tree fragment, the angstrom service file, +# and make it runable. +# + +DIRNAME="`dirname $0`" +cd "$DIRNAME/.." + +cp dts/CAPE-BONE-OCTO-00A0.dtbo /lib/firmware + +if [ ! -d /etc/systemd ]; then + echo >&2 '/etc/systemd does not exist? Is this not angstrom?' + exit 1 +fi + +cp bin/ledscape.service /etc/systemd/system/ +systemctl enable ledscape.service +systemctl status ledscape.service From 24c92b001a717a765ff340e313ad21e4fe5a8feb Mon Sep 17 00:00:00 2001 From: root Date: Sat, 24 May 2014 15:06:12 +0000 Subject: [PATCH 287/332] do not fill up the log --- bin/run-ledscape | 2 +- src/ledscape/pru.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/run-ledscape b/bin/run-ledscape index 5df23386..1f59f9ae 100755 --- a/bin/run-ledscape +++ b/bin/run-ledscape @@ -5,4 +5,4 @@ cd "$DIRNAME/.." echo CAPE-BONE-OCTO > /sys/devices/bone_capemgr.8/slots sleep 10 -exec ./bin/matrix-test +exec ./bin/matrix-test >/dev/null diff --git a/src/ledscape/pru.c b/src/ledscape/pru.c index 7b2f81ad..d76cf7da 100644 --- a/src/ledscape/pru.c +++ b/src/ledscape/pru.c @@ -94,7 +94,8 @@ pru_init( .ddr_size = ddr_size, }; - printf("%s: PRU %d: data %p @ %zu bytes, DMA %p / %"PRIxPTR" @ %zu bytes\n", + fprintf(stderr, + "%s: PRU %d: data %p @ %zu bytes, DMA %p / %"PRIxPTR" @ %zu bytes\n", __func__, pru_num, pru->data_ram, From cd89362b257920bdf7a6743027e4b0bfe9d858a2 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 24 May 2014 15:06:27 +0000 Subject: [PATCH 288/332] update the uEnv file, too --- bin/install | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/bin/install b/bin/install index a8a8a0f0..d5e6f646 100755 --- a/bin/install +++ b/bin/install @@ -7,13 +7,29 @@ DIRNAME="`dirname $0`" cd "$DIRNAME/.." +die() { + echo >&2 "$*" + exit 1 +} + cp dts/CAPE-BONE-OCTO-00A0.dtbo /lib/firmware if [ ! -d /etc/systemd ]; then - echo >&2 '/etc/systemd does not exist? Is this not angstrom?' - exit 1 + die "/etc/systemd does not exist? Is this not angstrom?" fi +BOOT=/media/BEAGLEBONE +UENV="$BOOT/uEnv.txt" +mount -t vfat /dev/mmcblk0p1 "$BOOT" || die "Failed to mount $BOOT" +cp "$UENV" "$UENV.backup" + +cat < "$UENV" +optargs=quiet capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN +END + +umount "$BOOT" + cp bin/ledscape.service /etc/systemd/system/ systemctl enable ledscape.service systemctl status ledscape.service + From 354e6e716d4ab5c40e780e6c2571f633df36aacb Mon Sep 17 00:00:00 2001 From: root Date: Sat, 24 May 2014 17:53:23 +0000 Subject: [PATCH 289/332] handle case of /media/BEAGLEBONE already being mounted --- bin/install | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bin/install b/bin/install index d5e6f646..750a440e 100755 --- a/bin/install +++ b/bin/install @@ -20,13 +20,19 @@ fi BOOT=/media/BEAGLEBONE UENV="$BOOT/uEnv.txt" -mount -t vfat /dev/mmcblk0p1 "$BOOT" || die "Failed to mount $BOOT" + +if ! mount | grep -q "$BOOT"; then + mkdir "$BOOT" + mount -t vfat /dev/mmcblk0p1 "$BOOT" || die "Failed to mount $BOOT" +fi + cp "$UENV" "$UENV.backup" cat < "$UENV" optargs=quiet capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN END +sync umount "$BOOT" cp bin/ledscape.service /etc/systemd/system/ From b21c5b1af600509c364a4381b1ca36d388d60cd5 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sat, 31 May 2014 19:18:11 +0000 Subject: [PATCH 290/332] TCP receiving code --- src/net/Makefile | 2 + src/net/matrix-tcp-rx.c | 351 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 353 insertions(+) create mode 100644 src/net/matrix-tcp-rx.c diff --git a/src/net/Makefile b/src/net/Makefile index ef217bdb..c91a6e53 100755 --- a/src/net/Makefile +++ b/src/net/Makefile @@ -4,10 +4,12 @@ # # BIN-y += matrix-udp-rx +BIN-y += matrix-tcp-rx BIN-y += opc-rx BIN-n += udp-rx matrix-udp-rx.srcs += matrix-udp-rx.c +matrix-tcp-rx.srcs += matrix-tcp-rx.c opc-rx.srcs += opc-rx.c udp-rx.srcs += udp-rx.c diff --git a/src/net/matrix-tcp-rx.c b/src/net/matrix-tcp-rx.c new file mode 100644 index 00000000..f0a0da30 --- /dev/null +++ b/src/net/matrix-tcp-rx.c @@ -0,0 +1,351 @@ +/** \file + * TCP image packet receiver. + * + * Based on the HackRockCity LED Display code: + * https://github.com/agwn/pyramidTransmitter/blob/master/LEDDisplay.pde + * + * Designed to render into the LED matrix. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "ledscape.h" + +static int verbose; + +static int +tcp_socket( + const int port +) +{ + const int sock = socket(AF_INET, SOCK_STREAM, 0); + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_port = htons(port), + .sin_addr.s_addr = INADDR_ANY, + }; + + if (sock < 0) + return -1; + if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr)) < 0) + return -1; + if (listen(sock, 5) , 0) + return -1; + + int yes = 1; + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) + return -1; + + return sock; +} + + +static int +wait_socket( + int fd, + int msec_timeout +) +{ + struct timeval tv = { msec_timeout / 1000, msec_timeout % 1000 }; + fd_set fds; + FD_ZERO(&fds); + FD_SET(fd, &fds); + return select(fd+1, &fds, NULL, NULL, &tv); +} + + +static ssize_t +recv_all( + const int sock, + void * const buf_out, + size_t len +) +{ + uint8_t * buf = buf_out; + size_t off = 0; + + while (off < len) + { + const ssize_t rlen = recv(sock, buf+off, len-off, 0); + if (rlen < 0) + return rlen; + if (rlen == 0) + break; + off += rlen; + } + + return off; +} + + +static struct option long_options[] = +{ + /* These options set a flag. */ + {"verbose", no_argument, 0, 1}, + {"port", required_argument, 0, 'p'}, + {"width", required_argument, 0, 'W'}, + {"height", required_argument, 0, 'H'}, + {"config", required_argument, 0, 'c'}, + {"timeout", required_argument, 0, 't'}, + {"message", required_argument, 0, 'm'}, + {"noinit", no_argument, 0, 'n'}, + {0, 0, 0, 0} +}; + + +static void usage(void) +{ + fprintf(stderr, "usage not yet written\n"); + exit(EXIT_FAILURE); +} + + +const unsigned int packets_per_frame = 2; + +int +main( + int argc, + char ** argv +) +{ + /* getopt_long stores the option index here. */ + int option_index = 0; + int port = 9999; + const char * config_file = NULL; + const char * startup_message = ""; + int timeout = 60; + unsigned width = 512; + unsigned height = 64; + int no_init = 0; + + while (1) + { + const int c = getopt_long( + argc, + argv, + "vp:c:t:W:H:m:n", + long_options, + &option_index + ); + + if (c == -1) + break; + switch (c) + { + case 'v': + verbose++; + break; + case 'n': + no_init++; + break; + case 'c': + config_file = optarg; + break; + case 't': + timeout = atoi(optarg); + break; + case 'W': + width = atoi(optarg); + break; + case 'H': + height = atoi(optarg); + break; + case 'm': + startup_message = optarg; + break; + default: + usage(); + return -1; + } + } + + const int sock = tcp_socket(port); + if (sock < 0) + die("socket port %d failed: %s\n", port, strerror(errno)); + + const size_t image_size = width * height * 3; + const size_t buf_size = (width*height*4)/packets_per_frame + 1; + + // largest possible UDP packet + uint8_t *buf = malloc(buf_size); +#if 0 + if (sizeof(buf) < image_size + 1) + die("%u x %u too large for UDP\n", width, height); +#endif + + fprintf(stderr, "%u x %u, TCP port %u\n", width, height, port); + + ledscape_config_t * config = &ledscape_matrix_default; + if (config_file) + { + config = ledscape_config(config_file); + if (!config) + return EXIT_FAILURE; + } + + if (config->type == LEDSCAPE_MATRIX) + { + config->matrix_config.width = width; + config->matrix_config.height = height; + } + + ledscape_t * const leds = ledscape_init(config, no_init); + if (!leds) + return EXIT_FAILURE; + + const unsigned report_interval = 10; + unsigned last_report = 0; + unsigned long delta_sum = 0; + unsigned frames = 0; + + uint32_t * const fb = calloc(width*height,4); + ledscape_printf(fb, width, 0xFF0000, "%s", startup_message); + ledscape_printf(fb+16*width, width, 0x00FF00, "%dx%d UDP port %d", width, height, port); + ledscape_draw(leds, fb); + + while (1) + { + int rc = wait_socket(sock, timeout*1000); + if (rc < 0) + { + // something failed + memset(fb, 0, width*height*4); + ledscape_printf(fb, width, 0xFF0000, "read failed?"); + ledscape_draw(leds, fb); + exit(EXIT_FAILURE); + } + + if (rc == 0) + { + // go into timeout mode + memset(fb, 0, width*height*4); + ledscape_printf(fb, width, 0xFF0000, "timeout"); + ledscape_draw(leds, fb); + continue; + } + + const int new_sock = accept(sock, NULL, NULL); + if (new_sock < 0) + { + perror("accept"); + continue; + } + + while (1) + { + int rc = wait_socket(new_sock, timeout*1000); + if (rc < 0) + break; + if (rc == 0) + continue; + + const size_t packet_size = 1 + 3*512*32; + const ssize_t rlen = recv_all(new_sock, buf, packet_size); + if (rlen < 0) + die("recv failed: %s\n", strerror(errno)); + if ((size_t) rlen != packet_size) + break; + + warn_once("received %zu bytes\n", rlen); + + /* + if (buf[0] == 2) + { + // image type + printf("image type: %.*s\n", + (int) rlen - 1, + &buf[1] + ); + continue; + } + + if (buf[0] != 1) + { + // What is it? + warn_once("Unknown image type '%c' (%02x)\n", + buf[0], + buf[0] + ); + continue; + } + */ + const unsigned frame_part = buf[0]; + if (frame_part != 0 && frame_part != 1) + { + printf("bad type %d\n", frame_part); + continue; + } + + if ((size_t) rlen != image_size + 1) + { + warn_once("WARNING: Received packet %zu bytes, expected %zu\n", + rlen, + image_size + 1 + ); + } + + struct timeval start_tv, stop_tv, delta_tv; + gettimeofday(&start_tv, NULL); + + const unsigned frame_num = 0; + + // copy the 3-byte values into the 4-byte framebuffer + // and turn onto the side + for (unsigned x = 0 ; x < width ; x++) // 256 + { + for (unsigned y = 0 ; y < 32 ; y++) // 64 + { + uint32_t * out = (void*) &fb[(y+32*frame_part)*width + x]; + const uint8_t * const in = &buf[1 + 3*(y*width + x)]; + uint32_t r = in[0]; + uint32_t g = in[1]; + uint32_t b = in[2]; + *out = (r << 16) | (g << 8) | (b << 0); + } + } + + // only draw after the second frame + if (frame_part == 1) + ledscape_draw(leds, fb); + + gettimeofday(&stop_tv, NULL); + timersub(&stop_tv, &start_tv, &delta_tv); + + frames++; + delta_sum += delta_tv.tv_usec; + if (stop_tv.tv_sec - last_report < report_interval) + continue; + last_report = stop_tv.tv_sec; + + const unsigned delta_avg = delta_sum / frames; + printf("%6u usec avg, max %.2f fps, actual %.2f fps (over %u frames)\n", + delta_avg, + report_interval * 1.0e6 / delta_avg, + frames * 1.0 / report_interval, + frames + ); + + frames = delta_sum = 0; + } + + // this socket was closed + fprintf(stderr, "socket closed, waiting for new conncetion\n"); + close(new_sock); + } + + return 0; +} From c8ef2341824834c0e1c0b2ec6efbd1a45d026e60 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 1 Jun 2014 00:48:54 +0000 Subject: [PATCH 291/332] python test works agian --- bin/python-test | 35 ++++++++++++++++++++++++----------- fonts/nycr.png | Bin 0 -> 2699 bytes 2 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 fonts/nycr.png diff --git a/bin/python-test b/bin/python-test index 44f63201..f45e3067 100755 --- a/bin/python-test +++ b/bin/python-test @@ -13,12 +13,15 @@ dest = ("localhost", 9999) #print im.format, im.size, im.mode # use a truetype font -font = ImageFont.truetype("spincycle.ttf", 18) -font_sm = ImageFont.truetype("pf_tempesta_seven.ttf", 8) +font = ImageFont.truetype("fonts/spincycle.ttf", 32) +font_sm = ImageFont.truetype("fonts/spincycle.ttf", 24) +#font_sm = ImageFont.truetype("fonts/pf_tempesta_seven.ttf", 8) +logo = Image.open("fonts/nycr.png") +#logo.resize((64,64)) i = 0 -width = 256 -height = 48 +width = 512 +height = 64 disp = Image.new("RGB", (width,height), "black") im = Image.new("RGB", (width,height), "black") im_draw = ImageDraw.Draw(im) @@ -32,21 +35,31 @@ def rainbow(i): while True: im.paste("black", (0,0,width,height)) now = datetime.datetime.now() - d = now.strftime("%a %d %b %Y") - t = now.strftime("%H:%M") + d = now.strftime("%a %d %b") + t = now.strftime("%H:%M:%S") # Draw the date - im_draw.text((0, -2), d, font=font, fill=rainbow(i)) + im_draw.text((60, 4), d, font=font, fill=rainbow(i)) + im_draw.text((90, 32), t, font=font_sm, fill=rainbow(i)) + im_draw.text((256+60, 4), d, font=font, fill=rainbow(i)) + im_draw.text((256+90, 32), t, font=font_sm, fill=rainbow(i)) + + im.paste(logo, (0,8)) + im.paste(logo, (256,8)) # Make it scroll disp.paste(im.crop((0,0,i,height)), (width-i,0)) disp.paste(im.crop((i+1,0,width-1,height)), (0,0)) # draw the time on each face - for x in range(0,7): - disp_draw.text((4+x*32, 8-3), t, font=font_sm) + #for x in range(0,7): + #disp_draw.text((4+x*32, 8-3), t, font=font_sm) - # Send it to the drawing server - sock.sendto(chr(1) + disp.tostring(), dest) + # Split it into two pieces and send it to the drawing server + s = disp.tostring() + s1 = s[:(width*height*3/2)] + s2 = s[(width*height*3/2):] + sock.sendto(chr(0) + s1, dest) + sock.sendto(chr(1) + s2, dest) i = (i+1) % width time.sleep(0.025) diff --git a/fonts/nycr.png b/fonts/nycr.png new file mode 100644 index 0000000000000000000000000000000000000000..e05a91cfa0e35ab834e8e37045bb528ae0c59647 GIT binary patch literal 2699 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 wM#@Y|Nm*7_SyGZr$+a}0K Date: Sun, 1 Jun 2014 21:20:12 +0000 Subject: [PATCH 292/332] using hmason/botomatic to get twitter results --- bin/twitter-scroller | 101 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 bin/twitter-scroller diff --git a/bin/twitter-scroller b/bin/twitter-scroller new file mode 100644 index 00000000..a2003d99 --- /dev/null +++ b/bin/twitter-scroller @@ -0,0 +1,101 @@ +#!/usr/bin/python +import Image, ImageFont, ImageDraw +import socket +import time, datetime +import pickle +import tweepy +import time +import thread +from botomatic import TBot +from colorsys import hsv_to_rgb + +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +dest = ("localhost", 9999) + +#print im.format, im.size, im.mode +# use a truetype font +font = ImageFont.truetype("fonts/spincycle.ttf", 32) +font_sm = ImageFont.truetype("fonts/spincycle.ttf", 24) + +i = 0 +width = 512 +height = 64 +disp = Image.new("RGB", (width,height), "black") +im = Image.new("RGB", (width,height), "black") +im_draw = ImageDraw.Draw(im) +disp_draw = ImageDraw.Draw(disp) + +tweets = [] +seen = {} + + +class Searcher(TBot): + debug_mode = True + + def __init__(self): + handle = "searcher" + super(Searcher, self).__init__(handle) + + def run(self): + while True: + results = self.search('"I"') + for result in results: + if result.id in seen: + continue + tweets.append(str(result.text)) + seen[result.id] = 1 + + #print "-----\n" + str(result.text) + "\n" + #try: + #result.retweet() + #except tweepy.error.TweepError: # private status update? + #continue + time.sleep(10) + + + self.wrap_up() + +def start_bot(): + p = Searcher() + +thread.start_new_thread(start_bot, ()) + + +while True: + if len(tweets) == 0: + time.sleep(1) + continue + tweet = tweets.pop() + print "---\n" + tweet + "\n" + continue + + im.paste("black", (0,0,width,height)) + now = datetime.datetime.now() + d = now.strftime("%a %d %b") + t = now.strftime("%H:%M:%S") + + # Draw the date + im_draw.text((60, 4), d, font=font, fill=rainbow(i)) + im_draw.text((90, 32), t, font=font_sm, fill=rainbow(i)) + im_draw.text((256+60, 4), d, font=font, fill=rainbow(i)) + im_draw.text((256+90, 32), t, font=font_sm, fill=rainbow(i)) + + im.paste(logo, (0,8)) + im.paste(logo, (256,8)) + + # Make it scroll + disp.paste(im.crop((0,0,i,height)), (width-i,0)) + disp.paste(im.crop((i+1,0,width-1,height)), (0,0)) + + # draw the time on each face + #for x in range(0,7): + #disp_draw.text((4+x*32, 8-3), t, font=font_sm) + + # Split it into two pieces and send it to the drawing server + s = disp.tostring() + s1 = s[:(width*height*3/2)] + s2 = s[(width*height*3/2):] + sock.sendto(chr(0) + s1, dest) + sock.sendto(chr(1) + s2, dest) + i = (i+1) % width + time.sleep(0.025) From 745e7b7a7306237671f32d4544874d576b19d211 Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Wed, 4 Jun 2014 00:50:53 +0000 Subject: [PATCH 293/332] .beats time for @phooky --- bin/python-test | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/bin/python-test b/bin/python-test index f45e3067..8ee2ccf5 100755 --- a/bin/python-test +++ b/bin/python-test @@ -31,18 +31,32 @@ def rainbow(i): rgb = [int(x*256) for x in hsv_to_rgb(i/256.0,0.8,0.8)] return (rgb[0],rgb[1],rgb[2]) +def internet_time(): + "Swatch Internet Time. Biel meridian." + "More granular Swatch time. Courtesy https://github.com/gcohen55/pebble-beapoch" + return (((time.time() + 3600) % 86400) * 1000) / 86400 + #h, m, s = time.gmtime()[3:6] + #h += 1 # Biel time zone: UTC+1 + #seconds = s + (60.0*m) + (60.0*60.0*h) + #beats = seconds * 1000.0 / (60.0*60.0*24.0) + #beats = beats % 1000.0 + #return beats + + while True: im.paste("black", (0,0,width,height)) now = datetime.datetime.now() d = now.strftime("%a %d %b") - t = now.strftime("%H:%M:%S") + t1 = now.strftime("%H:%M:%S") + t2 = "%07.3f" % (internet_time()) # Draw the date im_draw.text((60, 4), d, font=font, fill=rainbow(i)) - im_draw.text((90, 32), t, font=font_sm, fill=rainbow(i)) + im_draw.text((90, 32), t1, font=font_sm, fill=rainbow(i)) im_draw.text((256+60, 4), d, font=font, fill=rainbow(i)) - im_draw.text((256+90, 32), t, font=font_sm, fill=rainbow(i)) + im_draw.text((256+80, 32), t2, font=font_sm, fill=rainbow(i)) + im_draw.text((256+180, 32), ".beats", font=font_sm, fill=rainbow(i)) im.paste(logo, (0,8)) im.paste(logo, (256,8)) From 30a0b379c3623302e9e5f5de345fbf67d8d20a8a Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Thu, 5 Jun 2014 22:28:49 -0400 Subject: [PATCH 294/332] two player lightcycles game --- src/demos/lightcycles.c | 379 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 379 insertions(+) create mode 100644 src/demos/lightcycles.c diff --git a/src/demos/lightcycles.c b/src/demos/lightcycles.c new file mode 100644 index 00000000..a396d92f --- /dev/null +++ b/src/demos/lightcycles.c @@ -0,0 +1,379 @@ +/** \file + * Lightcycles style game on the cylindrical megascroller. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WIDTH 512 +#define HEIGHT 64 +#define MAX_PLAYERS 4 + +uint32_t board[HEIGHT][WIDTH]; + +typedef struct { + int x; + int y; + int dir; + uint32_t color; + int alive; +} player_t; + +player_t players[MAX_PLAYERS]; + + +int +player_update( + player_t * const player +) +{ + if (!player->alive) + return 0; + + switch (player->dir) + { + case 0: + player->x = (player->x + 1 + WIDTH) % WIDTH; + break; + case 1: + player->y = (player->y + 1 + HEIGHT) % HEIGHT; + break; + case 2: + player->x = (player->x - 1 + WIDTH) % WIDTH; + break; + case 3: + player->y = (player->y - 1 + HEIGHT) % HEIGHT; + break; + default: + player->dir = 0; + break; + } + + // check for collision + if (board[player->y][player->x] != 0) + { + // dead! + printf("player %08x died at %d,%d\n", + player->color, player->x, player->y); + board[player->y][player->x] = 0xFFFFFF; + player->alive = 0; + } else { + // ok! + board[player->y][player->x] = player->color; + } + + return player->alive; +} + + +static const uint32_t palette[] = +{ + 0xFF0000, + 0x00FF00, + 0x0000FF, + 0xFF00FF, + 0xFFFF00, +}; + + + +static void +fill( + uint32_t color +) +{ + for (int y = 0 ; y < HEIGHT ; y++) + for (int x = 0 ; x < WIDTH ; x++) + board[y][x] = color; +} + + +void +new_game( + int num_players +) +{ + fill(0); + + for (int i = 0 ; i < MAX_PLAYERS ; i++) + { + player_t * const player = &players[i]; + player->alive = i < num_players ? 1 : 0; + player->x = 0; // rand() % WIDTH; + player->y = rand() % HEIGHT; + player->dir = 0; //(rand() % 2) ? 0 : 2; + player->color = palette[i]; + } +} + +static int +tcp_socket( + const int port +) +{ + const int sock = socket(AF_INET, SOCK_STREAM, 0); + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_port = htons(port), + .sin_addr.s_addr = INADDR_ANY, + }; + + if (sock < 0) + return -1; + if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr)) < 0) + return -1; + + int max_size = 65536; + setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &max_size, sizeof(max_size)); + + + return sock; +} + + +static +void rgb32_to_rgb24_and_decay( + uint8_t * const out, + uint32_t * const in, + const int width, + const int height +) +{ + for (int y = 0 ; y < height ; y++) + { + for (int x = 0 ; x < width ; x++) + { + uint8_t * const pix = out + 3*(x + y*width); + uint32_t * const in_pix = &in[x + y*width]; + const uint32_t c = *in_pix; + + uint8_t r = pix[0] = (c >> 16) & 0xFF; + uint8_t g = pix[1] = (c >> 8) & 0xFF; + uint8_t b = pix[2] = (c >> 0) & 0xFF; + + if (r) r--; + if (g) g--; + if (b) b--; + + *in_pix = (r << 16) | (g << 8) | (b << 0); + } + } +} + + +static void +send_game( + const int sock +) +{ + // copy the game from RGBx to RGB and split into two packets + uint8_t pkt[65536]; + + pkt[0] = 0; + rgb32_to_rgb24_and_decay(&pkt[1], &board[0][0], WIDTH, HEIGHT/2); + if (send(sock, pkt, 1 + (WIDTH*HEIGHT/2) * 3, 0) < 0) + { + perror("send"); + exit(EXIT_FAILURE); + } + + pkt[0] = 1; + rgb32_to_rgb24_and_decay(&pkt[1], &board[HEIGHT/2][0], WIDTH, HEIGHT/2); + send(sock, pkt, 1 + (WIDTH*HEIGHT/2) * 3, 0); +} + + +static struct termios ttystate, ttysave; + +static void +tty_raw(void) +{ + //get the terminal state + tcgetattr(STDIN_FILENO, &ttystate); + ttysave = ttystate; + + //turn off canonical mode and echo + ttystate.c_lflag &= ~(ICANON | ECHO); + //minimum of number input read. + ttystate.c_cc[VMIN] = 1; + tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); +} + +static void +tty_reset(void) +{ + ttystate.c_lflag |= ICANON | ECHO; + tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); +} + + +// don't allow a turn backwards into yourself +static void +set_dir( + player_t * const player, + int new_dir +) +{ + if (new_dir == 0 && player->dir == 2) + return; + if (new_dir == 1 && player->dir == 3) + return; + if (new_dir == 2 && player->dir == 0) + return; + if (new_dir == 3 && player->dir == 1) + return; + + player->dir = new_dir; +} + + +static void +bomb( + player_t * const player +) +{ + // nothing yet + (void) player; +} + + + +static void * +read_thread( + void * arg +) +{ + (void) arg; + tty_raw(); + atexit(tty_reset); + + while (1) + { + char c; + ssize_t rc = read(STDIN_FILENO, &c, 1); + if (rc < 0) + { + if (rc == EINTR || rc == EAGAIN) + continue; + perror("stdin"); + break; + } + if (rc == 0) + continue; + + switch (c) + { + case 'h': set_dir(&players[0], 2); break; + case 'j': set_dir(&players[0], 1); break; + case 'k': set_dir(&players[0], 3); break; + case 'l': set_dir(&players[0], 0); break; + case ';': bomb(&players[0]); break; + + case 'a': set_dir(&players[1], 2); break; + case 's': set_dir(&players[1], 1); break; + case 'w': set_dir(&players[1], 3); break; + case 'd': set_dir(&players[1], 0); break; + case 'f': bomb(&players[1]); break; + + default: break; + } + } + + return NULL; +} + + +int main(void) +{ + int port = 9999; + const char * host = "192.168.1.119"; + + const int sock = tcp_socket(0); + struct sockaddr_in dest = { + .sin_family = AF_INET, + .sin_port = htons(port), + .sin_addr = { inet_addr(host) }, + }; + if (connect(sock, (void*) &dest, sizeof(dest)) < 0) + { + perror(host); + return EXIT_FAILURE; + } + + pthread_t thread_id; + if (pthread_create(&thread_id, NULL, read_thread, NULL) < 0) + { + perror("pthread"); + return EXIT_FAILURE; + } + + + int num_players = 2; + + while (1) + { + printf("new game!\n"); + new_game(num_players); + + while (1) + { + send_game(sock); + + int alive_count = 0; + for (int i = 0 ; i < num_players ; i++) + alive_count += player_update(&players[i]); + + if (alive_count == 1) + break; + usleep(5000); + } + + // one player won! figure out who + player_t * winner = NULL; + for (int i = 0 ; i < num_players ; i++) + { + player_t * const player = &players[i]; + if (!player->alive) + continue; + winner = player; + break; + } + + if (winner == NULL) + { + printf("no one won\n"); + continue; + } + + printf("%08x won\n", winner->color); + + // flash the screen + for (int i = 0 ; i < 3 ; i++) + { + fill(winner->color); + send_game(sock); + usleep(250000); + + fill(0); + send_game(sock); + usleep(250000); + + fill(winner->color); + send_game(sock); + usleep(250000); + + fill(0); + send_game(sock); + usleep(500000); + } + } +} From 4293d554d42708a918c4be002da4fb6ad7a3d7de Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Sat, 2 Aug 2014 16:49:06 +0800 Subject: [PATCH 295/332] RevB LEDscape board design: slightly bigger, debug headers for all signals --- pcb/LEDscape.brd | 7379 ++++++++++++++++++++++++++++++++++++++++------ pcb/LEDscape.sch | 497 +++- 2 files changed, 6882 insertions(+), 994 deletions(-) diff --git a/pcb/LEDscape.brd b/pcb/LEDscape.brd index 173007e5..1e7b320b 100644 --- a/pcb/LEDscape.brd +++ b/pcb/LEDscape.brd @@ -1,12 +1,12 @@ - + - + @@ -52,9 +52,9 @@ - + - + @@ -132,35 +132,83 @@ - - - + + + - - - - - - - - - - - - - - - - -+ -- -- -- -- -- -LEDscape LED Controller -By Matt Mets and Trammell Hudson -Rev A 2013-08-01 + + + + + + + + + + + +LEDscape + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +By Matt Mets +and Trammell Hudson +LEDscape Transmitter +Rev B 2014-08-01 +- + ++ - +- - @@ -965,6 +1013,20 @@ We've spent an enormous amount of time creating and checking these footprints an + + + + + + + + + + +>NAME +>VALUE + + @@ -1010,6 +1072,5264 @@ We've spent an enormous amount of time creating and checking these footprints an + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1083,7 +6403,7 @@ Please make sure your boards conform to these design rules. - + @@ -1092,7 +6412,7 @@ Please make sure your boards conform to these design rules. - + @@ -1192,54 +6512,54 @@ Please make sure your boards conform to these design rules. - - - - - - + + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + @@ -1250,24 +6570,56 @@ Please make sure your boards conform to these design rules. - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + @@ -1298,19 +6650,19 @@ Please make sure your boards conform to these design rules. - - - - - - - - - - - - - + + + + + + + + + + + + + @@ -1345,61 +6697,39 @@ Please make sure your boards conform to these design rules. - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + @@ -1409,16 +6739,32 @@ Please make sure your boards conform to these design rules. + + + + + + + + + + + + + + + + + + + + + - - - - - - + @@ -1426,11 +6772,11 @@ Please make sure your boards conform to these design rules. - - - - - + + + + + @@ -1450,11 +6796,12 @@ Please make sure your boards conform to these design rules. - - - - - + + + + + + @@ -1467,12 +6814,12 @@ Please make sure your boards conform to these design rules. - - - - - - + + + + + + @@ -1481,157 +6828,171 @@ Please make sure your boards conform to these design rules. - - + - - - - - - - + + + + + + + - - - - - + + + + + - - - - - + + + + + - - - + + + - - - - - - + + + + + + - + - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -1640,9 +7001,9 @@ Please make sure your boards conform to these design rules. - - - + + + @@ -1650,9 +7011,9 @@ Please make sure your boards conform to these design rules. - - - + + + @@ -1662,9 +7023,9 @@ Please make sure your boards conform to these design rules. - - - + + + @@ -1673,56 +7034,56 @@ Please make sure your boards conform to these design rules. - - - + + + - - - - - + + + + + - - - - - + + + + + - - - + + + - - - - - - + + + + + + - - - - - + + + + + @@ -1742,11 +7103,12 @@ Please make sure your boards conform to these design rules. - - - - - + + + + + + @@ -1759,37 +7121,37 @@ Please make sure your boards conform to these design rules. - - - - - - + + + + + + - - - - - + + + + + - - - - - + + + + + - - - + + + @@ -1808,18 +7170,18 @@ Please make sure your boards conform to these design rules. - - - + + + - - - - - + + + + + @@ -1832,11 +7194,11 @@ Please make sure your boards conform to these design rules. - - - - - + + + + + @@ -1844,10 +7206,10 @@ Please make sure your boards conform to these design rules. - - - - + + + + @@ -1862,12 +7224,12 @@ Please make sure your boards conform to these design rules. - - - - - - + + + + + + @@ -1880,14 +7242,14 @@ Please make sure your boards conform to these design rules. - - - - - - - - + + + + + + + + @@ -1895,44 +7257,44 @@ Please make sure your boards conform to these design rules. - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - + + + + - - - - - - - + + + + + + + @@ -1943,9 +7305,9 @@ Please make sure your boards conform to these design rules. - - - + + + @@ -1953,58 +7315,58 @@ Please make sure your boards conform to these design rules. - - - + + + - - + + - - + + - - - - - + + + + + - - - - - + + + + + - - - + + + - - - - - - + + + + + + @@ -2019,11 +7381,11 @@ Please make sure your boards conform to these design rules. - - - - - + + + + + @@ -2035,20 +7397,22 @@ Please make sure your boards conform to these design rules. - - - - - + + + + + + + - - - - - + + + + + @@ -2057,9 +7421,9 @@ Please make sure your boards conform to these design rules. - - - + + + @@ -2067,438 +7431,504 @@ Please make sure your boards conform to these design rules. - - - + + + - - - - - + + + + + - - - - - + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + - - - - - - - - + + + + + + + + + - - - - + + + + + + - - - - - - - + + + + + + + + + - - - - - - - - - + + + + + + + + + + + - - - - - + + + + + + + + + - - - - + + + + + + + + - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - + - - + + @@ -2511,33 +7941,33 @@ Please make sure your boards conform to these design rules. - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - + + + @@ -2551,28 +7981,27 @@ Please make sure your boards conform to these design rules. - - - - - - + + + + + + - - - - - - - + + + + + + + - - + @@ -2581,30 +8010,30 @@ Please make sure your boards conform to these design rules. - - - - - + + + + + - - - + + + - - - - - - - + + + + + + + @@ -2616,49 +8045,49 @@ Please make sure your boards conform to these design rules. - - - + + + - - + - - - + + + + - - - - - - + + + + + + - - - - + + + + - - - - - + + + + + @@ -2668,9 +8097,9 @@ Please make sure your boards conform to these design rules. - - - + + + @@ -2678,56 +8107,52 @@ Please make sure your boards conform to these design rules. - - - - - - + + + + - - - + + + - - - - - - + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - @@ -2757,175 +8182,193 @@ Please make sure your boards conform to these design rules. - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + + + + + + +Since Version 6.2.2 text objects can contain more than one line, +which will not be processed correctly with this version. + + diff --git a/pcb/LEDscape.sch b/pcb/LEDscape.sch index e884a988..d14c123e 100644 --- a/pcb/LEDscape.sch +++ b/pcb/LEDscape.sch @@ -1,6 +1,6 @@ - + @@ -4548,6 +4548,124 @@ will be further integrated into the Sparkfun Library for other footprints. It c >NAME >VALUE + + + + +>NAME +>VALUE + + + + +>NAME +>VALUE + + + + + + + + + + + + + +>Value +>Name + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +>NAME +>VALUE + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + @@ -4618,6 +4736,16 @@ will be further integrated into the Sparkfun Library for other footprints. It c + + + + + + +>VALUE +>NAME + + @@ -5014,6 +5142,127 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + +<b>Header 1</b> +Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -5091,7 +5340,6 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - @@ -5102,6 +5350,20 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + + + + + + + + + + + + @@ -5173,7 +5435,6 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - @@ -5184,6 +5445,20 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + + + + + + + + + + + + @@ -5206,18 +5481,6 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - - - - - - - - - - - @@ -5374,6 +5637,23 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + + + + + + + + + + + + + + + @@ -5603,15 +5883,9 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - - - - - @@ -5629,6 +5903,21 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + + + + + + + + + + + + + @@ -5710,6 +5999,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -5722,6 +6016,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -5734,6 +6033,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -5746,6 +6050,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -5758,6 +6067,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -5770,6 +6084,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6103,6 +6422,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6115,6 +6439,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6127,6 +6456,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6139,6 +6473,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6151,6 +6490,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6163,6 +6507,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6175,6 +6524,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6187,6 +6541,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6199,6 +6558,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6211,6 +6575,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6223,6 +6592,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6235,6 +6609,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6247,6 +6626,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6259,6 +6643,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6271,6 +6660,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6283,6 +6677,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6295,6 +6694,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6307,6 +6711,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6319,6 +6728,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6331,6 +6745,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6343,6 +6762,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6355,6 +6779,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6367,6 +6796,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6379,6 +6813,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6391,6 +6830,11 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + @@ -6401,7 +6845,12 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - + + + @@ -6753,10 +7202,6 @@ Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - - - From d97f5375a5882305f602191f6948a2f846818875 Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Sat, 2 Aug 2014 16:49:46 +0800 Subject: [PATCH 296/332] New receiver design: 4x output instead of 8x output --- pcb/receiver-4x.brd | 6228 ++++++++++++++++++++++++++++++++++++++ pcb/receiver-4x.sch | 6930 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 13158 insertions(+) create mode 100644 pcb/receiver-4x.brd create mode 100644 pcb/receiver-4x.sch diff --git a/pcb/receiver-4x.brd b/pcb/receiver-4x.brd new file mode 100644 index 00000000..e737e0fa --- /dev/null +++ b/pcb/receiver-4x.brd @@ -0,0 +1,6228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ - +RS485 receiver +Rev B 2014-09-1 +@cibomahto + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +- + +- + +RJ45 signals: +1. D0+ +2. D0- +3. D1+ +4. N/C +5. N/C +6. D1- +7. GND +8. GND + + +- + ++ - ++ - ++ D - ++ D - ++ D - ++ D - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Small Outline Package</b> + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>EAGLE Design Rules</b> +<p> +Die Standard-Design-Rules sind so gewählt, dass sie für +die meisten Anwendungen passen. Sollte ihre Platine +besondere Anforderungen haben, treffen Sie die erforderlichen +Einstellungen hier und speichern die Design Rules unter +einem neuen Namen ab. +<b>Laen's PCB Order Design Rules</b> +<p> +Please make sure your boards conform to these design rules. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Since Version 6.2.2 text objects can contain more than one line, +which will not be processed correctly with this version. + + + diff --git a/pcb/receiver-4x.sch b/pcb/receiver-4x.sch new file mode 100644 index 00000000..efe596d7 --- /dev/null +++ b/pcb/receiver-4x.sch @@ -0,0 +1,6930 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find non-functional items- supply symbols, logos, notations, frame blocks, etc.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + + + + +>VALUE + + + + + +>VALUE + + + + + +<b>SUPPLY SYMBOL</b> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Small Outline Package</b> + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + +<b>Dual In Line Package</b> + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>Small Outline Package</b> .150 SIOC<p> +Source: http://www.maxim-ic.com/package_drawings/21-0041B.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +B1 +A1 +B2 +A2 +B3 +A3 +B4 +A4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>±15kV ESD-Protected, 10Mbps, 3V/5V, Quad RS-422/RS-485 Receivers</b><p> +Source: http://pdfserv.maxim-ic.com/en/ds/MAX3095-MAX3096.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + +This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place. +You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line). +This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace" +to hold the component in place. 0.005 has proven to be the perfect amount of "off-center" position when using our standard breakaway headers. +Although looks a little odd when you look at the bare footprint, once you have a header in there, the alteration is very hard to notice. Also, +if you push a header all the way into place, it is covered up entirely on the bottom side. This idea of altering the position of holes to aid alignment +will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins. + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + +>NAME +>VALUE + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + +>Name +>Value ++ +- +S + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + +>Name +>Value + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + +>Value +>Name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + +Header for OS4000-T + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + +This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place. +You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line). +This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace" +to hold the component in place. 0.005 has proven to be the perfect amount of "off-center" position when using our standard breakaway headers. +Although looks a little odd when you look at the bare footprint, once you have a header in there, the alteration is very hard to notice. Also, +if you push a header all the way into place, it is covered up entirely on the bottom side. This idea of altering the position of holes to aid alignment +will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins. + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + +>VALUE +>NAME + + + + + + + + + + + + + + +>VALUE +>NAME + + + + + + + + + +<b>Header 3</b> +Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08232 with associated crimp pins and housings. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Header 5</b> +Standard 5-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08230 with associated crimp pins and housings. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip + + + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +chip, wave soldering + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +MELF 0.10 W + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +MELF 0.25 W + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +MELF 0.12 W + + + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +MELF 0.10 W + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +MELF 0.25 W + + + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +MELF 0.25 W + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +MELF 0.12 W + + + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +MELF 0.25 W + + + + + + + + + + +>NAME +>VALUE + + + + + +<b>RESISTOR</b><p> +type 0204, grid 5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0204, grid 7.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0207, grid 10 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0207, grid 12 mm + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + +<b>RESISTOR</b><p> +type 0207, grid 15mm + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + +<b>RESISTOR</b><p> +type 0207, grid 2.5 mm + + + + + + + +>NAME +>VALUE + + +<b>RESISTOR</b><p> +type 0207, grid 5 mm + + + + + + + +>NAME +>VALUE + + +<b>RESISTOR</b><p> +type 0207, grid 7.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0309, grid 10mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0309, grid 12.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0411, grid 12.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0411, grid 15 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0411, grid 3.81 mm + + + + + + +>NAME +>VALUE + + + +<b>RESISTOR</b><p> +type 0414, grid 15 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0414, grid 5 mm + + + + + + +>NAME +>VALUE + + + +<b>RESISTOR</b><p> +type 0617, grid 17.5 mm + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0617, grid 22.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0617, grid 5 mm + + + + + + +>NAME +>VALUE + + + +<b>RESISTOR</b><p> +type 0922, grid 22.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + +<b>RESISTOR</b><p> +type 0613, grid 5 mm + + + + + + +>NAME +>VALUE + + + +<b>RESISTOR</b><p> +type 0613, grid 15 mm + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type 0817, grid 22.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +0817 + + + + +<b>RESISTOR</b><p> +type 0817, grid 6.35 mm + + + + + + +>NAME +>VALUE +0817 + + + +<b>RESISTOR</b><p> +type V234, grid 12.5 mm + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type V235, grid 17.78 mm + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>RESISTOR</b><p> +type V526-0, grid 2.5 mm + + + + + + + + + + +>NAME +>VALUE + + +<b>Mini MELF 0102 Axial</b> + + + + +>NAME +>VALUE + + + +<b>RESISTOR</b><p> +type 0922, grid 7.5 mm + + + + + + +>NAME +>VALUE +0922 + + + +<b>CECC Size RC2211</b> Reflow Soldering<p> +source Beyschlag + + + + + + +>NAME +>VALUE + + +<b>CECC Size RC2211</b> Wave Soldering<p> +source Beyschlag + + + + + + +>NAME +>VALUE + + +<b>CECC Size RC3715</b> Reflow Soldering<p> +source Beyschlag + + + + + + +>NAME +>VALUE + + +<b>CECC Size RC3715</b> Wave Soldering<p> +source Beyschlag + + + + + + +>NAME +>VALUE + + +<b>CECC Size RC6123</b> Reflow Soldering<p> +source Beyschlag + + + + + + +>NAME +>VALUE + + +<b>CECC Size RC6123</b> Wave Soldering<p> +source Beyschlag + + + + + + +>NAME +>VALUE + + +<b>RESISTOR</b><p> +type RDH, grid 15 mm + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +RDH + + + + +<b>RESISTOR</b><p> +type 0204, grid 2.5 mm + + + + + + +>NAME +>VALUE + + +<b>RESISTOR</b><p> +type 0309, grid 2.5 mm + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 2.4 x 4.4 mm + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 2.5 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 3 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 4 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 5 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm, outline 6 x 5 mm + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 mm + 5 mm, outline 2.4 x 7 mm + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 + 5 mm, outline 2.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 + 5 mm, outline 3.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 + 5 mm, outline 4.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 2.5 + 5 mm, outline 5.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 2.4 x 4.4 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 2.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 4.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 3 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 5.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 7.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +Horizontal, grid 5 mm, outline 7.5 x 7.5 mm + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +<b>CAPACITOR</b><p> +grid 7.5 mm, outline 3.2 x 10.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 7.5 mm, outline 4.2 x 10.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 7.5 mm, outline 5.2 x 10.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 10.2 mm, outline 4.3 x 13.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 10.2 mm, outline 5.4 x 13.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 10.2 mm, outline 6.4 x 13.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 10.2 mm + 15.2 mm, outline 6.2 x 18.4 mm + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 5.4 x 18.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 6.4 x 18.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 7.2 x 18.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 8.4 x 18.3 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 15 mm, outline 9.1 x 18.2 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 6.2 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 7.4 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 8.7 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 10.8 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 22.5 mm, outline 11.3 x 26.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 9.3 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 11.3 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 13.4 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 20.5 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 32.5 mm, outline 13.7 x 37.4 mm + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 32.5 mm, outline 16.2 x 37.4 mm + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 32.5 mm, outline 18.2 x 37.4 mm + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 37.5 mm, outline 19.2 x 41.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 37.5 mm, outline 20.3 x 41.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 5 mm, outline 3.5 x 7.5 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 37.5 mm, outline 15.5 x 41.8 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 7.5 mm, outline 6.3 x 10.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 15.4 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>CAPACITOR</b><p> +grid 27.5 mm, outline 17.3 x 31.6 mm + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +<b>Ceramic Chip Capacitor KEMET 0204 Reflow solder</b><p> +Metric Code Size 1005 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 0603 Reflow solder</b><p> +Metric Code Size 1608 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 0805 Reflow solder</b><p> +Metric Code Size 2012 + + + + + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 1206 Reflow solder</b><p> +Metric Code Size 3216 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 1210 Reflow solder</b><p> +Metric Code Size 3225 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 1812 Reflow solder</b><p> +Metric Code Size 4532 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 1825 Reflow solder</b><p> +Metric Code Size 4564 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 2220 Reflow solder</b><p> +Metric Code Size 5650 + + + + +>NAME +>VALUE + + + + +<b>Ceramic Chip Capacitor KEMET 2225 Reflow solder</b><p> +Metric Code Size 5664 + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + +>NAME +>VALUE + + + + + + +<B>RESISTOR</B>, American symbol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<B>CAPACITOR</B>, American symbol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>Name +>Value ++ +- + + +2mm SMD side-entry connector. tDocu layer indicates the actual physical plastic housing. +/- indicate SparkFun standard batteries and wiring. + + + + + + + + + + + + + +>Name +>Value ++ +- + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + +>Name +>Value + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + +>Name +>Value ++ +- + + +<H3>JST-2-PTH-KIT</h3> +2-Pin JST, through-hole connector<br> +<br> +<b>Warning:</b> This is the KIT version of this package. This package has a smaller diameter top stop mask, which doesn't cover the diameter of the pad. This means only the bottom side of the pads' copper will be exposed. You'll only be able to solder to the bottom side. + + + + + + + + + +>Name +>Value ++ +- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place. +You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line). +This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace" +to hold the component in place. 0.005 has proven to be the perfect amount of "off-center" position when using our standard breakaway headers. +Although looks a little odd when you look at the bare footprint, once you have a header in there, the alteration is very hard to notice. Also, +if you push a header all the way into place, it is covered up entirely on the bottom side. This idea of altering the position of holes to aid alignment +will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins. + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + +<b>Header 2</b> +Standard 2-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08233 with associated crimp pins and housings. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 0fdaf2419a745045b075671bc08c41fbd1e8204e Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Sun, 3 Aug 2014 02:25:42 +0800 Subject: [PATCH 297/332] Redesign transmitter PCB to use top and bottom ground planes, and one track for +5V- should be much easier to work with. --- pcb/LEDscape.brd | 1354 +++++++++++++++++++++++----------------------- pcb/LEDscape.sch | 94 ++-- 2 files changed, 733 insertions(+), 715 deletions(-) diff --git a/pcb/LEDscape.brd b/pcb/LEDscape.brd index 1e7b320b..437f24c6 100644 --- a/pcb/LEDscape.brd +++ b/pcb/LEDscape.brd @@ -6,7 +6,7 @@ - + @@ -147,7 +147,7 @@ -LEDscape +LEDscape @@ -202,13 +202,13 @@ -By Matt Mets +By Matt Mets and Trammell Hudson -LEDscape Transmitter -Rev B 2014-08-01 -- + -+ - -- - +LEDscape Transmitter +Rev B 2014-08-01 +- + ++ - +- - @@ -6578,16 +6578,16 @@ Please make sure your boards conform to these design rules. - - + + - - + + - - - - + + + + @@ -6613,10 +6613,10 @@ Please make sure your boards conform to these design rules. - - - - + + + + @@ -6649,21 +6649,12 @@ Please make sure your boards conform to these design rules. - - - - - - - - - - - - - - - + + + + + + @@ -6697,39 +6688,9 @@ Please make sure your boards conform to these design rules. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -6739,27 +6700,108 @@ Please make sure your boards conform to these design rules. - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -6795,13 +6837,15 @@ Please make sure your boards conform to these design rules. - - - - - - - + + + + + + + + + @@ -6812,14 +6856,12 @@ Please make sure your boards conform to these design rules. - - - - - - - - + + + + + + @@ -6830,15 +6872,16 @@ Please make sure your boards conform to these design rules. - - - - - - - - - + + + + + + + + + + @@ -6870,129 +6913,103 @@ Please make sure your boards conform to these design rules. - - - - - + + + + - + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + - - - - - - - - + - + + + + - - - - - - - - - - - - - - - + + - + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + @@ -7060,19 +7077,19 @@ Please make sure your boards conform to these design rules. - - - + + + - - - - - + + + + + @@ -7082,7 +7099,6 @@ Please make sure your boards conform to these design rules. - @@ -7092,6 +7108,7 @@ Please make sure your boards conform to these design rules. + @@ -7101,14 +7118,13 @@ Please make sure your boards conform to these design rules. - - - - - - - - + + + + + + + @@ -7119,14 +7135,10 @@ Please make sure your boards conform to these design rules. - - - - - - - - + + + + @@ -7206,15 +7218,17 @@ Please make sure your boards conform to these design rules. - - - - - + + + + + + + @@ -7225,15 +7239,10 @@ Please make sure your boards conform to these design rules. - - - - - - - - - + + + + @@ -7242,17 +7251,15 @@ Please make sure your boards conform to these design rules. - - - - - - - - - + + + + + + + @@ -7260,43 +7267,38 @@ Please make sure your boards conform to these design rules. - - - - + + - - - - - + + + - + - - - - - - - + + + + + + @@ -7363,10 +7365,10 @@ Please make sure your boards conform to these design rules. - - - - + + + + @@ -7395,15 +7397,13 @@ Please make sure your boards conform to these design rules. - - - - - - - - - + + + + + + + @@ -7456,207 +7456,151 @@ Please make sure your boards conform to these design rules. - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - + - - - + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - + + + + + + - - - - - - - - - + + + + + - - - - - - - - - - - - - - - + - + + + + + + + + - - - - - - - - - - - - - - - + - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - + + + + + + + + + + + @@ -7667,10 +7611,12 @@ Please make sure your boards conform to these design rules. - - + - + + + + @@ -7699,12 +7645,11 @@ Please make sure your boards conform to these design rules. - - - - + - + + + @@ -7717,52 +7662,69 @@ Please make sure your boards conform to these design rules. - - - + + - - - - - + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + - - - - + - - - - - - + + + + + + + @@ -7772,30 +7734,32 @@ Please make sure your boards conform to these design rules. - - - - - - - + + + + + - + + + + + + + - - - - - + - - - + + + + + @@ -7819,14 +7783,13 @@ Please make sure your boards conform to these design rules. - + - - - - + + + @@ -7841,35 +7804,28 @@ Please make sure your boards conform to these design rules. - - - - + - - - - - - - - - - - + + + + + + + @@ -7877,47 +7833,39 @@ Please make sure your boards conform to these design rules. - - - - - + - - - - - + + + + - - - - - - - - - - - + + + + + + + + @@ -7939,26 +7887,24 @@ Please make sure your boards conform to these design rules. - - - - - - - - - + + + + + + + + - - - - - - + + + + + @@ -7979,33 +7925,30 @@ Please make sure your boards conform to these design rules. - - - - - - - + + + - - - - - - - - - + + + + + + + + + + @@ -8028,12 +7971,11 @@ Please make sure your boards conform to these design rules. - - - - - - + + + + + @@ -8065,10 +8007,10 @@ Please make sure your boards conform to these design rules. - - - - + + + + @@ -8116,40 +8058,23 @@ Please make sure your boards conform to these design rules. - - - + + + - - - - - + + + + + - - - - - - - - - - - - - - - - - @@ -8183,24 +8108,13 @@ Please make sure your boards conform to these design rules. - - - - - - - - - + + + - - - - - - - + + @@ -8218,151 +8132,261 @@ Please make sure your boards conform to these design rules. - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + - - - - - + + + + + + - - - - - + + + + + + - - - - - + + + + + + - - - - - + + + + + + - - - - - + + + + + + - - - - - + + + + + - - - - - - - + + + + + + - - - - - - - + + + + + + - - - - - - - + + + + + + - - - - - - - + + + + + + - - - - - - - + + + + + + - - - - - - - + + + + + + + + + + diff --git a/pcb/LEDscape.sch b/pcb/LEDscape.sch index d14c123e..2f5c4ad9 100644 --- a/pcb/LEDscape.sch +++ b/pcb/LEDscape.sch @@ -5347,7 +5347,6 @@ Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - @@ -5442,7 +5441,6 @@ Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - @@ -5630,14 +5628,6 @@ Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - - - - - - - @@ -5902,6 +5892,10 @@ Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + + @@ -5995,15 +5989,15 @@ Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - - - + + + + @@ -6012,15 +6006,15 @@ Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - - - + + + + @@ -6063,15 +6057,15 @@ Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - - - + + + + @@ -6080,15 +6074,15 @@ Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - - - + + + + @@ -6452,15 +6446,15 @@ Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - - - + + + + @@ -6469,15 +6463,15 @@ Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - - - + + + + @@ -6673,15 +6667,15 @@ Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - - - + + + + @@ -6690,15 +6684,15 @@ Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - - - + + + + From d9011eda65150e6d15eee841746c7c779596d104 Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Sun, 3 Aug 2014 15:38:29 +0800 Subject: [PATCH 298/332] Receiver 4x: Rev B design --- pcb/receiver-4x.brd | 4877 +------------------------------------------ pcb/receiver-4x.sch | 563 +---- 2 files changed, 160 insertions(+), 5280 deletions(-) diff --git a/pcb/receiver-4x.brd b/pcb/receiver-4x.brd index e737e0fa..964b6391 100644 --- a/pcb/receiver-4x.brd +++ b/pcb/receiver-4x.brd @@ -48,12 +48,12 @@ - - + + - - + + @@ -134,20 +134,20 @@ - - - - - + + + + + - - + + -+ - -RS485 receiver -Rev B 2014-09-1 -@cibomahto ++ - +LEDscape receiver +Rev B 2014-09-2 +By Matt Mets @@ -155,10 +155,10 @@ Rev B 2014-09-1 - - - - + + + + @@ -167,16 +167,16 @@ Rev B 2014-09-1 - - - - + + + + - - - - + + + + @@ -185,10 +185,10 @@ Rev B 2014-09-1 - - - - + + + + @@ -196,26 +196,26 @@ Rev B 2014-09-1 -- + -- + -RJ45 signals: +- + +- + +RJ45 signals: 1. D0+ 2. D0- 3. D1+ 4. N/C -5. N/C +5. N/C 6. D1- 7. GND 8. GND - -- + +- + + - -+ - -+ D - -+ D - -+ D - -+ D - ++ - ++ D - ++ D - ++ D - ++ D - + @@ -296,6 +296,21 @@ Rev B 2014-09-1 + + + + + + + + + + + + +>NAME +>VALUE + @@ -305,27 +320,6 @@ We've spent an enormous amount of time creating and checking these footprints an <br><br> <b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - @@ -1038,4660 +1032,6 @@ chip - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -5883,17 +1223,17 @@ Please make sure your boards conform to these design rules. - - + + - - + + - - + + - - + + @@ -5904,23 +1244,22 @@ Please make sure your boards conform to these design rules. - - + + - - + + - - + + - - + - - + + @@ -5937,10 +1276,10 @@ Please make sure your boards conform to these design rules. - + - + @@ -6022,10 +1361,10 @@ Please make sure your boards conform to these design rules. - + - + @@ -6153,54 +1492,54 @@ Please make sure your boards conform to these design rules. - - - - - - - - + + + + + + + + - - - - - - + + + + + + - - + + - - - - - - + + + + + + - - + + - - - - - - + + + + + + diff --git a/pcb/receiver-4x.sch b/pcb/receiver-4x.sch index efe596d7..87271f88 100644 --- a/pcb/receiver-4x.sch +++ b/pcb/receiver-4x.sch @@ -336,6 +336,21 @@ Source: http://www.maxim-ic.com/package_drawings/21-0041B.pdf + + + + + + + + + + + + +>NAME +>VALUE + @@ -507,6 +522,20 @@ Source: http://www.maxim-ic.com/package_drawings/21-0041B.pdf + + + + + + + + +>VALUE +>NAME + + + + @@ -694,6 +723,25 @@ Source: http://pdfserv.maxim-ic.com/en/ds/MAX3095-MAX3096.pdf + +<b>Header 3</b> +Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08232 with associated crimp pins and housings. + + + + + + + + + + + + + + + + @@ -703,315 +751,6 @@ We've spent an enormous amount of time creating and checking these footprints an <br><br> <b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - -This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place. -You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line). -This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace" -to hold the component in place. 0.005 has proven to be the perfect amount of "off-center" position when using our standard breakaway headers. -Although looks a little odd when you look at the bare footprint, once you have a header in there, the alteration is very hard to notice. Also, -if you push a header all the way into place, it is covered up entirely on the bottom side. This idea of altering the position of holes to aid alignment -will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins. - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - ->NAME ->VALUE - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - ->Name ->Value -+ -- -S - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - ->Name ->Value - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - ->Value ->Name - - - - - - - - - - - - - - - - - - - @@ -1232,20 +971,6 @@ will be further integrated into the Sparkfun Library for other footprints. It c - - - - - - - - ->VALUE ->NAME - - - - @@ -1266,190 +991,6 @@ will be further integrated into the Sparkfun Library for other footprints. It c - -<b>Header 3</b> -Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08232 with associated crimp pins and housings. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <b>Header 5</b> Standard 5-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08230 with associated crimp pins and housings. @@ -6470,10 +6011,10 @@ Standard 2-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - - - + + + + From 05a6a77299cbe9a5fd42d04393f50117f2ef4c1f Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Mon, 4 Aug 2014 00:00:05 +0800 Subject: [PATCH 299/332] Updated BBB footprint, mounting holes in LEDscape baord, small cleanups --- pcb/LEDscape.brd | 284 ++++++++++++++---------- pcb/LEDscape.lbr | 115 +++++++--- pcb/LEDscape.sch | 86 +++++--- pcb/receiver-4x.brd | 514 ++++++++++++++++++++++---------------------- 4 files changed, 580 insertions(+), 419 deletions(-) diff --git a/pcb/LEDscape.brd b/pcb/LEDscape.brd index 437f24c6..f61a9e2a 100644 --- a/pcb/LEDscape.brd +++ b/pcb/LEDscape.brd @@ -36,8 +36,8 @@ - - + + @@ -147,9 +147,9 @@ -LEDscape - - +LEDscape + + @@ -162,7 +162,7 @@ - + @@ -175,7 +175,7 @@ - + @@ -188,7 +188,7 @@ - + @@ -202,13 +202,52 @@ -By Matt Mets +By Matt Mets and Trammell Hudson LEDscape Transmitter -Rev B 2014-08-01 +Rev B 2014-08-01 - + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -270,18 +309,18 @@ http://www.maxim-ic.com .. MAX3223-MAX3243.pdf - - - - - + + + + + - + @@ -321,15 +360,15 @@ http://www.maxim-ic.com .. MAX3223-MAX3243.pdf - - + + - - - - - + + + + + @@ -654,16 +693,17 @@ http://www.maxim-ic.com .. MAX3223-MAX3243.pdf - - - - - - - - - - + + + + + + + + + + + @@ -857,6 +897,22 @@ http://www.maxim-ic.com .. MAX3223-MAX3243.pdf + + + + + + + + + + + + + + + + @@ -6512,7 +6568,7 @@ Please make sure your boards conform to these design rules. - + @@ -6586,8 +6642,8 @@ Please make sure your boards conform to these design rules. - - + + @@ -6650,8 +6706,8 @@ Please make sure your boards conform to these design rules. - - + + @@ -6693,12 +6749,6 @@ Please make sure your boards conform to these design rules. - - - - - - @@ -6744,7 +6794,7 @@ Please make sure your boards conform to these design rules. - + @@ -6780,7 +6830,6 @@ Please make sure your boards conform to these design rules. - @@ -6802,11 +6851,25 @@ Please make sure your boards conform to these design rules. + + + + + + + + + + + + + + + - @@ -7863,7 +7926,8 @@ Please make sure your boards conform to these design rules. - + + @@ -8244,7 +8308,7 @@ Please make sure your boards conform to these design rules. - + @@ -8257,126 +8321,126 @@ Please make sure your boards conform to these design rules. - - + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + diff --git a/pcb/LEDscape.lbr b/pcb/LEDscape.lbr index f0529cee..a7bdef6e 100644 --- a/pcb/LEDscape.lbr +++ b/pcb/LEDscape.lbr @@ -1,12 +1,12 @@ - + - + @@ -135,18 +135,18 @@ - - - - - + + + + + - + @@ -186,15 +186,15 @@ - - + + - - - - - + + + + + @@ -519,16 +519,17 @@ - - - - - - - - - - + + + + + + + + + + + @@ -722,6 +723,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE @@ -864,6 +896,20 @@ + + + + + + + + +>VALUE +>NAME + + + + @@ -1018,6 +1064,25 @@ + +<b>Header 3</b> +Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08232 with associated crimp pins and housings. + + + + + + + + + + + + + + + + diff --git a/pcb/LEDscape.sch b/pcb/LEDscape.sch index 2f5c4ad9..6cb90296 100644 --- a/pcb/LEDscape.sch +++ b/pcb/LEDscape.sch @@ -618,18 +618,18 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - - - - + + + + + - + @@ -669,15 +669,15 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - + + - - - - - + + + + + @@ -1002,16 +1002,17 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - - - - - - - - - + + + + + + + + + + + @@ -1205,6 +1206,22 @@ Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf + + + + + + + + + + + + + + + + @@ -5895,7 +5912,10 @@ Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - + + + + @@ -7184,9 +7204,9 @@ Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 - - - + + + @@ -7196,6 +7216,18 @@ Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-0011 + + + + + + + + + + + + diff --git a/pcb/receiver-4x.brd b/pcb/receiver-4x.brd index 964b6391..6a1bfa2d 100644 --- a/pcb/receiver-4x.brd +++ b/pcb/receiver-4x.brd @@ -132,90 +132,90 @@ - - - - - - - - - - - - -+ - -LEDscape receiver + + + + + + + + + + + + ++ - +LEDscape receiver Rev B 2014-09-2 By Matt Mets - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + -- + -- + -RJ45 signals: +- + +- + +RJ45 signals: 1. D0+ 2. D0- 3. D1+ 4. N/C -5. N/C +5. N/C 6. D1- 7. GND 8. GND - -- + -+ - -+ - -+ D - -+ D - -+ D - -+ D - - + +- + ++ - ++ - ++ D - ++ D - ++ D - ++ D - + @@ -1216,53 +1216,53 @@ Please make sure your boards conform to these design rules. - - - - - + + + + + - - - + + + - - + + - - + + - - + + - - - - - - - - - - - + + + + + + + + + + + - - + + - - + + - - - - - - - + + + + + + + - - + + @@ -1274,19 +1274,19 @@ Please make sure your boards conform to these design rules. - + - - - - + + + + - - - - - - + + + + + + @@ -1296,11 +1296,11 @@ Please make sure your boards conform to these design rules. - + - - - + + + @@ -1308,63 +1308,63 @@ Please make sure your boards conform to these design rules. - - - - - + + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - - + + + + + - - - - + + + + - - - - + + + + @@ -1382,178 +1382,178 @@ Please make sure your boards conform to these design rules. - - - - - - - - + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - + + + + + + - - - - + + + + - - + + - - + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - + + + + - - - - - - - - + + + + + + + + - - - + + + - - - + + + From 902d4d1ca272e67ae3d67a8816b5632b02497440 Mon Sep 17 00:00:00 2001 From: Matthew Mets Date: Sat, 9 Aug 2014 07:45:02 +0000 Subject: [PATCH 300/332] Make consistant whitespace formatting in ws281x.p --- src/ledscape/ws281x.p | 699 +++++++++++++++++++++--------------------- 1 file changed, 351 insertions(+), 348 deletions(-) diff --git a/src/ledscape/ws281x.p b/src/ledscape/ws281x.p index 0cd4a207..006f0b99 100644 --- a/src/ledscape/ws281x.p +++ b/src/ledscape/ws281x.p @@ -15,9 +15,9 @@ //* Reset is 50 usec // // Pins are not contiguous. - // 16 pins on GPIO0: 2 3 4 5 7 12 13 14 15 20 22 23 26 27 30 31 + // 16 pins on GPIO0: 2 3 4 5 7 12 13 14 15 20 22 23 26 27 30 31 // 10 pins on GPIO1: 12 13 14 15 16 17 18 19 28 29 - // 5 pins on GPIO2: 1 2 3 4 5 + // 5 pins on GPIO2: 1 2 3 4 5 // 8 pins on GPIO3: 14 15 16 17 18 19 20 21 // // each pixel is stored in 4 bytes in the order GRBA (4th byte is ignored) @@ -45,117 +45,117 @@ //* //*/ -#define r11_gpio 2 -#define r11_pin 2 -#define g11_gpio 2 -#define g11_pin 3 -#define b11_gpio 2 -#define b11_pin 5 - -#define r12_gpio 0 -#define r12_pin 23 -#define g12_gpio 2 -#define g12_pin 4 -#define b12_gpio 0 -#define b12_pin 26 - -#define r21_gpio 0 -#define r21_pin 27 -#define g21_gpio 2 -#define g21_pin 1 -#define b21_gpio 0 -#define b21_pin 22 - -#define r22_gpio 2 -#define r22_pin 22 -#define g22_gpio 2 -#define g22_pin 23 -#define b22_gpio 2 -#define b22_pin 24 - -#define r31_gpio 0 -#define r31_pin 30 -#define g31_gpio 1 -#define g31_pin 18 -#define b31_gpio 0 -#define b31_pin 31 - -#define r32_gpio 1 -#define r32_pin 16 -#define g32_gpio 0 -#define g32_pin 3 -#define b32_gpio 0 // not working? -#define b32_pin 5 - -#define r41_gpio 0 -#define r41_pin 2 -#define g41_gpio 0 -#define g41_pin 15 -#define b41_gpio 1 -#define b41_pin 17 - -#define r42_gpio 3 -#define r42_pin 21 -#define g42_gpio 3 -#define g42_pin 19 -#define b42_gpio 0 -#define b42_pin 4 - -#define r51_gpio 2 -#define r51_pin 25 -#define g51_gpio 0 -#define g51_pin 11 -#define b51_gpio 0 -#define b51_pin 10 - -#define r52_gpio 0 -#define r52_pin 9 -#define g52_gpio 0 -#define g52_pin 8 -#define b52_gpio 2 -#define b52_pin 17 - -#define r61_gpio 2 -#define r61_pin 16 -#define g61_gpio 2 -#define g61_pin 15 -#define b61_gpio 2 -#define b61_pin 14 - -#define r62_gpio 2 -#define r62_pin 13 -#define g62_gpio 2 -#define g62_pin 10 -#define b62_gpio 2 -#define b62_pin 12 - -#define r71_gpio 2 -#define r71_pin 11 -#define g71_gpio 2 -#define g71_pin 9 -#define b71_gpio 2 -#define b71_pin 8 - -#define r72_gpio 2 -#define r72_pin 6 -#define g72_gpio 0 -#define g72_pin 7 -#define b72_gpio 2 -#define b72_pin 7 - -#define r81_gpio 3 -#define r81_pin 17 -#define g81_gpio 3 -#define g81_pin 16 -#define b81_gpio 3 -#define b81_pin 15 - -#define r82_gpio 3 -#define r82_pin 14 -#define g82_gpio 0 -#define g82_pin 14 -#define b82_gpio 0 -#define b82_pin 20 +#define r11_gpio 2 +#define r11_pin 2 +#define g11_gpio 2 +#define g11_pin 3 +#define b11_gpio 2 +#define b11_pin 5 + +#define r12_gpio 0 +#define r12_pin 23 +#define g12_gpio 2 +#define g12_pin 4 +#define b12_gpio 0 +#define b12_pin 26 + +#define r21_gpio 0 +#define r21_pin 27 +#define g21_gpio 2 +#define g21_pin 1 +#define b21_gpio 0 +#define b21_pin 22 + +#define r22_gpio 2 +#define r22_pin 22 +#define g22_gpio 2 +#define g22_pin 23 +#define b22_gpio 2 +#define b22_pin 24 + +#define r31_gpio 0 +#define r31_pin 30 +#define g31_gpio 1 +#define g31_pin 18 +#define b31_gpio 0 +#define b31_pin 31 + +#define r32_gpio 1 +#define r32_pin 16 +#define g32_gpio 0 +#define g32_pin 3 +#define b32_gpio 0 +#define b32_pin 5 + +#define r41_gpio 0 +#define r41_pin 2 +#define g41_gpio 0 +#define g41_pin 15 +#define b41_gpio 1 +#define b41_pin 17 + +#define r42_gpio 3 +#define r42_pin 21 +#define g42_gpio 3 +#define g42_pin 19 +#define b42_gpio 0 +#define b42_pin 4 + +#define r51_gpio 2 +#define r51_pin 25 +#define g51_gpio 0 +#define g51_pin 11 +#define b51_gpio 0 +#define b51_pin 10 + +#define r52_gpio 0 +#define r52_pin 9 +#define g52_gpio 0 +#define g52_pin 8 +#define b52_gpio 2 +#define b52_pin 17 + +#define r61_gpio 2 +#define r61_pin 16 +#define g61_gpio 2 +#define g61_pin 15 +#define b61_gpio 2 +#define b61_pin 14 + +#define r62_gpio 2 +#define r62_pin 13 +#define g62_gpio 2 +#define g62_pin 10 +#define b62_gpio 2 +#define b62_pin 12 + +#define r71_gpio 2 +#define r71_pin 11 +#define g71_gpio 2 +#define g71_pin 9 +#define b71_gpio 2 +#define b71_pin 8 + +#define r72_gpio 2 +#define r72_pin 6 +#define g72_gpio 0 +#define g72_pin 7 +#define b72_gpio 2 +#define b72_pin 7 + +#define r81_gpio 3 +#define r81_pin 17 +#define g81_gpio 3 +#define g81_pin 16 +#define b81_gpio 3 +#define b81_pin 15 + +#define r82_gpio 3 +#define r82_pin 14 +#define g82_gpio 0 +#define g82_pin 14 +#define b82_gpio 0 +#define b82_pin 20 .origin 0 @@ -164,29 +164,29 @@ #include "ws281x.hp" /** Mappings of the GPIO devices */ -#define GPIO0 0x44E07000 -#define GPIO1 0x4804c000 -#define GPIO2 0x481AC000 -#define GPIO3 0x481AE000 +#define GPIO0 0x44E07000 +#define GPIO1 0x4804c000 +#define GPIO2 0x481AC000 +#define GPIO3 0x481AE000 /** Offsets for the clear and set registers in the devices */ -#define GPIO_CLEARDATAOUT 0x190 -#define GPIO_SETDATAOUT 0x194 +#define GPIO_CLEARDATAOUT 0x190 +#define GPIO_SETDATAOUT 0x194 /** Register map */ -#define data_addr r0 -#define data_len r1 -#define gpio0_zeros r2 -#define gpio1_zeros r3 -#define gpio2_zeros r4 -#define gpio3_zeros r5 -#define bit_num r6 -#define sleep_counter r7 -#define gpio0_led_mask r26 -#define gpio1_led_mask r27 -#define gpio2_led_mask r28 -#define gpio3_led_mask r29 +#define data_addr r0 +#define data_len r1 +#define gpio0_zeros r2 +#define gpio1_zeros r3 +#define gpio2_zeros r4 +#define gpio3_zeros r5 +#define bit_num r6 +#define sleep_counter r7 // r10 - r22 are used for temp storage and bitmap processing +#define gpio0_led_mask r26 +#define gpio1_led_mask r27 +#define gpio2_led_mask r28 +#define gpio3_led_mask r29 /** Sleep a given number of nanoseconds with 10 ns resolution. @@ -197,20 +197,20 @@ .macro SLEEPNS .mparam ns,inst,lab #ifdef CONFIG_WS2812 - MOV sleep_counter, (ns/5)-1-inst // ws2812 -- low speed + MOV sleep_counter, (ns/5)-1-inst // ws2812 -- low speed #else - MOV sleep_counter, (ns/10)-1-inst // ws2811 -- high speed + MOV sleep_counter, (ns/10)-1-inst // ws2811 -- high speed #endif lab: - SUB sleep_counter, sleep_counter, 1 - QBNE lab, sleep_counter, 0 + SUB sleep_counter, sleep_counter, 1 + QBNE lab, sleep_counter, 0 .endm /** Wait for the cycle counter to reach a given value */ .macro WAITNS .mparam ns,lab - MOV r8, 0x22000 // control register + MOV r8, 0x22000 // control register lab: LBBO r9, r8, 0xC, 4 // read the cycle counter SUB r9, r9, sleep_counter @@ -223,142 +223,144 @@ lab: START: - // Enable OCP master port - // clear the STANDBY_INIT bit in the SYSCFG register, - // otherwise the PRU will not be able to write outside the - // PRU memory space and to the BeagleBon's pins. - LBCO r0, C4, 4, 4 - CLR r0, r0, 4 - SBCO r0, C4, 4, 4 - - // Configure the programmable pointer register for PRU0 by setting - // c28_pointer[15:0] field to 0x0120. This will make C28 point to - // 0x00012000 (PRU shared RAM). - MOV r0, 0x00000120 - MOV r1, CTPPR_0 - ST32 r0, r1 - - // Configure the programmable pointer register for PRU0 by setting - // c31_pointer[15:0] field to 0x0010. This will make C31 point to - // 0x80001000 (DDR memory). - MOV r0, 0x00100000 - MOV r1, CTPPR_1 - ST32 r0, r1 - - // Write a 0x1 into the response field so that they know we have started - MOV r2, #0x1 - SBCO r2, CONST_PRUDRAM, 12, 4 + // Enable OCP master port + // clear the STANDBY_INIT bit in the SYSCFG register, + // otherwise the PRU will not be able to write outside the + // PRU memory space and to the BeagleBon's pins. + LBCO r0, C4, 4, 4 + CLR r0, r0, 4 + SBCO r0, C4, 4, 4 + + // Configure the programmable pointer register for PRU0 by setting + // c28_pointer[15:0] field to 0x0120. This will make C28 point to + // 0x00012000 (PRU shared RAM). + MOV r0, 0x00000120 + MOV r1, CTPPR_0 + ST32 r0, r1 + + // Configure the programmable pointer register for PRU0 by setting + // c31_pointer[15:0] field to 0x0010. This will make C31 point to + // 0x80001000 (DDR memory). + MOV r0, 0x00100000 + MOV r1, CTPPR_1 + ST32 r0, r1 + + // Write a 0x1 into the response field so that they know we have started + MOV r2, #0x1 + SBCO r2, CONST_PRUDRAM, 12, 4 #define CAT3(X,Y,Z) X##Y##Z + #define GPIO_MASK(X) CAT3(gpio,X,_led_mask) - SET GPIO_MASK(r11_gpio), r11_pin - SET GPIO_MASK(g11_gpio), g11_pin - SET GPIO_MASK(b11_gpio), b11_pin - SET GPIO_MASK(r12_gpio), r12_pin - SET GPIO_MASK(g12_gpio), g12_pin - SET GPIO_MASK(b12_gpio), b12_pin - - SET GPIO_MASK(r21_gpio), r21_pin - SET GPIO_MASK(g21_gpio), g21_pin - SET GPIO_MASK(b21_gpio), b21_pin - SET GPIO_MASK(r22_gpio), r22_pin - SET GPIO_MASK(g22_gpio), g22_pin - SET GPIO_MASK(b22_gpio), b22_pin - - SET GPIO_MASK(r31_gpio), r31_pin - SET GPIO_MASK(g31_gpio), g31_pin - SET GPIO_MASK(b31_gpio), b31_pin - SET GPIO_MASK(r32_gpio), r32_pin - SET GPIO_MASK(g32_gpio), g32_pin - SET GPIO_MASK(b32_gpio), b32_pin - - SET GPIO_MASK(r41_gpio), r41_pin - SET GPIO_MASK(g41_gpio), g41_pin - SET GPIO_MASK(b41_gpio), b41_pin - SET GPIO_MASK(r42_gpio), r42_pin - SET GPIO_MASK(g42_gpio), g42_pin - SET GPIO_MASK(b42_gpio), b42_pin - - SET GPIO_MASK(r51_gpio), r51_pin - SET GPIO_MASK(g51_gpio), g51_pin - SET GPIO_MASK(b51_gpio), b51_pin - SET GPIO_MASK(r52_gpio), r52_pin - SET GPIO_MASK(g52_gpio), g52_pin - SET GPIO_MASK(b52_gpio), b52_pin - - SET GPIO_MASK(r61_gpio), r61_pin - SET GPIO_MASK(g61_gpio), g61_pin - SET GPIO_MASK(b61_gpio), b61_pin - SET GPIO_MASK(r62_gpio), r62_pin - SET GPIO_MASK(g62_gpio), g62_pin - SET GPIO_MASK(b62_gpio), b62_pin - - SET GPIO_MASK(r71_gpio), r71_pin - SET GPIO_MASK(g71_gpio), g71_pin - SET GPIO_MASK(b71_gpio), b71_pin - SET GPIO_MASK(r72_gpio), r72_pin - SET GPIO_MASK(g72_gpio), g72_pin - SET GPIO_MASK(b72_gpio), b72_pin - - SET GPIO_MASK(r81_gpio), r81_pin - SET GPIO_MASK(g81_gpio), g81_pin - SET GPIO_MASK(b81_gpio), b81_pin - SET GPIO_MASK(r82_gpio), r82_pin - SET GPIO_MASK(g82_gpio), g82_pin - SET GPIO_MASK(b82_gpio), b82_pin - - // Wait for the start condition from the main program to indicate - // that we have a rendered frame ready to clock out. This also - // handles the exit case if an invalid value is written to the start - // start position. + + SET GPIO_MASK(r11_gpio), r11_pin + SET GPIO_MASK(g11_gpio), g11_pin + SET GPIO_MASK(b11_gpio), b11_pin + SET GPIO_MASK(r12_gpio), r12_pin + SET GPIO_MASK(g12_gpio), g12_pin + SET GPIO_MASK(b12_gpio), b12_pin + + SET GPIO_MASK(r21_gpio), r21_pin + SET GPIO_MASK(g21_gpio), g21_pin + SET GPIO_MASK(b21_gpio), b21_pin + SET GPIO_MASK(r22_gpio), r22_pin + SET GPIO_MASK(g22_gpio), g22_pin + SET GPIO_MASK(b22_gpio), b22_pin + + SET GPIO_MASK(r31_gpio), r31_pin + SET GPIO_MASK(g31_gpio), g31_pin + SET GPIO_MASK(b31_gpio), b31_pin + SET GPIO_MASK(r32_gpio), r32_pin + SET GPIO_MASK(g32_gpio), g32_pin + SET GPIO_MASK(b32_gpio), b32_pin + + SET GPIO_MASK(r41_gpio), r41_pin + SET GPIO_MASK(g41_gpio), g41_pin + SET GPIO_MASK(b41_gpio), b41_pin + SET GPIO_MASK(r42_gpio), r42_pin + SET GPIO_MASK(g42_gpio), g42_pin + SET GPIO_MASK(b42_gpio), b42_pin + + SET GPIO_MASK(r51_gpio), r51_pin + SET GPIO_MASK(g51_gpio), g51_pin + SET GPIO_MASK(b51_gpio), b51_pin + SET GPIO_MASK(r52_gpio), r52_pin + SET GPIO_MASK(g52_gpio), g52_pin + SET GPIO_MASK(b52_gpio), b52_pin + + SET GPIO_MASK(r61_gpio), r61_pin + SET GPIO_MASK(g61_gpio), g61_pin + SET GPIO_MASK(b61_gpio), b61_pin + SET GPIO_MASK(r62_gpio), r62_pin + SET GPIO_MASK(g62_gpio), g62_pin + SET GPIO_MASK(b62_gpio), b62_pin + + SET GPIO_MASK(r71_gpio), r71_pin + SET GPIO_MASK(g71_gpio), g71_pin + SET GPIO_MASK(b71_gpio), b71_pin + SET GPIO_MASK(r72_gpio), r72_pin + SET GPIO_MASK(g72_gpio), g72_pin + SET GPIO_MASK(b72_gpio), b72_pin + + SET GPIO_MASK(r81_gpio), r81_pin + SET GPIO_MASK(g81_gpio), g81_pin + SET GPIO_MASK(b81_gpio), b81_pin + SET GPIO_MASK(r82_gpio), r82_pin + SET GPIO_MASK(g82_gpio), g82_pin + SET GPIO_MASK(b82_gpio), b82_pin + + // Wait for the start condition from the main program to indicate + // that we have a rendered frame ready to clock out. This also + // handles the exit case if an invalid value is written to the start + // start position. _LOOP: - // Load the pointer to the buffer from PRU DRAM into r0 and the - // length (in bytes-bit words) into r1. - // start command into r2 - LBCO data_addr, CONST_PRUDRAM, 0, 12 + // Load the pointer to the buffer from PRU DRAM into r0 and the + // length (in bytes-bit words) into r1. + // start command into r2 + LBCO data_addr, CONST_PRUDRAM, 0, 12 - // Wait for a non-zero command - QBEQ _LOOP, r2, #0 + // Wait for a non-zero command + QBEQ _LOOP, r2, #0 - // Zero out the start command so that they know we have received it - // This allows maximum speed frame drawing since they know that they - // can now swap the frame buffer pointer and write a new start command. - MOV r3, 0 - SBCO r3, CONST_PRUDRAM, 8, 4 + // Zero out the start command so that they know we have received it + // This allows maximum speed frame drawing since they know that they + // can now swap the frame buffer pointer and write a new start command. + MOV r3, 0 + SBCO r3, CONST_PRUDRAM, 8, 4 - // Command of 0xFF is the signal to exit - QBEQ EXIT, r2, #0xFF + // Command of 0xFF is the signal to exit + QBEQ EXIT, r2, #0xFF - // The data len is in pixels; convert it to 3 channels * pixels - ADD r2, data_len, data_len - ADD data_len, data_len, r2 + // The data len is in pixels; convert it to 3 channels * pixels + ADD r2, data_len, data_len + ADD data_len, data_len, r2 WORD_LOOP: // for bit in 8 to 0; one color at a time - MOV bit_num, 8 + MOV bit_num, 8 BIT_LOOP: - SUB bit_num, bit_num, 1 + SUB bit_num, bit_num, 1 // The idle period is 650 ns, but this is where // we do all of our work to read the RGB data and // repack it into bit slices. Read the current counter // and then wait until 650 ns have passed once we complete // our work. // Disable the counter and clear it, then re-enable it - MOV r8, 0x22000 // control register - LBBO r9, r8, 0, 4 - CLR r9, r9, 3 // disable counter bit - SBBO r9, r8, 0, 4 // write it back + MOV r8, 0x22000 // control register + LBBO r9, r8, 0, 4 + CLR r9, r9, 3 // disable counter bit + SBBO r9, r8, 0, 4 // write it back - MOV r10, 0 - SBBO r10, r8, 0xC, 4 // clear the timer + MOV r10, 0 + SBBO r10, r8, 0xC, 4 // clear the timer - SET r9, r9, 3 // enable counter bit - SBBO r9, r8, 0, 4 // write it back + SET r9, r9, 3 // enable counter bit + SBBO r9, r8, 0, 4 // write it back // Read the current counter value // Should be zero. - LBBO sleep_counter, r8, 0xC, 4 + LBBO sleep_counter, r8, 0xC, 4 /** Macro to generate the mask of which bits are zero. * For each of these registers, set the @@ -366,126 +368,127 @@ WORD_LOOP: * the current bit is set in the strided register. */ #define TEST_BIT(regN,gpioN,bitN) \ - QBBS gpioN##_##regN##_skip, regN, bit_num; \ - SET gpioN##_zeros, gpioN##_zeros, gpioN##_##bitN ; \ + QBBS gpioN##_##regN##_skip, regN, bit_num; \ + SET gpioN##_zeros, gpioN##_zeros, gpioN##_##bitN ; \ gpioN##_##regN##_skip: ; \ // Load 48 bytes of data, starting at r10 // one byte for each of the outputs - LBBO r10, r0, 0, 48 - MOV gpio0_zeros, 0 - MOV gpio1_zeros, 0 - MOV gpio2_zeros, 0 - MOV gpio3_zeros, 0 + LBBO r10, r0, 0, 48 + MOV gpio0_zeros, 0 + MOV gpio1_zeros, 0 + MOV gpio2_zeros, 0 + MOV gpio3_zeros, 0 -#define GPIO(R) CAT3(gpio,R,_zeros) +#define GPIO(R) CAT3(gpio,R,_zeros) #define OUTPUT_ROW(N,reg_r,reg_g,reg_b) \ - QBBS skip_r##N, reg_r, bit_num; \ - SET GPIO(r##N##_gpio), r##N##_pin; \ + QBBS skip_r##N, reg_r, bit_num; \ + SET GPIO(r##N##_gpio), r##N##_pin; \ skip_r##N: \ - QBBS skip_g##N, reg_g, bit_num; \ - SET GPIO(g##N##_gpio), g##N##_pin; \ + QBBS skip_g##N, reg_g, bit_num; \ + SET GPIO(g##N##_gpio), g##N##_pin; \ skip_g##N: \ - QBBS skip_b##N, reg_b, bit_num; \ - SET GPIO(b##N##_gpio), b##N##_pin; \ + QBBS skip_b##N, reg_b, bit_num; \ + SET GPIO(b##N##_gpio), b##N##_pin; \ skip_b##N: \ - OUTPUT_ROW(11, r10.b0, r10.b1, r10.b2) - OUTPUT_ROW(12, r10.b3, r11.b0, r11.b1) - OUTPUT_ROW(21, r11.b2, r11.b3, r12.b0) - OUTPUT_ROW(22, r12.b1, r12.b2, r12.b3) - - OUTPUT_ROW(31, r13.b0, r13.b1, r13.b2) - OUTPUT_ROW(32, r13.b3, r14.b0, r14.b1) - OUTPUT_ROW(41, r14.b2, r14.b3, r15.b0) - OUTPUT_ROW(42, r15.b1, r15.b2, r15.b3) - - OUTPUT_ROW(51, r16.b0, r16.b1, r16.b2) - OUTPUT_ROW(52, r16.b3, r17.b0, r17.b1) - OUTPUT_ROW(61, r17.b2, r17.b3, r18.b0) - OUTPUT_ROW(62, r18.b1, r18.b2, r18.b3) - - OUTPUT_ROW(71, r19.b0, r19.b1, r19.b2) - OUTPUT_ROW(72, r19.b3, r20.b0, r20.b1) - OUTPUT_ROW(81, r20.b2, r20.b3, r21.b0) - OUTPUT_ROW(82, r21.b1, r21.b2, r21.b3) - - // Now that we have read all of the data, - // we can reuse the registers for the set/clear addresses - // and the masks of which pins are mapped to which LEDs. - MOV r10, GPIO0 | GPIO_SETDATAOUT - MOV r11, GPIO1 | GPIO_SETDATAOUT - MOV r12, GPIO2 | GPIO_SETDATAOUT - MOV r13, GPIO3 | GPIO_SETDATAOUT - - // Wait for 650 ns to have passed - WAITNS 650, wait_start_time - - // Send all the start bits - SBBO gpio0_led_mask, r10, 0, 4 - SBBO gpio1_led_mask, r11, 0, 4 - SBBO gpio2_led_mask, r12, 0, 4 - SBBO gpio3_led_mask, r13, 0, 4 - - // Reconfigure r10-13 for clearing the bits - MOV r10, GPIO0 | GPIO_CLEARDATAOUT - MOV r11, GPIO1 | GPIO_CLEARDATAOUT - MOV r12, GPIO2 | GPIO_CLEARDATAOUT - MOV r13, GPIO3 | GPIO_CLEARDATAOUT - - // wait for the length of the zero bits (250 ns) - WAITNS 650+250, wait_zero_time - //SLEEPNS 250, 1, wait_zero_time - - // turn off all the zero bits - SBBO gpio0_zeros, r10, 0, 4 - SBBO gpio1_zeros, r11, 0, 4 - SBBO gpio2_zeros, r12, 0, 4 - SBBO gpio3_zeros, r13, 0, 4 - - // Wait until the length of the one bits - WAITNS 650+600, wait_one_time - SLEEPNS 500, 1, sleep_one_time - - // Turn all the bits off - SBBO gpio0_led_mask, r10, 0, 4 - SBBO gpio1_led_mask, r11, 0, 4 - SBBO gpio2_led_mask, r12, 0, 4 - SBBO gpio3_led_mask, r13, 0, 4 - - QBNE BIT_LOOP, bit_num, 0 + OUTPUT_ROW(11, r10.b0, r10.b1, r10.b2) + OUTPUT_ROW(12, r10.b3, r11.b0, r11.b1) + OUTPUT_ROW(21, r11.b2, r11.b3, r12.b0) + OUTPUT_ROW(22, r12.b1, r12.b2, r12.b3) + + OUTPUT_ROW(31, r13.b0, r13.b1, r13.b2) + OUTPUT_ROW(32, r13.b3, r14.b0, r14.b1) + OUTPUT_ROW(41, r14.b2, r14.b3, r15.b0) + OUTPUT_ROW(42, r15.b1, r15.b2, r15.b3) + + OUTPUT_ROW(51, r16.b0, r16.b1, r16.b2) + OUTPUT_ROW(52, r16.b3, r17.b0, r17.b1) + OUTPUT_ROW(61, r17.b2, r17.b3, r18.b0) + OUTPUT_ROW(62, r18.b1, r18.b2, r18.b3) + + OUTPUT_ROW(71, r19.b0, r19.b1, r19.b2) + OUTPUT_ROW(72, r19.b3, r20.b0, r20.b1) + OUTPUT_ROW(81, r20.b2, r20.b3, r21.b0) + OUTPUT_ROW(82, r21.b1, r21.b2, r21.b3) + + // Now that we have read all of the data, + // we can reuse the registers for the set/clear addresses + // and the masks of which pins are mapped to which LEDs. + MOV r10, GPIO0 | GPIO_SETDATAOUT + MOV r11, GPIO1 | GPIO_SETDATAOUT + MOV r12, GPIO2 | GPIO_SETDATAOUT + MOV r13, GPIO3 | GPIO_SETDATAOUT + + // Wait for 650 ns to have passed + WAITNS 650, wait_start_time + + // Send all the start bits + SBBO gpio0_led_mask, r10, 0, 4 + SBBO gpio1_led_mask, r11, 0, 4 + SBBO gpio2_led_mask, r12, 0, 4 + SBBO gpio3_led_mask, r13, 0, 4 + + // Reconfigure r10-13 for clearing the bits + MOV r10, GPIO0 | GPIO_CLEARDATAOUT + MOV r11, GPIO1 | GPIO_CLEARDATAOUT + MOV r12, GPIO2 | GPIO_CLEARDATAOUT + MOV r13, GPIO3 | GPIO_CLEARDATAOUT + + // wait for the length of the zero bits (250 ns) + WAITNS 650+250, wait_zero_time + //SLEEPNS 250, 1, wait_zero_time + + // turn off all the zero bits + SBBO gpio0_zeros, r10, 0, 4 + SBBO gpio1_zeros, r11, 0, 4 + SBBO gpio2_zeros, r12, 0, 4 + SBBO gpio3_zeros, r13, 0, 4 + + // Wait until the length of the one bits + // TODO: Fix WAITNS so it can incorporate both delays? + WAITNS 650+600, wait_one_time + SLEEPNS 500, 1, sleep_one_time // Wait a little longer to fix the timing + + // Turn all the bits off + SBBO gpio0_led_mask, r10, 0, 4 + SBBO gpio1_led_mask, r11, 0, 4 + SBBO gpio2_led_mask, r12, 0, 4 + SBBO gpio3_led_mask, r13, 0, 4 + + QBNE BIT_LOOP, bit_num, 0 // The 48 RGB streams have been clocked out // Move to the next color component for each pixel - ADD data_addr, data_addr, 48 - SUB data_len, data_len, 1 - QBNE WORD_LOOP, data_len, #0 + ADD data_addr, data_addr, 48 + SUB data_len, data_len, 1 + QBNE WORD_LOOP, data_len, #0 - // Delay at least 50 usec; this is the required reset - // time for the LED strip to update with the new pixels. - SLEEPNS 50000, 1, reset_time + // Delay at least 50 usec; this is the required reset + // time for the LED strip to update with the new pixels. + SLEEPNS 50000, 1, reset_time - // Write out that we are done! - // Store a non-zero response in the buffer so that they know that we are done - // aso a quick hack, we write the counter so that we know how - // long it took to write out. - MOV r8, 0x22000 // control register - LBBO r2, r8, 0xC, 4 - SBCO r2, CONST_PRUDRAM, 12, 4 + // Write out that we are done! + // Store a non-zero response in the buffer so that they know that we are done + // aso a quick hack, we write the counter so that we know how + // long it took to write out. + MOV r8, 0x22000 // control register + LBBO r2, r8, 0xC, 4 + SBCO r2, CONST_PRUDRAM, 12, 4 - // Go back to waiting for the next frame buffer - QBA _LOOP + // Go back to waiting for the next frame buffer + QBA _LOOP EXIT: - // Write a 0xFF into the response field so that they know we're done - MOV r2, #0xFF - SBCO r2, CONST_PRUDRAM, 12, 4 + // Write a 0xFF into the response field so that they know we're done + MOV r2, #0xFF + SBCO r2, CONST_PRUDRAM, 12, 4 #ifdef AM33XX - // Send notification to Host for program completion - MOV R31.b0, PRU0_ARM_INTERRUPT+16 + // Send notification to Host for program completion + MOV R31.b0, PRU0_ARM_INTERRUPT+16 #else - MOV R31.b0, PRU0_ARM_INTERRUPT + MOV R31.b0, PRU0_ARM_INTERRUPT #endif - HALT + HALT From 1f9402d73ba251db7712abcd0ae5e757b0443247 Mon Sep 17 00:00:00 2001 From: Matthew Mets Date: Sat, 9 Aug 2014 09:13:58 +0000 Subject: [PATCH 301/332] More cleanup and whitespace alignment in ws281x.p --- src/ledscape/ws281x.p | 277 +++++++++++++++++++++--------------------- 1 file changed, 138 insertions(+), 139 deletions(-) diff --git a/src/ledscape/ws281x.p b/src/ledscape/ws281x.p index 006f0b99..addca6e6 100644 --- a/src/ledscape/ws281x.p +++ b/src/ledscape/ws281x.p @@ -15,11 +15,10 @@ //* Reset is 50 usec // // Pins are not contiguous. - // 16 pins on GPIO0: 2 3 4 5 7 12 13 14 15 20 22 23 26 27 30 31 - // 10 pins on GPIO1: 12 13 14 15 16 17 18 19 28 29 - // 5 pins on GPIO2: 1 2 3 4 5 - // 8 pins on GPIO3: 14 15 16 17 18 19 20 21 - // + // 18 pins on GPIO0: 2 3 4 5 7 8 9 10 11 14 15 20 22 23 26 27 30 31 + // 3 pins on GPIO01: 16 17 18 + // 18 pins on GPIO02: 1 4 6 7 8 9 10 11 12 13 14 15 16 17 22 23 24 25 + // 6 pins on GPIO03: 14 15 16 17 19 21 // each pixel is stored in 4 bytes in the order GRBA (4th byte is ignored) // // while len > 0: @@ -85,7 +84,7 @@ #define g32_gpio 0 #define g32_pin 3 #define b32_gpio 0 -#define b32_pin 5 +#define b32_pin 5 #define r41_gpio 0 #define r41_pin 2 @@ -221,6 +220,32 @@ lab: #endif .endm +///** Macro to generate the mask of which bits are zero. +// * For each of these registers, set the +// * corresponding bit in the gpio0_zeros register if +// * the current bit is set in the strided register. +// */ +//#define TEST_BIT(regN,gpioN,bitN) \ +// QBBS gpioN##_##regN##_skip, regN, bit_num; \ +// SET gpioN##_zeros, gpioN##_zeros, gpioN##_##bitN ; \ +// gpioN##_##regN##_skip: ; \ + +#define CAT3(X,Y,Z) X##Y##Z + +#define GPIO_MASK(X) CAT3(gpio,X,_led_mask) + +#define GPIO(R) CAT3(gpio,R,_zeros) + +#define OUTPUT_ROW(N,reg_r,reg_g,reg_b) \ + QBBS skip_r##N, reg_r, bit_num; \ + SET GPIO(r##N##_gpio), r##N##_pin; \ + skip_r##N: \ + QBBS skip_g##N, reg_g, bit_num; \ + SET GPIO(g##N##_gpio), g##N##_pin; \ + skip_g##N: \ + QBBS skip_b##N, reg_b, bit_num; \ + SET GPIO(b##N##_gpio), b##N##_pin; \ + skip_b##N: \ START: // Enable OCP master port @@ -249,11 +274,6 @@ START: MOV r2, #0x1 SBCO r2, CONST_PRUDRAM, 12, 4 -#define CAT3(X,Y,Z) X##Y##Z - -#define GPIO_MASK(X) CAT3(gpio,X,_led_mask) - - SET GPIO_MASK(r11_gpio), r11_pin SET GPIO_MASK(g11_gpio), g11_pin SET GPIO_MASK(b11_gpio), b11_pin SET GPIO_MASK(r12_gpio), r12_pin @@ -335,134 +355,113 @@ _LOOP: ADD r2, data_len, data_len ADD data_len, data_len, r2 -WORD_LOOP: - // for bit in 8 to 0; one color at a time - MOV bit_num, 8 - - BIT_LOOP: - SUB bit_num, bit_num, 1 - // The idle period is 650 ns, but this is where - // we do all of our work to read the RGB data and - // repack it into bit slices. Read the current counter - // and then wait until 650 ns have passed once we complete - // our work. - // Disable the counter and clear it, then re-enable it - MOV r8, 0x22000 // control register - LBBO r9, r8, 0, 4 - CLR r9, r9, 3 // disable counter bit - SBBO r9, r8, 0, 4 // write it back - - MOV r10, 0 - SBBO r10, r8, 0xC, 4 // clear the timer - - SET r9, r9, 3 // enable counter bit - SBBO r9, r8, 0, 4 // write it back - - // Read the current counter value - // Should be zero. - LBBO sleep_counter, r8, 0xC, 4 - -/** Macro to generate the mask of which bits are zero. - * For each of these registers, set the - * corresponding bit in the gpio0_zeros register if - * the current bit is set in the strided register. - */ -#define TEST_BIT(regN,gpioN,bitN) \ - QBBS gpioN##_##regN##_skip, regN, bit_num; \ - SET gpioN##_zeros, gpioN##_zeros, gpioN##_##bitN ; \ - gpioN##_##regN##_skip: ; \ - - // Load 48 bytes of data, starting at r10 - // one byte for each of the outputs - LBBO r10, r0, 0, 48 - MOV gpio0_zeros, 0 - MOV gpio1_zeros, 0 - MOV gpio2_zeros, 0 - MOV gpio3_zeros, 0 - -#define GPIO(R) CAT3(gpio,R,_zeros) -#define OUTPUT_ROW(N,reg_r,reg_g,reg_b) \ - QBBS skip_r##N, reg_r, bit_num; \ - SET GPIO(r##N##_gpio), r##N##_pin; \ - skip_r##N: \ - QBBS skip_g##N, reg_g, bit_num; \ - SET GPIO(g##N##_gpio), g##N##_pin; \ - skip_g##N: \ - QBBS skip_b##N, reg_b, bit_num; \ - SET GPIO(b##N##_gpio), b##N##_pin; \ - skip_b##N: \ - - OUTPUT_ROW(11, r10.b0, r10.b1, r10.b2) - OUTPUT_ROW(12, r10.b3, r11.b0, r11.b1) - OUTPUT_ROW(21, r11.b2, r11.b3, r12.b0) - OUTPUT_ROW(22, r12.b1, r12.b2, r12.b3) - - OUTPUT_ROW(31, r13.b0, r13.b1, r13.b2) - OUTPUT_ROW(32, r13.b3, r14.b0, r14.b1) - OUTPUT_ROW(41, r14.b2, r14.b3, r15.b0) - OUTPUT_ROW(42, r15.b1, r15.b2, r15.b3) - - OUTPUT_ROW(51, r16.b0, r16.b1, r16.b2) - OUTPUT_ROW(52, r16.b3, r17.b0, r17.b1) - OUTPUT_ROW(61, r17.b2, r17.b3, r18.b0) - OUTPUT_ROW(62, r18.b1, r18.b2, r18.b3) - - OUTPUT_ROW(71, r19.b0, r19.b1, r19.b2) - OUTPUT_ROW(72, r19.b3, r20.b0, r20.b1) - OUTPUT_ROW(81, r20.b2, r20.b3, r21.b0) - OUTPUT_ROW(82, r21.b1, r21.b2, r21.b3) - - // Now that we have read all of the data, - // we can reuse the registers for the set/clear addresses - // and the masks of which pins are mapped to which LEDs. - MOV r10, GPIO0 | GPIO_SETDATAOUT - MOV r11, GPIO1 | GPIO_SETDATAOUT - MOV r12, GPIO2 | GPIO_SETDATAOUT - MOV r13, GPIO3 | GPIO_SETDATAOUT - - // Wait for 650 ns to have passed - WAITNS 650, wait_start_time - - // Send all the start bits - SBBO gpio0_led_mask, r10, 0, 4 - SBBO gpio1_led_mask, r11, 0, 4 - SBBO gpio2_led_mask, r12, 0, 4 - SBBO gpio3_led_mask, r13, 0, 4 - - // Reconfigure r10-13 for clearing the bits - MOV r10, GPIO0 | GPIO_CLEARDATAOUT - MOV r11, GPIO1 | GPIO_CLEARDATAOUT - MOV r12, GPIO2 | GPIO_CLEARDATAOUT - MOV r13, GPIO3 | GPIO_CLEARDATAOUT - - // wait for the length of the zero bits (250 ns) - WAITNS 650+250, wait_zero_time - //SLEEPNS 250, 1, wait_zero_time - - // turn off all the zero bits - SBBO gpio0_zeros, r10, 0, 4 - SBBO gpio1_zeros, r11, 0, 4 - SBBO gpio2_zeros, r12, 0, 4 - SBBO gpio3_zeros, r13, 0, 4 - - // Wait until the length of the one bits - // TODO: Fix WAITNS so it can incorporate both delays? - WAITNS 650+600, wait_one_time - SLEEPNS 500, 1, sleep_one_time // Wait a little longer to fix the timing - - // Turn all the bits off - SBBO gpio0_led_mask, r10, 0, 4 - SBBO gpio1_led_mask, r11, 0, 4 - SBBO gpio2_led_mask, r12, 0, 4 - SBBO gpio3_led_mask, r13, 0, 4 - - QBNE BIT_LOOP, bit_num, 0 - - // The 48 RGB streams have been clocked out - // Move to the next color component for each pixel - ADD data_addr, data_addr, 48 - SUB data_len, data_len, 1 - QBNE WORD_LOOP, data_len, #0 + WORD_LOOP: + // for bit in 8 to 0; one color at a time + MOV bit_num, 8 + + BIT_LOOP: + SUB bit_num, bit_num, 1 + // The idle period is 650 ns, but this is where + // we do all of our work to read the RGB data and + // repack it into bit slices. Read the current counter + // and then wait until 650 ns have passed once we complete + // our work. + // Disable the counter and clear it, then re-enable it + MOV r8, 0x22000 // control register + LBBO r9, r8, 0, 4 + CLR r9, r9, 3 // disable counter bit + SBBO r9, r8, 0, 4 // write it back + + MOV r10, 0 + SBBO r10, r8, 0xC, 4 // clear the timer + + SET r9, r9, 3 // enable counter bit + SBBO r9, r8, 0, 4 // write it back + + // Read the current counter value + // Should be zero. + LBBO sleep_counter, r8, 0xC, 4 + + + // Load 48 bytes of data, starting at r10 + // one byte for each of the outputs + LBBO r10, r0, 0, 48 + MOV gpio0_zeros, 0 + MOV gpio1_zeros, 0 + MOV gpio2_zeros, 0 + MOV gpio3_zeros, 0 + + OUTPUT_ROW(11, r10.b0, r10.b1, r10.b2) + OUTPUT_ROW(12, r10.b3, r11.b0, r11.b1) + OUTPUT_ROW(21, r11.b2, r11.b3, r12.b0) + OUTPUT_ROW(22, r12.b1, r12.b2, r12.b3) + + OUTPUT_ROW(31, r13.b0, r13.b1, r13.b2) + OUTPUT_ROW(32, r13.b3, r14.b0, r14.b1) + OUTPUT_ROW(41, r14.b2, r14.b3, r15.b0) + OUTPUT_ROW(42, r15.b1, r15.b2, r15.b3) + + OUTPUT_ROW(51, r16.b0, r16.b1, r16.b2) + OUTPUT_ROW(52, r16.b3, r17.b0, r17.b1) + OUTPUT_ROW(61, r17.b2, r17.b3, r18.b0) + OUTPUT_ROW(62, r18.b1, r18.b2, r18.b3) + + OUTPUT_ROW(71, r19.b0, r19.b1, r19.b2) + OUTPUT_ROW(72, r19.b3, r20.b0, r20.b1) + OUTPUT_ROW(81, r20.b2, r20.b3, r21.b0) + OUTPUT_ROW(82, r21.b1, r21.b2, r21.b3) + + // Now that we have read all of the data, + // we can reuse the registers for the set/clear addresses + // and the masks of which pins are mapped to which LEDs. + MOV r10, GPIO0 | GPIO_SETDATAOUT + MOV r11, GPIO1 | GPIO_SETDATAOUT + MOV r12, GPIO2 | GPIO_SETDATAOUT + MOV r13, GPIO3 | GPIO_SETDATAOUT + + // Wait for 650 ns to have passed + WAITNS 650, wait_start_time + + // Send all the start bits + SBBO gpio0_led_mask, r10, 0, 4 + SBBO gpio1_led_mask, r11, 0, 4 + SBBO gpio2_led_mask, r12, 0, 4 + SBBO gpio3_led_mask, r13, 0, 4 + + // Reconfigure r10-13 for clearing the bits + MOV r10, GPIO0 | GPIO_CLEARDATAOUT + MOV r11, GPIO1 | GPIO_CLEARDATAOUT + MOV r12, GPIO2 | GPIO_CLEARDATAOUT + MOV r13, GPIO3 | GPIO_CLEARDATAOUT + + // wait for the length of the zero bits (250 ns) + WAITNS 650+250, wait_zero_time + //SLEEPNS 250, 1, wait_zero_time + + // turn off all the zero bits + SBBO gpio0_zeros, r10, 0, 4 + SBBO gpio1_zeros, r11, 0, 4 + SBBO gpio2_zeros, r12, 0, 4 + SBBO gpio3_zeros, r13, 0, 4 + + // Wait until the length of the one bits + // TODO: Fix WAITNS so it can incorporate both delays? + WAITNS 650+600, wait_one_time + SLEEPNS 500, 1, sleep_one_time // Wait a little longer to fix the timing + + // Turn all the bits off + SBBO gpio0_led_mask, r10, 0, 4 + SBBO gpio1_led_mask, r11, 0, 4 + SBBO gpio2_led_mask, r12, 0, 4 + SBBO gpio3_led_mask, r13, 0, 4 + + QBNE BIT_LOOP, bit_num, 0 + + // The 48 RGB streams have been clocked out + // Move to the next color component for each pixel + ADD data_addr, data_addr, 48 + SUB data_len, data_len, 1 + QBNE WORD_LOOP, data_len, #0 // Delay at least 50 usec; this is the required reset // time for the LED strip to update with the new pixels. From df0a1628f7ab929648c7ff4bd6008b757090fc92 Mon Sep 17 00:00:00 2001 From: Matthew Mets Date: Sat, 9 Aug 2014 10:04:43 +0000 Subject: [PATCH 302/332] Reassign GPIOs for WS281x mode --- src/ledscape/ws281x.p | 240 +++++++++++++++++++++--------------------- 1 file changed, 122 insertions(+), 118 deletions(-) diff --git a/src/ledscape/ws281x.p b/src/ledscape/ws281x.p index addca6e6..ad1a0bac 100644 --- a/src/ledscape/ws281x.p +++ b/src/ledscape/ws281x.p @@ -1,26 +1,28 @@ // \file - //* WS281x LED strip driver for the BeagleBone Black. - //* - //* Drives up to 32 strips using the PRU hardware. The ARM writes - //* rendered frames into shared DDR memory and sets a flag to indicate - //* how many pixels wide the image is. The PRU then bit bangs the signal - //* out the 32 GPIO pins and sets a done flag. - //* - //* To stop, the ARM can write a 0xFF to the command, which will - //* cause the PRU code to exit. - //* - //* At 800 KHz: - //* 0 is 0.25 usec high, 1 usec low - //* 1 is 0.60 usec high, 0.65 usec low - //* Reset is 50 usec - // - // Pins are not contiguous. - // 18 pins on GPIO0: 2 3 4 5 7 8 9 10 11 14 15 20 22 23 26 27 30 31 - // 3 pins on GPIO01: 16 17 18 - // 18 pins on GPIO02: 1 4 6 7 8 9 10 11 12 13 14 15 16 17 22 23 24 25 - // 6 pins on GPIO03: 14 15 16 17 19 21 - // each pixel is stored in 4 bytes in the order GRBA (4th byte is ignored) - // + /* WS281x LED strip driver for the BeagleBone Black. + * + * Drives up to 32 strips using the PRU hardware. The ARM writes + * rendered frames into shared DDR memory and sets a flag to indicate + * how many pixels wide the image is. The PRU then bit bangs the signal + * out the 32 GPIO pins and sets a done flag. + * + * To stop, the ARM can write a 0xFF to the command, which will + * cause the PRU code to exit. + * + * At 800 KHz: + * 0 is 0.25 usec high, 1 usec low + * 1 is 0.60 usec high, 0.65 usec low + * Reset is 50 usec + * + * Pins are not contiguous. + * 18 pins on GPIO0: 2 3 4 5 7 8 9 10 11 14 15 20 22 23 26 27 30 31 + * 3 pins on GPIO01: 16 17 18 + * 21 pins on GPIO02: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 22 23 24 25 + * 6 pins on GPIO03: 14 15 16 17 19 21 + * each pixel is stored in 4 bytes in the order GRBA (4th byte is ignored) + * + */ + // while len > 0: // for bit# = 24 down to 0: // delay 600 ns @@ -44,117 +46,119 @@ //* //*/ -#define r11_gpio 2 -#define r11_pin 2 -#define g11_gpio 2 -#define g11_pin 3 +#define r11_gpio 2 +#define r11_pin 1 +#define g11_gpio 0 +#define g11_pin 27 #define b11_gpio 2 -#define b11_pin 5 - -#define r12_gpio 0 -#define r12_pin 23 -#define g12_gpio 2 -#define g12_pin 4 -#define b12_gpio 0 -#define b12_pin 26 - -#define r21_gpio 0 -#define r21_pin 27 -#define g21_gpio 2 -#define g21_pin 1 -#define b21_gpio 0 -#define b21_pin 22 - -#define r22_gpio 2 -#define r22_pin 22 -#define g22_gpio 2 -#define g22_pin 23 -#define b22_gpio 2 -#define b22_pin 24 - -#define r31_gpio 0 -#define r31_pin 30 -#define g31_gpio 1 -#define g31_pin 18 -#define b31_gpio 0 -#define b31_pin 31 - -#define r32_gpio 1 -#define r32_pin 16 +#define b11_pin 2 + +#define r12_gpio 2 +#define r12_pin 3 +#define g12_gpio 0 +#define g12_pin 20 +#define b12_gpio 3 +#define b12_pin 16 + +#define r21_gpio 3 +#define r21_pin 19 +#define g21_gpio 0 +#define g21_pin 14 +#define b21_gpio 3 +#define b21_pin 21 + +#define r22_gpio 0 +#define r22_pin 15 +#define g22_gpio 1 +#define g22_pin 17 +#define b22_gpio 0 +#define b22_pin 2 + +#define r31_gpio 1 +#define r31_pin 15 +#define g31_gpio 0 +#define g31_pin 3 +#define b31_gpio 2 +#define b31_pin 22 + +#define r32_gpio 2 +#define r32_pin 24 #define g32_gpio 0 -#define g32_pin 3 +#define g32_pin 4 #define b32_gpio 0 #define b32_pin 5 -#define r41_gpio 0 -#define r41_pin 2 -#define g41_gpio 0 -#define g41_pin 15 +#define r41_gpio 1 +#define r41_pin 19 +#define g41_gpio 1 +#define g41_pin 16 #define b41_gpio 1 -#define b41_pin 17 - -#define r42_gpio 3 -#define r42_pin 21 -#define g42_gpio 3 -#define g42_pin 19 -#define b42_gpio 0 -#define b42_pin 4 - -#define r51_gpio 2 -#define r51_pin 25 -#define g51_gpio 0 -#define g51_pin 11 +#define b41_pin 18 + +#define r42_gpio 0 +#define r42_pin 31 +#define g42_gpio 1 +#define g42_pin 28 +#define b42_gpio 1 +#define b42_pin 14 + +#define r51_gpio 0 +#define r51_pin 30 +#define g51_gpio 1 +#define g51_pin 29 #define b51_gpio 0 -#define b51_pin 10 +#define b51_pin 26 #define r52_gpio 0 -#define r52_pin 9 -#define g52_gpio 0 -#define g52_pin 8 -#define b52_gpio 2 -#define b52_pin 17 +#define r52_pin 23 +#define g52_gpio 1 +#define g52_pin 13 +#define b52_gpio 1 +#define b52_pin 12 #define r61_gpio 2 -#define r61_pin 16 +#define r61_pin 4 #define g61_gpio 2 -#define g61_pin 15 -#define b61_gpio 2 -#define b61_pin 14 - -#define r62_gpio 2 -#define r62_pin 13 -#define g62_gpio 2 -#define g62_pin 10 -#define b62_gpio 2 -#define b62_pin 12 - -#define r71_gpio 2 -#define r71_pin 11 -#define g71_gpio 2 -#define g71_pin 9 -#define b71_gpio 2 -#define b71_pin 8 - -#define r72_gpio 2 -#define r72_pin 6 +#define g61_pin 5 + +// Note: From here down, these are garbage, we only have 32 outputs. +#define b61_gpio 0 +#define b61_pin 1 + +#define r62_gpio 0 +#define r62_pin 1 +#define g62_gpio 0 +#define g62_pin 1 +#define b62_gpio 0 +#define b62_pin 1 + +#define r71_gpio 0 +#define r71_pin 1 +#define g71_gpio 0 +#define g71_pin 1 +#define b71_gpio 0 +#define b71_pin 1 + +#define r72_gpio 0 +#define r72_pin 1 #define g72_gpio 0 -#define g72_pin 7 -#define b72_gpio 2 -#define b72_pin 7 - -#define r81_gpio 3 -#define r81_pin 17 -#define g81_gpio 3 -#define g81_pin 16 -#define b81_gpio 3 -#define b81_pin 15 - -#define r82_gpio 3 -#define r82_pin 14 +#define g72_pin 1 +#define b72_gpio 0 +#define b72_pin 1 + +#define r81_gpio 0 +#define r81_pin 1 +#define g81_gpio 0 +#define g81_pin 1 +#define b81_gpio 0 +#define b81_pin 1 + +#define r82_gpio 0 +#define r82_pin 1 #define g82_gpio 0 -#define g82_pin 14 +#define g82_pin 1 #define b82_gpio 0 -#define b82_pin 20 +#define b82_pin 1 .origin 0 From bd41ef79ecabe304c42396feabc3322120dd970a Mon Sep 17 00:00:00 2001 From: Matthew Mets Date: Fri, 22 Aug 2014 14:13:02 +0000 Subject: [PATCH 303/332] Fix mapping for new LEDscape board, fix bug in matrix-udp-rx --- src/demos/matrix-test.c | 26 ++++--- src/ledscape/ledscape.c | 7 +- src/ledscape/ws281x.p | 160 +++++++++++++++++++++------------------- src/net/matrix-udp-rx.c | 57 +++++--------- strips.config | 2 +- 5 files changed, 124 insertions(+), 128 deletions(-) diff --git a/src/demos/matrix-test.c b/src/demos/matrix-test.c index c7f64859..7ac0bb7c 100644 --- a/src/demos/matrix-test.c +++ b/src/demos/matrix-test.c @@ -98,7 +98,11 @@ rainbow( ) { const unsigned color = cycle % 180; - const unsigned dim = 127; + const unsigned dim = 128; + + static unsigned count = 0; + + count += 1; for (unsigned x=0; x < width; x++) { for (unsigned y=0; y < height; y++) { @@ -110,12 +114,16 @@ rainbow( out[1] = ((in >> 8) & 0xFF) * dim / 128; // * y / 16; out[2] = ((in >> 16) & 0xFF) * dim / 128; // * y / 16; #else - //out[0] = ((in >> 0) & 0xFF); - //out[1] = ((in >> 8) & 0xFF); - //out[2] = ((in >> 16) & 0xFF); - out[0] = y + 3*x + cycle; - out[1] = y + 3*x + cycle; - out[2] = y + 3*x + cycle; + if(y==((count >> 3) & 0x1F) && x<20) { + out[0] = 0xff; + out[1] = 0xff; + out[2] = 0x00; + } + else { + out[0] = 0x00; + out[1] = 0x00; + out[2] = 0xff; + } #endif } } @@ -194,8 +202,8 @@ main( { // int width = 240; // 256; // int height = 64; //128; - int width = 256; - int height = 128; + int width = 135; + int height = 32; ledscape_config_t * config = &ledscape_matrix_default; if (argc > 1) diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index 8ad8bf51..3738c2f8 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -335,12 +335,9 @@ ledscape_strip_draw( uint8_t * const row_out = ledscape_remap(leds, out, x, y); uint32_t p = row_in[x]; - row_out[0*pru_stride] = 0xFF; // green - row_out[1*pru_stride] = 0x00; // red - row_out[2*pru_stride] = 0x00; // blue row_out[0*pru_stride] = (p >> 8) & 0xFF; // green - row_out[1*pru_stride] = (p >> 0) & 0xFF; // red - row_out[2*pru_stride] = (p >> 16) & 0xFF; // blue + row_out[1*pru_stride] = (p >> 16) & 0xFF; // red + row_out[2*pru_stride] = (p >> 0) & 0xFF; // blue } } diff --git a/src/ledscape/ws281x.p b/src/ledscape/ws281x.p index ad1a0bac..da8a48f7 100644 --- a/src/ledscape/ws281x.p +++ b/src/ledscape/ws281x.p @@ -23,19 +23,19 @@ * */ - // while len > 0: - // for bit# = 24 down to 0: - // delay 600 ns - // read 16 registers of data, build zero map for gpio0 - // read 10 registers of data, build zero map for gpio1 - // read 5 registers of data, build zero map for gpio3 - // - // Send start pulse on all pins on gpio0, gpio1 and gpio3 - // delay 250 ns - // bring zero pins low - // delay 300 ns - // bring all pins low - // increment address by 32 +// while len > 0: +// for bit# = 24 down to 0: +// delay 600 ns +// read 16 registers of data, build zero map for gpio0 +// read 10 registers of data, build zero map for gpio1 +// read 5 registers of data, build zero map for gpio3 +// +// Send start pulse on all pins on gpio0, gpio1 and gpio3 +// delay 250 ns +// bring zero pins low +// delay 300 ns +// bring all pins low +// increment address by 32 //* //* So to clock this out: @@ -46,80 +46,80 @@ //* //*/ -#define r11_gpio 2 -#define r11_pin 1 -#define g11_gpio 0 -#define g11_pin 27 -#define b11_gpio 2 -#define b11_pin 2 +#define r11_gpio 0 +#define r11_pin 27 +#define g11_gpio 2 +#define g11_pin 1 +#define b11_gpio 1 +#define b11_pin 14 -#define r12_gpio 2 -#define r12_pin 3 +#define r12_gpio 1 +#define r12_pin 15 #define g12_gpio 0 -#define g12_pin 20 -#define b12_gpio 3 -#define b12_pin 16 - -#define r21_gpio 3 -#define r21_pin 19 -#define g21_gpio 0 -#define g21_pin 14 -#define b21_gpio 3 -#define b21_pin 21 - -#define r22_gpio 0 -#define r22_pin 15 -#define g22_gpio 1 -#define g22_pin 17 -#define b22_gpio 0 +#define g12_pin 23 +#define b12_gpio 0 +#define b12_pin 26 + +#define r21_gpio 1 +#define r21_pin 12 +#define g21_gpio 1 +#define g21_pin 13 +#define b21_gpio 2 +#define b21_pin 5 + +#define r22_gpio 2 +#define r22_pin 4 +#define g22_gpio 2 +#define g22_pin 3 +#define b22_gpio 2 #define b22_pin 2 -#define r31_gpio 1 -#define r31_pin 15 +#define r31_gpio 3 +#define r31_pin 16 #define g31_gpio 0 -#define g31_pin 3 -#define b31_gpio 2 -#define b31_pin 22 +#define g31_pin 20 +#define b31_gpio 0 +#define b31_pin 14 -#define r32_gpio 2 -#define r32_pin 24 +#define r32_gpio 3 +#define r32_pin 19 #define g32_gpio 0 -#define g32_pin 4 -#define b32_gpio 0 -#define b32_pin 5 +#define g32_pin 15 +#define b32_gpio 3 +#define b32_pin 21 -#define r41_gpio 1 -#define r41_pin 19 +#define r41_gpio 0 +#define r41_pin 2 #define g41_gpio 1 -#define g41_pin 16 -#define b41_gpio 1 -#define b41_pin 18 +#define g41_pin 17 +#define b41_gpio 2 +#define b41_pin 22 #define r42_gpio 0 -#define r42_pin 31 -#define g42_gpio 1 -#define g42_pin 28 -#define b42_gpio 1 -#define b42_pin 14 - -#define r51_gpio 0 -#define r51_pin 30 -#define g51_gpio 1 -#define g51_pin 29 -#define b51_gpio 0 -#define b51_pin 26 - -#define r52_gpio 0 -#define r52_pin 23 +#define r42_pin 3 +#define g42_gpio 0 +#define g42_pin 4 +#define b42_gpio 2 +#define b42_pin 24 + +#define r51_gpio 1 +#define r51_pin 19 +#define g51_gpio 0 +#define g51_pin 5 +#define b51_gpio 1 +#define b51_pin 18 + +#define r52_gpio 1 +#define r52_pin 16 #define g52_gpio 1 -#define g52_pin 13 -#define b52_gpio 1 -#define b52_pin 12 +#define g52_pin 28 +#define b52_gpio 0 +#define b52_pin 31 -#define r61_gpio 2 -#define r61_pin 4 -#define g61_gpio 2 -#define g61_pin 5 +#define r61_gpio 1 +#define r61_pin 29 +#define g61_gpio 0 +#define g61_pin 30 // Note: From here down, these are garbage, we only have 32 outputs. #define b61_gpio 0 @@ -240,6 +240,17 @@ lab: #define GPIO(R) CAT3(gpio,R,_zeros) +// Output the current bit for three LED strip outputs +// Note that this nomenclature was ported from the matrix code, and is +// mostly nonsense when applied to the strip code. +// Parameters: +// N: Output group to consider (11, 12, 21, ... 82) +// reg_r: register byte to read first strip data from (ex: r10.b0) +// reg_g: register byte to read second strip data from (ex: r10.b1) +// reg_b: register byte to read third strip data from (ex: r10.b2) +// +// Parameters from the environment: +// bit_num: current bit we're reading from #define OUTPUT_ROW(N,reg_r,reg_g,reg_b) \ QBBS skip_r##N, reg_r, bit_num; \ SET GPIO(r##N##_gpio), r##N##_pin; \ @@ -278,6 +289,7 @@ START: MOV r2, #0x1 SBCO r2, CONST_PRUDRAM, 12, 4 + SET GPIO_MASK(r11_gpio), r11_pin SET GPIO_MASK(g11_gpio), g11_pin SET GPIO_MASK(b11_gpio), b11_pin SET GPIO_MASK(r12_gpio), r12_pin diff --git a/src/net/matrix-udp-rx.c b/src/net/matrix-udp-rx.c index 88881ead..be73095f 100644 --- a/src/net/matrix-udp-rx.c +++ b/src/net/matrix-udp-rx.c @@ -131,6 +131,9 @@ main( break; case 'H': height = atoi(optarg); + if(height%2) { + die("Height must be even!\n"); + } break; case 'm': startup_message = optarg; @@ -146,13 +149,11 @@ main( die("socket port %d failed: %s\n", port, strerror(errno)); const size_t image_size = width * height * 3; + const size_t frame_size = 1 + image_size/2; // largest possible UDP packet - uint8_t *buf = calloc(width*height,4); -#if 0 - if (sizeof(buf) < image_size + 1) - die("%u x %u too large for UDP\n", width, height); -#endif + // 1 header byte + width*height/2 for a half frame + uint8_t *buf = calloc(frame_size,1); fprintf(stderr, "%u x %u, UDP port %u\n", width, height, port); @@ -185,6 +186,7 @@ main( ledscape_printf(fb, width, 0xFF0000, "%s", startup_message); ledscape_printf(fb+16*width, width, 0x00FF00, "%dx%d UDP port %d", width, height, port); ledscape_draw(leds, fb); + ledscape_draw(leds, fb); // TODO: Why do we have to do this twice? while (1) { @@ -207,32 +209,11 @@ main( continue; } - const ssize_t rlen = recv(sock, buf, sizeof(buf), 0); + const ssize_t rlen = recv(sock, buf, frame_size, 0); if (rlen < 0) die("recv failed: %s\n", strerror(errno)); warn_once("received %zu bytes\n", rlen); - /* - if (buf[0] == 2) - { - // image type - printf("image type: %.*s\n", - (int) rlen - 1, - &buf[1] - ); - continue; - } - - if (buf[0] != 1) - { - // What is it? - warn_once("Unknown image type '%c' (%02x)\n", - buf[0], - buf[0] - ); - continue; - } - */ const unsigned frame_part = buf[0]; if (frame_part != 0 && frame_part != 1) { @@ -240,30 +221,28 @@ main( continue; } - if ((size_t) rlen != image_size + 1) + if ((size_t) rlen != frame_size) { - warn_once("WARNING: Received packet %zu bytes, expected %zu\n", + printf("WARNING: Received packet %zu bytes, expected %zu\n", rlen, - image_size + 1 + frame_size ); } struct timeval start_tv, stop_tv, delta_tv; gettimeofday(&start_tv, NULL); - const unsigned frame_num = 0; - // copy the 3-byte values into the 4-byte framebuffer - // and turn onto the side for (unsigned x = 0 ; x < width ; x++) // 256 { - for (unsigned y = 0 ; y < 32 ; y++) // 64 + for (unsigned y = 0 ; y < height ; y++) // 64 { - uint32_t * out = (void*) &fb[(y+32*frame_part)*width + x]; - const uint8_t * const in = &buf[1 + 3*(y*width + x)]; - uint32_t r = in[0]; - uint32_t g = in[1]; - uint32_t b = in[2]; + uint32_t * out = &fb[(height*frame_part + y)*width + x]; + const uint8_t * in = &buf[1 + 3*(y*width + x)]; + + uint8_t r = in[0]; + uint8_t g = in[1]; + uint8_t b = in[2]; *out = (r << 16) | (g << 8) | (b << 0); } } diff --git a/strips.config b/strips.config index b901cb7d..abc53166 100644 --- a/strips.config +++ b/strips.config @@ -1,2 +1,2 @@ ws2812 -240,48 +240,32 From a3d85914b2aeadf450353433bd4ebda5143b3a11 Mon Sep 17 00:00:00 2001 From: Matthew Mets Date: Fri, 22 Aug 2014 14:20:28 +0000 Subject: [PATCH 304/332] Move scripts to src/scripts, remove old udp receiver example --- bin/run-ledscape | 8 -- debian/LEDscape | 2 +- src/net/Makefile | 2 - src/net/udp-rx.c | 84 --------------- {bin => src/script}/bbb-network-setup | 0 {bin => src/script}/find-serial | 0 {bin => src/script}/install | 0 {bin => src/script}/ledscape.service | 4 +- {bin => src/script}/python-test | 0 src/script/run-ledscape | 22 ++++ src/script/run-videoplayer | 28 +++++ {bin => src/script}/twitter-scroller | 0 src/script/videoplayer | 148 ++++++++++++++++++++++++++ src/script/videoplayer.service | 18 ++++ 14 files changed, 219 insertions(+), 97 deletions(-) delete mode 100755 bin/run-ledscape delete mode 100644 src/net/udp-rx.c rename {bin => src/script}/bbb-network-setup (100%) rename {bin => src/script}/find-serial (100%) rename {bin => src/script}/install (100%) rename {bin => src/script}/ledscape.service (74%) rename {bin => src/script}/python-test (100%) create mode 100755 src/script/run-ledscape create mode 100755 src/script/run-videoplayer rename {bin => src/script}/twitter-scroller (100%) mode change 100644 => 100755 create mode 100755 src/script/videoplayer create mode 100755 src/script/videoplayer.service diff --git a/bin/run-ledscape b/bin/run-ledscape deleted file mode 100755 index 1f59f9ae..00000000 --- a/bin/run-ledscape +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -DIRNAME="`dirname "$0"`" -cd "$DIRNAME/.." - -echo CAPE-BONE-OCTO > /sys/devices/bone_capemgr.8/slots -sleep 10 - -exec ./bin/matrix-test >/dev/null diff --git a/debian/LEDscape b/debian/LEDscape index c37853ff..be9c3abd 100755 --- a/debian/LEDscape +++ b/debian/LEDscape @@ -18,7 +18,7 @@ case "$1" in start) echo "Starting LEDscape" # run application you want to start - bash -c 'cd /home/ubuntu/LEDscape/; ./run_ledscape' + bash -c 'cd /home/ubuntu/LEDscape/debian; ./run_ledscape' ;; stop) echo "Stopping LEDscape" diff --git a/src/net/Makefile b/src/net/Makefile index c91a6e53..0d661e20 100755 --- a/src/net/Makefile +++ b/src/net/Makefile @@ -6,12 +6,10 @@ BIN-y += matrix-udp-rx BIN-y += matrix-tcp-rx BIN-y += opc-rx -BIN-n += udp-rx matrix-udp-rx.srcs += matrix-udp-rx.c matrix-tcp-rx.srcs += matrix-tcp-rx.c opc-rx.srcs += opc-rx.c -udp-rx.srcs += udp-rx.c include ../../Makefile.common diff --git a/src/net/udp-rx.c b/src/net/udp-rx.c deleted file mode 100644 index 9b1dda1f..00000000 --- a/src/net/udp-rx.c +++ /dev/null @@ -1,84 +0,0 @@ -/** \file - * UDP image packet receiver. - * - * Based on the HackRockCity LED Display code: - * https://github.com/agwn/pyramidTransmitter/blob/master/LEDDisplay.pde - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "ledscape.h" -#include "pru.h" - -int -main( - int argc, - char ** argv -) -{ - int port = 9999; - int num_pixels = 256; - int num_strips = 32; // not necessarily LEDSCAPE_NUM_STRIPS - - const int sock = socket(AF_INET, SOCK_DGRAM, 0); - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_addr.s_addr = INADDR_ANY, - .sin_port = htons(port), - }; - - if (sock < 0) - die("socket failed: %s\n", strerror(errno)); - if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr)) < 0) - die("bind port %d failed: %s\n", port, strerror(errno)); - - ledscape_t * const leds = ledscape_init(num_pixels); - - unsigned frame_num = 0; - - uint8_t buf[65536]; - - while (1) - { - const ssize_t rc = recv(sock, buf, sizeof(buf), 0); - if (rc < 0) - die("recv failed: %s\n", strerror(errno)); - - if (buf[0] == '2') - { - // image type - printf("image type: %.*s\n", - (int) rc - 1, - &buf[1] - ); - continue; - } - - ledscape_frame_t * const frame - = ledscape_frame(leds, frame_num); - - for(unsigned x=0 ; x < num_pixels ; x++) - { - for(unsigned strip = 0 ; strip < 32 ; strip++) - { - const uint8_t r = buf[x*num_strips+1]; - const uint8_t g = buf[x*num_strips+2]; - const uint8_t b = buf[x*num_strips+3]; - ledscape_set_color(frame, strip, x, r, g, b); - } - } - - ledscape_wait(leds); - ledscape_draw(leds, frame_num); - - frame_num = (frame_num+1) % 2; - } - - ledscape_close(leds); - return 0; -} diff --git a/bin/bbb-network-setup b/src/script/bbb-network-setup similarity index 100% rename from bin/bbb-network-setup rename to src/script/bbb-network-setup diff --git a/bin/find-serial b/src/script/find-serial similarity index 100% rename from bin/find-serial rename to src/script/find-serial diff --git a/bin/install b/src/script/install similarity index 100% rename from bin/install rename to src/script/install diff --git a/bin/ledscape.service b/src/script/ledscape.service similarity index 74% rename from bin/ledscape.service rename to src/script/ledscape.service index a3a5f944..d7144fba 100755 --- a/bin/ledscape.service +++ b/src/script/ledscape.service @@ -8,8 +8,8 @@ Description=BeagleBone LED matrix driver [Service] -WorkingDirectory=/home/root/LEDscape/ -ExecStart=/home/root/LEDscape/bin/run-ledscape +WorkingDirectory=/opt/LEDscape/ +ExecStart=/opt/LEDscape/bin/run-ledscape KillMode=process [Install] diff --git a/bin/python-test b/src/script/python-test similarity index 100% rename from bin/python-test rename to src/script/python-test diff --git a/src/script/run-ledscape b/src/script/run-ledscape new file mode 100755 index 00000000..d488c872 --- /dev/null +++ b/src/script/run-ledscape @@ -0,0 +1,22 @@ +#!/bin/bash +DIRNAME="`dirname "$0"`" +cd "$DIRNAME/.." + +# Enable the octoscroller overlay +# Note that we can't do this at boot because it won't load then, for some reason +echo CAPE-BONE-OCTO > /sys/devices/bone_capemgr*/slots + +# Wait for unknown and unimaginable things to happen +sleep 10 + +CONFIGFILE="$DIRNAME/strips.config" +USBMOUNT="/media/usb0" + +# If a USB stick is mounted, try to load the config file from it +if [ -e "$USBMOUNT/ledscape.config" ] +then + CONFIGFILE="$USBMOUNT/ledscape.config" +fi + +exec ./bin/matrix-test "$CONFIGFILE" >/dev/null +#exec ./bin/matrix-udp-rx -m "Starting LEDscape" -c "$CONFIGFILE" >/dev/null diff --git a/src/script/run-videoplayer b/src/script/run-videoplayer new file mode 100755 index 00000000..b5292d92 --- /dev/null +++ b/src/script/run-videoplayer @@ -0,0 +1,28 @@ +#!/bin/bash +DIRNAME="`dirname "$0"`" +cd "$DIRNAME" + +USBMOUNT="/media/usb0" + +# Wait for a USB drive to be inserted +while true +do + grep -qs $USBMOUNT /proc/mounts + if [ $? -eq 0 ]; then + echo "Mount success!" + break + fi + + sleep 1 +done + + +# Turn on extended filename globbing +shopt -s extglob + +# Play the first video we find, on a loop. +for video in "$USBMOUNT/"*+(.mp4|.MP4|.avi|.AVI) +do + exec ./video_player.py -l -w 112 "$video" + break +done diff --git a/bin/twitter-scroller b/src/script/twitter-scroller old mode 100644 new mode 100755 similarity index 100% rename from bin/twitter-scroller rename to src/script/twitter-scroller diff --git a/src/script/videoplayer b/src/script/videoplayer new file mode 100755 index 00000000..7db21f4d --- /dev/null +++ b/src/script/videoplayer @@ -0,0 +1,148 @@ +#!/usr/bin/python +# Play a video onto the screen + +import cv2, cv +import socket +import numpy +import datetime +import time +import argparse + +parser = argparse.ArgumentParser( + description="Display a video on the LEDscape screen" + ) +parser.add_argument( + "-s", "--screenGeometry", + dest="screenGeometry", + help="LEDscape screen size (ex: 256x128)", + default="256x128", + ) +parser.add_argument( + "-w", "--scaleWidth", + dest="scaleWidth", + help="Width to scale video to during playback (ex: 256)", + default="256", + type=int, + ) +parser.add_argument( + "-a", "--address", + dest="address", + help="TCP address to connect to (ex: localhost)", + default="localhost", + ) +parser.add_argument( + "-p", "--port", + dest="port", + help="TCP port to send data to (ex: 9999)", + default=9999, + type=int, + ) +parser.add_argument( + "-l", "--loop", + action="store_true", + dest="loop", + help="Loop the video continuously", + default=False, + ) +parser.add_argument( + dest="filename", + help="Filename to load", + ) + +config = parser.parse_args() + +# LEDscape screen geometry +screenWidth = int(config.screenGeometry.split('x')[0]) +screenHeight = int(config.screenGeometry.split('x')[1]) + +# If the screen height is not a divisor of 2, then the subframe scheme won't work. +if screenHeight % 2: + print "Error, screen height must be a multiple of 2!" + exit(1) + +# LEDscape packet geometry +# Note: SubframeCount *must* be an integer divider of screenHeight!! +# Note: This is designed for large screen support, a la the megasidescroller +# Small screens only need one frame to transmit, so set subFrameCount to 1. +subFrameCount = 2 +subFrameHeight = screenHeight / subFrameCount +subFrameSize = 1 + subFrameHeight*screenWidth*3 + +# LEDscape message setup +message = numpy.zeros(subFrameSize*subFrameCount, numpy.uint8); +for subFrame in range(0, subFrameCount): + message[subFrame*subFrameSize] = subFrame + +# Socket to send to +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +sock.setsockopt(socket.SOL_SOCKET,socket.SO_SNDBUF,int(subFrameSize)) + +# Test if the frame size is acceptable +# TODO: Fix this +if sock.getsockopt(socket.SOL_SOCKET,socket.SO_SNDBUF) < subFrameSize: + print "Error configuring TCP socket: buffer too big (reduce LEDscape image size?)" + exit(1) + +# Open the video for playback +cap = cv2.VideoCapture(config.filename) + + +# Test that the video was loaded +if not cap.isOpened(): + print "Error opening video: Check that the file exists and the format is correct" + exit(1) + +fps = cap.get(cv.CV_CAP_PROP_FPS) +frameDelay = 1.0/fps + +nextTime = time.time() + frameDelay + +while cap.isOpened(): + # Get the video frame + ret, frame = cap.read() + + # If we've reached the end, reset the position to the beginning + if not ret: + if config.loop: + cap.set(cv.CV_CAP_PROP_POS_MSEC, 0) + ret, frame = cap.read() + else: + exit(0) + + # Resize the video to be the width that we actually want + originalHeight = frame.shape[0] + originalWidth = frame.shape[1] + originalAspect = float(originalWidth)/originalHeight + + scaleWidth = config.scaleWidth + scaleHeight = int(scaleWidth/originalAspect) + + smaller = cv2.resize(frame,(scaleWidth, scaleHeight)) + frame = smaller + + # Copy the image data into the LEDscape format + frameHeight = frame.shape[0] + frameWidth = frame.shape[1] + + flattenedFrame = frame.reshape(frameHeight, frameWidth*3) + + copyWidth = min(screenWidth, frameWidth) + copyHeight = min(screenHeight, frameHeight) + + copyLength = copyWidth*3 + + for row in range(0, copyHeight): + offset = 1 + (row / subFrameHeight) + messageOffset = (row*screenWidth)*3 + offset + + message[messageOffset:messageOffset+copyLength] = flattenedFrame[row, 0:copyLength] + + # Send the data to the LEDscape host + for subFrame in range(0, subFrameCount): + sock.sendto(message[subFrame*subFrameSize:(subFrame+1)*subFrameSize], (config.address, config.port)) + + # Delay until it's time to show the next frame. + while time.time() < nextTime: + pass + + nextTime += frameDelay diff --git a/src/script/videoplayer.service b/src/script/videoplayer.service new file mode 100755 index 00000000..7e258cd3 --- /dev/null +++ b/src/script/videoplayer.service @@ -0,0 +1,18 @@ +# +# Copy this file to /etc/systemd/system/ and run: +# systemctl enable videoplayer.service +# to enable videoplayer to start on each boot. +# + +[Unit] +Description=LEDscape video player +Requires=ledscape +After=ledscape + +[Service] +WorkingDirectory=/opt/LEDscape/bin +ExecStart=/opt/LEDscape/bin/run-videoplayer +KillMode=process + +[Install] +WantedBy=multi-user.target From 5c45eadbefdb94d5094183daa824d9e0880da2b7 Mon Sep 17 00:00:00 2001 From: Matthew Mets Date: Fri, 22 Aug 2014 14:37:26 +0000 Subject: [PATCH 305/332] Add makefile rule to copy scripts, extended setup instructions --- .gitignore | 2 +- Makefile | 1 + Setup.md | 153 ++++++++++++++++++++++++++++++++++++++++++++ radials.config | 2 + src/script/Makefile | 18 ++++++ 5 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 Setup.md create mode 100644 radials.config create mode 100644 src/script/Makefile diff --git a/.gitignore b/.gitignore index 725666a9..869ac7be 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,4 @@ am335x/pasm/pasm .*.d *~ *~ -a.out +bin/* diff --git a/Makefile b/Makefile index c14e8d26..e09bfaf4 100755 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ SUBDIR-y += src/demos SUBDIR-y += src/perlin SUBDIR-y += src/mta SUBDIR-y += src/net +SUBDIR-y += src/script all: for dir in $(SUBDIR-y); do \ diff --git a/Setup.md b/Setup.md new file mode 100644 index 00000000..5873fb33 --- /dev/null +++ b/Setup.md @@ -0,0 +1,153 @@ +Getting Started +=============== + +This is a quick introduction on how to set up LEDscape on a Debian-based image + +Setting up the BBB environment +============================== + +To develop for LEDscape on a Debian environment, Start by copying the latest BBB image to an SD card. These instructions were made using version bone-debian-7.5-2014-05-14-2gb.img. The latest version can be found at: + + http://elinux.org/BeagleBoardDebian#Demo_Image + +First, we need to expand the image to use the whole SD card. By default, it is only 2GB. + + cd /opt/scripts/tools/ + sudo ./grow_partition.sh + sudo reboot + +Next, update the the Debian environment: + + sudo apt-get update + sudo apt-get install usbmount + +Disable the HDMI output: + + sudo sed -i 's/#cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN/cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN'/g /boot/uboot/uEnv.txt + sudo reboot + +Note: These packages used to be required, but now are included in the default image. You might need to install them if you're using a different Debian system. + + sudo apt-get install git build-essential + +Next, set up LEDscape: +====================== + +Use git to download the repository: + + cd /opt + sudo git clone http://github.com/osresearch/LEDscape.git + cd LEDscape + sudo make + +Copy the device tree file into place, and add it to the slots: + + sudo cp dts/CAPE-BONE-OCTO-00A0.dtbo /lib/firmware + echo 'CAPE-BONE-OCTO' | sudo tee -a /sys/devices/bone_capemgr.9/slots + +Then run the identification program to test if all is well: + + sudo bin/identify + +Make a configuration file for your screen +========================================= + +The configuration file is what tells LEDscape how to draw it's virtual screen onto your matrix tiles or LED strips. There are two basic formats: + +Matrix screen +------------- + +Let's look at a sample matrix configuration. Here's one for a small display consisting of 4 LED matricies, arranged in a square: + + matrix16 + 0,6 N 0,0 + 0,7 N 32,0 + 1,6 N 0,16 + 2,7 N 32,16 + +The first line of the configuration file describes the type of matrix. Here are the valid matrix types: + +| Type | Description | +| ------------- |:-------------:| +| matrix16 | 32x16 LED matrix, 1/8th scanning (three address pins) | + +Each following line consists of three sets of information: Controller position, Rotation, and LEDscape virtual screen offset. + +The controller position consists of two values. The first is the output channel. This corresponds to the physical output that the matrix is plugged into on the board. There are 8 outputs available on the OCTOscroller shield. The second is the position in the output chain. This one is a little more tricky, as it is backwards from you might expect. The *first* matrix panel in the chain, which is the one connected to the OCTOscroller shield, is called 7. The second one is called 6, and so on, until the eighth and final one. For example, a single matrix panel connected to output #3 has the following controller position: + + 3,7 + +The rotation is any one of the following values: N, U, L, R. 'N' and 'U' are used when the long side of the panel is parallel to the ground, and 'L' and 'R' are used when it is perpendicular. Try one, then the other, to figure out the correct orientation for your panels. + +The Virtual screen offset is the top-left position in the LEDscape virtual screen that will be drawn to this matrix panel. Normally you will want to map sections of the screen into contigouos regions, so the top-left panel in your display should have a virtual screen offset of 0,0, then the panel to the right of that one should be offset by the width of the first panel, either 16,0 or 32,0, and so on. + + +WS2812 strips +------------- + +Let's look at a sample WS2812 strip configuration. Here's one that can control a single strip output: + + ws2812 + 64,48 + +The first line of the configuration file describes the type of matrix. Here are the valid matrix types: + +| Type | Description | +| ------------- |:-------------:| +| ws2812 | Strip of WS2812/WS2812B LEDs, aka NeoPixels | + +TODO: What do the next numbers here mean? + +Testing your configuration +-------------------------- + +For matricies, there is a handy identification program to draw some text that identifies each panel. Run it to test your new configuration: + + sudo bin/identify myconfig.config + + +Set up the UDP listener to display incoming packets +=================================================== + +To run the matrix listener: + + sudo bin/matrix-udp-rx -W 256 -H 32 -c sign.config & + +Or for WS2812B strips: + + sudo bin/matrix-udp-rx -W 256 -H 32 -c strips.config & + +There are a bunch of command line arguments, and the whole thing seems to be in a bit of flux. Here's what exists now: + +| Argument | Description | Default | +| ------------- |:-------------:| -----:| +| -v | Verbose mode | | +| -n | Skip LEDscape initialization | | +| -c | Configuration file to use. Note: Use full pathname, for example: /home/debian/LEDscape/default.config | | +| -t | Number of seconds the display server will show the previous image before timing out | 60 | +| -W | LEDscape virtual screen width | 256 | +| -H | LEDscape virtual screen height | 128 | +| -m | Message to display at startup | | + + +Run the UDP listener automatically at system boot +================================================= + + sudo cp bin/ledscape.service /etc/systemd/system + sudo systemctl enable ledscape.service + + sudo cp bin/videoplayer.service /etc/systemd/system + sudo systemctl enable videoplayer.service + +Video playback +============== + +Playing a video is as simple as running the video player (after running the UDP listener): + + bin/video_player.py -s 256x32 -l ../Daft\ Punk\ -\ Around\ The\ World.avi + +Note: These packages used to be required, but now are included in the default image. You might need to install them if you're using a different Debian system. + + sudo apt-get install libavformat-dev x264 v4l-utils ffmpeg + sudo apt-get install libcv2.3 libcvaux2.3 libhighgui2.3 python-opencv opencv-doc libcv-dev libcvaux-dev libhighgui-dev + diff --git a/radials.config b/radials.config new file mode 100644 index 00000000..8ebecc7a --- /dev/null +++ b/radials.config @@ -0,0 +1,2 @@ +ws2812 +135,32 diff --git a/src/script/Makefile b/src/script/Makefile new file mode 100644 index 00000000..b2ef5e82 --- /dev/null +++ b/src/script/Makefile @@ -0,0 +1,18 @@ + +BINDIR = ../../bin/ + +FILES = bbb-network-setup \ + find-serial \ + install \ + ledscape.service \ + python-test \ + run-ledscape \ + run-videoplayer \ + twitter-scroller \ + videoplayer \ + videoplayer.service + +all: copy + +copy: + cp -f $(FILES) $(BINDIR) From a3bb94d04cdffd0a36216da44928b1d796bad868 Mon Sep 17 00:00:00 2001 From: Matthew Mets Date: Fri, 22 Aug 2014 15:19:27 +0000 Subject: [PATCH 306/332] Document upstart startup script --- Setup.md | 47 +++++++++++++++++++++++++------------------- debian/LEDscape | 34 -------------------------------- ubuntu/ledscape.conf | 9 +++++++++ 3 files changed, 36 insertions(+), 54 deletions(-) delete mode 100755 debian/LEDscape create mode 100644 ubuntu/ledscape.conf diff --git a/Setup.md b/Setup.md index 5873fb33..d1e89b74 100644 --- a/Setup.md +++ b/Setup.md @@ -1,10 +1,8 @@ -Getting Started -=============== +# Getting Started This is a quick introduction on how to set up LEDscape on a Debian-based image -Setting up the BBB environment -============================== +# Setting up the BBB environment To develop for LEDscape on a Debian environment, Start by copying the latest BBB image to an SD card. These instructions were made using version bone-debian-7.5-2014-05-14-2gb.img. The latest version can be found at: @@ -30,8 +28,7 @@ Note: These packages used to be required, but now are included in the default im sudo apt-get install git build-essential -Next, set up LEDscape: -====================== +# Next, set up LEDscape: Use git to download the repository: @@ -49,13 +46,11 @@ Then run the identification program to test if all is well: sudo bin/identify -Make a configuration file for your screen -========================================= +# Make a configuration file for your screen The configuration file is what tells LEDscape how to draw it's virtual screen onto your matrix tiles or LED strips. There are two basic formats: -Matrix screen -------------- +## Matrix screen Let's look at a sample matrix configuration. Here's one for a small display consisting of 4 LED matricies, arranged in a square: @@ -82,8 +77,7 @@ The rotation is any one of the following values: N, U, L, R. 'N' and 'U' are use The Virtual screen offset is the top-left position in the LEDscape virtual screen that will be drawn to this matrix panel. Normally you will want to map sections of the screen into contigouos regions, so the top-left panel in your display should have a virtual screen offset of 0,0, then the panel to the right of that one should be offset by the width of the first panel, either 16,0 or 32,0, and so on. -WS2812 strips -------------- +## WS2812 strips Let's look at a sample WS2812 strip configuration. Here's one that can control a single strip output: @@ -98,16 +92,14 @@ The first line of the configuration file describes the type of matrix. Here are TODO: What do the next numbers here mean? -Testing your configuration --------------------------- +## Testing your configuration For matricies, there is a handy identification program to draw some text that identifies each panel. Run it to test your new configuration: sudo bin/identify myconfig.config -Set up the UDP listener to display incoming packets -=================================================== +# Set up the UDP listener to display incoming packets To run the matrix listener: @@ -130,23 +122,38 @@ There are a bunch of command line arguments, and the whole thing seems to be in | -m | Message to display at startup | | -Run the UDP listener automatically at system boot -================================================= +# Run the UDP listener automatically at system boot + +There's a handy script for starting LEDscape at boot. It should listen on the ethernet interface on port 9999 automatically. + +## Ubuntu + +Ubuntu appears to use upstart. Do this: + + sudo cp ubuntu/ledscape.conf /etc/init + sudo start ledscape + +## Debian / Angstrom + +Debian and Angstrom appear to be able to use systemd. Do this: sudo cp bin/ledscape.service /etc/systemd/system sudo systemctl enable ledscape.service +Extra: for video playback + sudo cp bin/videoplayer.service /etc/systemd/system sudo systemctl enable videoplayer.service + Video playback ============== Playing a video is as simple as running the video player (after running the UDP listener): - bin/video_player.py -s 256x32 -l ../Daft\ Punk\ -\ Around\ The\ World.avi + bin/video_player -s 256x32 -l ../Daft\ Punk\ -\ Around\ The\ World.avi -Note: These packages used to be required, but now are included in the default image. You might need to install them if you're using a different Debian system. +Note: These packages used to be required, but now are included in the default Debian image. You might need to install them if you're using a different system. sudo apt-get install libavformat-dev x264 v4l-utils ffmpeg sudo apt-get install libcv2.3 libcvaux2.3 libhighgui2.3 python-opencv opencv-doc libcv-dev libcvaux-dev libhighgui-dev diff --git a/debian/LEDscape b/debian/LEDscape deleted file mode 100755 index be9c3abd..00000000 --- a/debian/LEDscape +++ /dev/null @@ -1,34 +0,0 @@ -#! /bin/sh -# /etc/init.d/LEDscape - -### BEGIN INIT INFO -# Provides: LEDscape -# Required-Start: -# Required-Stop: -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Run the LEDscape scuplture -# Description: loads the correct DTS file and then the LEDscape -### END INIT INFO - -# If you want a command to always run, put it here - -# Carry out specific functions when asked to by the system -case "$1" in - start) - echo "Starting LEDscape" - # run application you want to start - bash -c 'cd /home/ubuntu/LEDscape/debian; ./run_ledscape' - ;; - stop) - echo "Stopping LEDscape" - # kill application you want to stop - killall matrix-test - ;; - *) - echo "Usage: /etc/init.d/LEDscape {start|stop}" - exit 1 - ;; -esac - -exit 0 diff --git a/ubuntu/ledscape.conf b/ubuntu/ledscape.conf new file mode 100644 index 00000000..e0d0e89a --- /dev/null +++ b/ubuntu/ledscape.conf @@ -0,0 +1,9 @@ +# +# This task runs at boot to start the LEDscape service + +description "start LEDscape udp-rx receiver" + +start on startup + +task +exec /opt/LEDscape/bin/run-ledscape From 10948d3506b85fbc774704db75f62908bcdbf2f0 Mon Sep 17 00:00:00 2001 From: Matt Mets Date: Sat, 23 Aug 2014 00:37:12 +0800 Subject: [PATCH 307/332] Add pin assignments chart for LEDscape trasnsmitter board --- pcb/LEDscape pin assignments.csv | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 pcb/LEDscape pin assignments.csv diff --git a/pcb/LEDscape pin assignments.csv b/pcb/LEDscape pin assignments.csv new file mode 100644 index 00000000..8f2b7c07 --- /dev/null +++ b/pcb/LEDscape pin assignments.csv @@ -0,0 +1,33 @@ +Signal,Header/Pin,Port +S00,P8-18,GPIO2_01 +S01,P8-17,GPIO0_27 +S02,P8-15,GPIO1_15 +S03,P8-16,GPIO1_14 +S04,P8-14,GPIO0_26 +S05,P8-13,GPIO0_23 +S06,P8-11,GPIO1_13 +S07,P8-12,GPIO1_12 +S08,P8-10,GPIO2_04 +S09,P8-09,GPIO2_05 +S10,P8-07,GPIO2_02 +S11,P8-08,GPIO2_03 +S12,P9-41,GPIO0_20 +S13,P9-30,GPIO3_16 +S14,P9-27,GPIO3_19 +S15,P9-26,GPIO0_14 +S16,P9-25,GPIO3_21 +S17,P9-24,GPIO0_15 +S18,P9-23,GPIO1_17 +S19,P9-22,GPIO0_02 +S20,P9-21,GPIO0_03 +S21,P8-27,GPIO2_22 +S22,P8-28,GPIO2_24 +S23,P9-18,GPIO0_04 +S24,P9-17,GPIO0_05 +S25,P9-16,GPIO1_19 +S26,P9-15,GPIO1_16 +S27,P9-14,GPIO1_18 +S28,P9-13,GPIO0_31 +S29,P9-12,GPIO1_28 +S30,P9-11,GPIO0_30 +S31,P8-26,GPIO1_29 From a240d87cdaa47db63f1b972ac07fae0d0334108b Mon Sep 17 00:00:00 2001 From: Trammell Hudson Date: Sun, 7 Sep 2014 13:50:44 -0400 Subject: [PATCH 308/332] create empty bin directory --- bin/.empty | 1 + 1 file changed, 1 insertion(+) create mode 100644 bin/.empty diff --git a/bin/.empty b/bin/.empty new file mode 100644 index 00000000..078f480b --- /dev/null +++ b/bin/.empty @@ -0,0 +1 @@ +git: please make this directory From aea845da701657096fb20ff6ed7431ed369549b2 Mon Sep 17 00:00:00 2001 From: Matthew Mets Date: Sun, 14 Sep 2014 01:16:54 +0800 Subject: [PATCH 309/332] Update Setup.md --- Setup.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Setup.md b/Setup.md index d1e89b74..ae054102 100644 --- a/Setup.md +++ b/Setup.md @@ -18,15 +18,21 @@ Next, update the the Debian environment: sudo apt-get update sudo apt-get install usbmount + sudo apt-get install git build-essential Disable the HDMI output: - sudo sed -i 's/#cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN/cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN'/g /boot/uboot/uEnv.txt +If you are using a Debian image from 2014.8.13 or newer, do this: + + sudo sed -i 's/#cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN/cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN'/g /boot/uEnv.txt sudo reboot -Note: These packages used to be required, but now are included in the default image. You might need to install them if you're using a different Debian system. +If you are using an older Debian image, do this: - sudo apt-get install git build-essential + sudo sed -i 's/#cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN/cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN'/g /boot/uboot/uEnv.txt + sudo reboot + +Otherwise, modify the uEnv boot file to disable HDMI and HDMIN overlays, then reboot. # Next, set up LEDscape: @@ -40,7 +46,7 @@ Use git to download the repository: Copy the device tree file into place, and add it to the slots: sudo cp dts/CAPE-BONE-OCTO-00A0.dtbo /lib/firmware - echo 'CAPE-BONE-OCTO' | sudo tee -a /sys/devices/bone_capemgr.9/slots + echo 'CAPE-BONE-OCTO' | sudo tee -a /sys/devices/bone_capemgr.*/slots Then run the identification program to test if all is well: From 9f96f25ac0c2ca6ffad11cc6bbaeb0854c8381f2 Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Wed, 17 Sep 2014 21:12:16 -0700 Subject: [PATCH 310/332] Fixes to allow configuration of 32x32 panels. Fixes to allow configuration of fewer than 8 ports --- src/ledscape/ledscape.c | 80 +++++++++++++++++++++++++++++++---------- src/ledscape/matrix.p | 49 +++++++++++++++++++++++-- 2 files changed, 109 insertions(+), 20 deletions(-) diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index 3738c2f8..9d711e39 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -31,20 +31,40 @@ * * \todo: Find a way to unify this with the defines in the .p file */ -static const uint8_t gpios0[] = { - 23, 27, 22, 10, 9, 8, 26, 11, 30, 31, 5, 3, 20, 4, 2, 14, 7, 15 +static const uint8_t gpios_output1[] = { + 2,2,2,3,2,5,0,23,2,4,0,26 }; -static const uint8_t gpios1[] = { - 13, 15, 12, 14, 29, 16, 17, 28, 18, 19, +static const uint8_t gpios_output2[] = { + 0,27,2,1,0,22,2,22,2,23,2,24 }; -static const uint8_t gpios2[] = { - 2, 5, 22, 23, 14, 12, 10, 8, 6, 3, 4, 1, 24, 25, 17, 16, 15, 13, 11, 9, 7, +static const uint8_t gpios_output3[] = { + 0,30,1,18,0,31,1,16,0,3,0,5 }; -static const uint8_t gpios3[] = { - 21, 19, 15, 14, 17, 16 +static const uint8_t gpios_output4[] = { + 0,2,0,15,1,17,3,21,3,19,0,4,1,19 +}; + +static const uint8_t gpios_output5[] = { + 2,25,0,11,0,10,0,9,0,8,2,17 +}; + +static const uint8_t gpios_output6[] = { + 2,16,2,15,2,14,2,13,2,10,2,12 +}; + +static const uint8_t gpios_output7[] = { + 2,11,2,9,2,8,2,6,0,7,2,7 +}; + +static const uint8_t gpios_output8[] = { + 3,17,3,16,3,15,3,14,0,14,0,20 +}; + +static const uint8_t gpios_output_all[] = { + 1,12,1,13,1,14,1,15,1,28,1,29,1,19 }; #define ARRAY_COUNT(a) ((sizeof(a) / sizeof(*a))) @@ -59,14 +79,38 @@ static const uint8_t gpios3[] = { static void ledscape_gpio_init(void) { - for (unsigned i = 0 ; i < ARRAY_COUNT(gpios0) ; i++) - pru_gpio(0, gpios0[i], 1, 0); - for (unsigned i = 0 ; i < ARRAY_COUNT(gpios1) ; i++) - pru_gpio(1, gpios1[i], 1, 0); - for (unsigned i = 0 ; i < ARRAY_COUNT(gpios2) ; i++) - pru_gpio(2, gpios2[i], 1, 0); - for (unsigned i = 0 ; i < ARRAY_COUNT(gpios3) ; i++) - pru_gpio(3, gpios3[i], 1, 0); + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios_output1) ; i+=2) + pru_gpio(gpios_output1[i], gpios_output1[i+1], 1, 0); +#if LEDSCAPE_MATRIX_OUTPUTS > 1 + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios_output2) ; i+=2) + pru_gpio(gpios_output2[i], gpios_output2[i+1], 1, 0); +#endif +#if LEDSCAPE_MATRIX_OUTPUTS > 2 + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios_output3) ; i+=2) + pru_gpio(gpios_output3[i], gpios_output3[i+1], 1, 0); +#endif +#if LEDSCAPE_MATRIX_OUTPUTS > 3 + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios_output4) ; i+=2) + pru_gpio(gpios_output4[i], gpios_output4[i+1], 1, 0); +#endif +#if LEDSCAPE_MATRIX_OUTPUTS > 4 + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios_output5) ; i+=2) + pru_gpio(gpios_output5[i], gpios_output5[i+1], 1, 0); +#endif +#if LEDSCAPE_MATRIX_OUTPUTS > 5 + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios_output6) ; i+=2) + pru_gpio(gpios_output6[i], gpios_output6[i+1], 1, 0); +#endif +#if LEDSCAPE_MATRIX_OUTPUTS > 6 + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios_output7) ; i+=2) + pru_gpio(gpios_output7[i], gpios_output7[i+1], 1, 0); +#endif +#if LEDSCAPE_MATRIX_OUTPUTS > 7 + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios_output8) ; i+=2) + pru_gpio(gpios_output8[i], gpios_output8[i+1], 1, 0); +#endif + for (unsigned i = 0 ; i < ARRAY_COUNT(gpios_output_all) ; i+=2) + pru_gpio(gpios_output_all[i], gpios_output_all[i+1], 1, 0); } @@ -241,7 +285,7 @@ ledscape_matrix_panel_copy( // the top half and bottom half of the panels // are squished together in the output since // they are drawn simultaneously. - uint8_t * const pix = &out[x*row_stride + (y/8)*3 + (y%8)*row_len]; + uint8_t * const pix = &out[x*row_stride + (y/(config->panel_height/2))*3 + (y%(config->panel_height/2))*row_len]; pix[0] = (col >> 16) & 0xFF; // red pix[1] = (col >> 8) & 0xFF; // green @@ -397,7 +441,7 @@ ledscape_matrix_init( *(leds->ws281x) = (ws281x_command_t) { .pixels_dma = 0, // will be set in draw routine - .num_pixels = (config->leds_width * 3) * 16, + .num_pixels = (config->leds_width * 3) * (LEDSCAPE_MATRIX_OUTPUTS * 2), .command = 0, .response = 0, }; diff --git a/src/ledscape/matrix.p b/src/ledscape/matrix.p index b9fe7031..02a8951e 100644 --- a/src/ledscape/matrix.p +++ b/src/ledscape/matrix.p @@ -26,6 +26,7 @@ // 4 is a ok brightness, 5 is bright, 6 is powerful #define BRIGHT_SHIFT 5 +#define NUMBER_OUTPUTS 8 #define r11_gpio 2 #define r11_pin 2 @@ -41,6 +42,7 @@ #define b12_gpio 0 #define b12_pin 26 +#if NUMBER_OUTPUTS > 1 #define r21_gpio 0 #define r21_pin 27 #define g21_gpio 2 @@ -54,7 +56,9 @@ #define g22_pin 23 #define b22_gpio 2 #define b22_pin 24 +#endif +#if NUMBER_OUTPUTS > 2 #define r31_gpio 0 #define r31_pin 30 #define g31_gpio 1 @@ -68,7 +72,9 @@ #define g32_pin 3 #define b32_gpio 0 // not working? #define b32_pin 5 +#endif +#if NUMBER_OUTPUTS > 3 #define r41_gpio 0 #define r41_pin 2 #define g41_gpio 0 @@ -87,7 +93,9 @@ #define g42_pin 19 #define b42_gpio 0 #define b42_pin 4 +#endif +#if NUMBER_OUTPUTS > 4 #define r51_gpio 2 #define r51_pin 25 #define g51_gpio 0 @@ -101,7 +109,9 @@ #define g52_pin 8 #define b52_gpio 2 #define b52_pin 17 +#endif +#if NUMBER_OUTPUTS > 5 #define r61_gpio 2 #define r61_pin 16 #define g61_gpio 2 @@ -115,7 +125,9 @@ #define g62_pin 10 #define b62_gpio 2 #define b62_pin 12 +#endif +#if NUMBER_OUTPUTS > 6 #define r71_gpio 2 #define r71_pin 11 #define g71_gpio 2 @@ -129,7 +141,9 @@ #define g72_pin 7 #define b72_gpio 2 #define b72_pin 7 +#endif +#if NUMBER_OUTPUTS > 7 #define r81_gpio 3 #define r81_pin 17 #define g81_gpio 3 @@ -143,6 +157,7 @@ #define g82_pin 14 #define b82_gpio 0 #define b82_pin 20 +#endif #define CAT3(X,Y,Z) X##Y##Z @@ -290,55 +305,68 @@ START: SET GPIO_MASK(g12_gpio), g12_pin SET GPIO_MASK(b12_gpio), b12_pin +#if NUMBER_OUTPUTS > 1 SET GPIO_MASK(r21_gpio), r21_pin SET GPIO_MASK(g21_gpio), g21_pin SET GPIO_MASK(b21_gpio), b21_pin SET GPIO_MASK(r22_gpio), r22_pin SET GPIO_MASK(g22_gpio), g22_pin SET GPIO_MASK(b22_gpio), b22_pin +#endif +#if NUMBER_OUTPUTS > 2 SET GPIO_MASK(r31_gpio), r31_pin SET GPIO_MASK(g31_gpio), g31_pin SET GPIO_MASK(b31_gpio), b31_pin SET GPIO_MASK(r32_gpio), r32_pin SET GPIO_MASK(g32_gpio), g32_pin SET GPIO_MASK(b32_gpio), b32_pin +#endif +#if NUMBER_OUTPUTS > 3 SET GPIO_MASK(r41_gpio), r41_pin SET GPIO_MASK(g41_gpio), g41_pin SET GPIO_MASK(b41_gpio), b41_pin SET GPIO_MASK(r42_gpio), r42_pin SET GPIO_MASK(g42_gpio), g42_pin SET GPIO_MASK(b42_gpio), b42_pin +#endif +#if NUMBER_OUTPUTS > 4 SET GPIO_MASK(r51_gpio), r51_pin SET GPIO_MASK(g51_gpio), g51_pin SET GPIO_MASK(b51_gpio), b51_pin SET GPIO_MASK(r52_gpio), r52_pin SET GPIO_MASK(g52_gpio), g52_pin SET GPIO_MASK(b52_gpio), b52_pin +#endif +#if NUMBER_OUTPUTS > 5 SET GPIO_MASK(r61_gpio), r61_pin SET GPIO_MASK(g61_gpio), g61_pin SET GPIO_MASK(b61_gpio), b61_pin SET GPIO_MASK(r62_gpio), r62_pin SET GPIO_MASK(g62_gpio), g62_pin SET GPIO_MASK(b62_gpio), b62_pin +#endif +#if NUMBER_OUTPUTS > 6 SET GPIO_MASK(r71_gpio), r71_pin SET GPIO_MASK(g71_gpio), g71_pin SET GPIO_MASK(b71_gpio), b71_pin SET GPIO_MASK(r72_gpio), r72_pin SET GPIO_MASK(g72_gpio), g72_pin SET GPIO_MASK(b72_gpio), b72_pin +#endif +#if NUMBER_OUTPUTS > 7 SET GPIO_MASK(r81_gpio), r81_pin SET GPIO_MASK(g81_gpio), g81_pin SET GPIO_MASK(b81_gpio), b81_pin SET GPIO_MASK(r82_gpio), r82_pin SET GPIO_MASK(g82_gpio), g82_pin SET GPIO_MASK(b82_gpio), b82_pin - +#endif //MOV clock_pin, 1 << gpio1_clock READ_LOOP: @@ -412,23 +440,40 @@ NEW_ROW_LOOP: OUTPUT_ROW(11, r18.b0, r18.b1, r18.b2) OUTPUT_ROW(12, r18.b3, r19.b0, r19.b1) +#if NUMBER_OUTPUTS > 1 OUTPUT_ROW(21, r19.b2, r19.b3, r20.b0) OUTPUT_ROW(22, r20.b1, r20.b2, r20.b3) +#endif +#if NUMBER_OUTPUTS > 2 OUTPUT_ROW(31, r21.b0, r21.b1, r21.b2) OUTPUT_ROW(32, r21.b3, r22.b0, r22.b1) +#endif + +#if NUMBER_OUTPUTS > 3 OUTPUT_ROW(41, r22.b2, r22.b3, r23.b0) OUTPUT_ROW(42, r23.b1, r23.b2, r23.b3) +#endif +#if NUMBER_OUTPUTS > 4 OUTPUT_ROW(51, r24.b0, r24.b1, r24.b2) OUTPUT_ROW(52, r24.b3, r25.b0, r25.b1) +#endif + +#if NUMBER_OUTPUTS > 5 OUTPUT_ROW(61, r25.b2, r25.b3, r26.b0) OUTPUT_ROW(62, r26.b1, r26.b2, r26.b3) +#endif +#if NUMBER_OUTPUTS > 6 OUTPUT_ROW(71, r27.b0, r27.b1, r27.b2) OUTPUT_ROW(72, r27.b3, r28.b0, r28.b1) +#endif + +#if NUMBER_OUTPUTS > 7 OUTPUT_ROW(81, r28.b2, r28.b3, r29.b0) OUTPUT_ROW(82, r29.b1, r29.b2, r29.b3) +#endif // reload the gpio*_base registers // since we have overwritten them with our pixel data @@ -496,7 +541,7 @@ NEW_ROW_LOOP: #endif - ADD offset, offset, 3*16 + ADD offset, offset, 3*(NUMBER_OUTPUTS*2) QBNE PIXEL_LOOP, offset, width // Full data has been clocked out; latch it From 3d43f24da9328c92d7581d200d808c9c76c7e934 Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Wed, 4 Feb 2015 21:03:35 -0800 Subject: [PATCH 311/332] Update the configuration to handle a 64x64 display made up of one chain of 4 32x32 panels --- src/demos/fire.c | 2 +- src/ledscape/ledscape.c | 31 +++++++++---------------------- src/ledscape/ledscape.h | 5 ++--- src/ledscape/matrix.p | 6 +++--- 4 files changed, 15 insertions(+), 29 deletions(-) diff --git a/src/demos/fire.c b/src/demos/fire.c index 8e0b9673..ee4b2689 100644 --- a/src/demos/fire.c +++ b/src/demos/fire.c @@ -12,7 +12,7 @@ #include "ledscape.h" // sideways pyramid; 256 height, but 128 wide -#define WIDTH 512 +#define WIDTH 64 #define HEIGHT 64 diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index 9d711e39..02e6e31c 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -611,7 +611,6 @@ ledscape_draw_char( } } - /** Write with a fixed-width 8px font */ void ledscape_printf( @@ -647,37 +646,25 @@ ledscape_printf( } } - /** Default ledscape config */ #define DEFAULT_MATRIX(i) { \ - { 0*32, i*16, 0 }, \ - { 1*32, i*16, 0 }, \ - { 2*32, i*16, 0 }, \ - { 3*32, i*16, 0 }, \ - { 4*32, i*16, 0 }, \ - { 5*32, i*16, 0 }, \ - { 6*32, i*16, 0 }, \ - { 7*32, i*16, 0 }, \ + { 0*32, i*32, 0 }, \ + { 1*32, i*32, 0 }, \ + { 0*32, (i+1)*32, 0 }, \ + { 1*32, (i+1)*32, 0 }, \ } \ ledscape_config_t ledscape_matrix_default = { .matrix_config = { .type = LEDSCAPE_MATRIX, - .width = 256, - .height = 128, + .width = 64, + .height = 64, .panel_width = 32, - .panel_height = 16, - .leds_width = 256, - .leds_height = 128, + .panel_height = 32, + .leds_width = 128, + .leds_height = 32, .panels = { DEFAULT_MATRIX(0), - DEFAULT_MATRIX(1), - DEFAULT_MATRIX(2), - DEFAULT_MATRIX(3), - DEFAULT_MATRIX(4), - DEFAULT_MATRIX(5), - DEFAULT_MATRIX(6), - DEFAULT_MATRIX(7), }, }, }; diff --git a/src/ledscape/ledscape.h b/src/ledscape/ledscape.h index f3f19aad..71cf7198 100644 --- a/src/ledscape/ledscape.h +++ b/src/ledscape/ledscape.h @@ -27,8 +27,8 @@ typedef struct { int rot; // 0 == none, 1 == left, 2 == right, 3 == flip } ledscape_matrix_panel_t; -#define LEDSCAPE_MATRIX_OUTPUTS 8 // number of outputs on the cape -#define LEDSCAPE_MATRIX_PANELS 8 // number of panels chained per output +#define LEDSCAPE_MATRIX_OUTPUTS 1 // number of outputs on the cape +#define LEDSCAPE_MATRIX_PANELS 4 // number of panels chained per output typedef struct { int type; @@ -145,7 +145,6 @@ ledscape_printf( ... ); - /** Parse a config file */ ledscape_config_t * ledscape_config( diff --git a/src/ledscape/matrix.p b/src/ledscape/matrix.p index 02a8951e..fd5fadc5 100644 --- a/src/ledscape/matrix.p +++ b/src/ledscape/matrix.p @@ -16,7 +16,7 @@ * To pause the redraw loop, write a NULL to the buffer pointer. * To shut down the PRU, write -1 to the buffer pointer. */ -#if 1 +#if 0 #define MATRIX_HEIGHT 8 // 32x16 matrices #else #define MATRIX_HEIGHT 16 // 32x32 matrices @@ -24,9 +24,9 @@ // higher constants == brighter. // 4 is a ok brightness, 5 is bright, 6 is powerful -#define BRIGHT_SHIFT 5 +#define BRIGHT_SHIFT 3 -#define NUMBER_OUTPUTS 8 +#define NUMBER_OUTPUTS 1 #define r11_gpio 2 #define r11_pin 2 From 7564b72c428d86bca079e6d17a1de73f214e835b Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Wed, 4 Feb 2015 21:51:29 -0800 Subject: [PATCH 312/332] Games in all the wrong directories --- Makefile.common | 9 +- dts/cape-bone-octo.dts | 78 +------ src/demos/Makefile | 10 + src/demos/ball_sprite.cc | 49 ++++ src/demos/ball_sprite.hh | 20 ++ src/demos/black.c | 82 +++++++ src/demos/brick_sprite.hh | 20 ++ src/demos/bricks.cc | 328 +++++++++++++++++++++++++++ src/demos/controls.cc | 69 ++++++ src/demos/controls.hh | 29 +++ src/demos/gpio_pin.cc | 45 ++++ src/demos/gpio_pin.hh | 16 ++ src/demos/invaders.cc | 311 +++++++++++++++++++++++++ src/demos/png.cc | 74 ++++++ src/demos/png.hh | 27 +++ src/demos/pong.cc | 308 +++++++++++++++++++++++++ src/demos/robin-hood-test.c | 436 ++++++++++++++++++++++++++++++++++++ src/demos/screen.cc | 76 +++++++ src/demos/screen.hh | 26 +++ src/demos/sprite.cc | 85 +++++++ src/demos/sprite.hh | 36 +++ src/demos/white.c | 82 +++++++ src/script/run-ledscape | 6 +- 23 files changed, 2145 insertions(+), 77 deletions(-) create mode 100644 src/demos/ball_sprite.cc create mode 100644 src/demos/ball_sprite.hh create mode 100644 src/demos/black.c create mode 100644 src/demos/brick_sprite.hh create mode 100644 src/demos/bricks.cc create mode 100644 src/demos/controls.cc create mode 100644 src/demos/controls.hh create mode 100644 src/demos/gpio_pin.cc create mode 100644 src/demos/gpio_pin.hh create mode 100644 src/demos/invaders.cc create mode 100644 src/demos/png.cc create mode 100644 src/demos/png.hh create mode 100644 src/demos/pong.cc create mode 100644 src/demos/robin-hood-test.c create mode 100644 src/demos/screen.cc create mode 100644 src/demos/screen.hh create mode 100644 src/demos/sprite.cc create mode 100644 src/demos/sprite.hh create mode 100644 src/demos/white.c diff --git a/Makefile.common b/Makefile.common index b593402c..3e629717 100644 --- a/Makefile.common +++ b/Makefile.common @@ -38,7 +38,7 @@ GENERIC_CFLAGS += \ -Wp,-MT,$@ \ -I. \ -I$(TOP)/src/ledscape \ - -O2 \ + -O0 \ -mtune=cortex-a8 \ -march=armv7-a \ @@ -48,6 +48,7 @@ CFLAGS += \ CPPFLAGS += \ $(GENERIC_CFLAGS) \ + -std=c++11 LDFLAGS += \ @@ -56,8 +57,12 @@ LDLIBS += \ -lledscape \ -lpthread \ -lm \ + -lpng \ + -lSDL \ + -lSDL_mixer COMPILE.c-o = $(CROSS_COMPILE)gcc $(CFLAGS) -c -o $@ $< +COMPILE.cc-o = $(CROSS_COMPILE)g++ $(CPPFLAGS) -c -o $@ $< COMPILE.cpp-o = $(CROSS_COMPILE)g++ $(CPPFLAGS) -c -o $@ $< COMPILE.a = $(CROSS_COMPILE)ar crv $@ $^ COMPILE.link = $(CROSS_COMPILE)g++ $(LDFLAGS) -o $@ $^ $(LDLIBS) @@ -66,6 +71,8 @@ $(OBJDIR)/%.o: %.c $(COMPILE.c-o) $(OBJDIR)/%.o: %.cpp $(COMPILE.cpp-o) +$(OBJDIR)/%.o: %.cc + $(COMPILE.cc-o) $(LIBDIR)/%.a: $(RM) $@ diff --git a/dts/cape-bone-octo.dts b/dts/cape-bone-octo.dts index d8db6b59..9074163a 100644 --- a/dts/cape-bone-octo.dts +++ b/dts/cape-bone-octo.dts @@ -1,20 +1,6 @@ /* * pru dts file BB-BONE-PRU-00A0.dts * -* Available outputs on pru 0 and their r30 pins: -* p9.31: 0 -* p9.29: 1 -* p9.30: 2 -* p9.28: 3 -* p9.27: 5 -* p9.25: 7 -* p8.12: 14 -* p8.11: 15 - -gpio 0: 23, 27, 22, 10, 9, 8, 26, 11, 30, 31, 5, 3, 20, 4, 2, 14, 7 -gpio 1: 13, 15, 12, 14, 29, 16, 17, 28, 18, 19, -gpio 2: 2, 5, 22, 23, 14, 12, 10, 8, 6, 3, 4, 1, 24, 25, 17, 16, 15, 13, 11, 9, 7, -gpio 3: 21, 19, 15, 14, 17, 16 */ /dts-v1/; @@ -28,21 +14,12 @@ gpio 3: 21, 19, 15, 14, 17, 16 version = "00A0"; exclusive-use = -//gpio 0: 23, 27, 22, 10, 9, 8, 26, 11, 30, 31, 5, 3, 20, 4, 2, 14, 7 - "P9.11", "P9.12", "P9.13", "P9.14", "P9.15", "P9.16", "P9.17", - "P9.18", - - "P9.21", "P9.22", "P9.23", "P9.24", "P9.25", "P9.26", - "P9.27", "P9.28", "P9.29", "P9.30", - - "P9.41", "P9.42", + "P9.12", "P9.16", "P8.7", "P8.8", "P8.9", "P8.10", "P8.11", "P8.12", "P8.13", - "P8.14", "P8.15", "P8.16", "P8.17", "P8.18", "P8.19", + "P8.14", "P8.15", "P8.16", - "P8.26", "P8.27", "P8.28", "P8.29", "P8.30", "P8.31", "P8.32", - "P8.33", "P8.34", "P8.35", "P8.36", "P8.37", "P8.38", "P8.39", - "P8.40", "P8.41", "P8.42", "P8.43", "P8.44", "P8.45", "P8.46", + "P8.26", "pruss", "ehrpwm1B"; @@ -53,32 +30,8 @@ gpio 3: 21, 19, 15, 14, 17, 16 mygpio: pinmux_mygpio { pinctrl-single,pins = < // p9.11-18 - 0x070 0x7 0x078 0x7 - 0x074 0x7 - 0x048 0x7 - 0x040 0x7 0x04c 0x7 // P9.16 could be PWM for output enable - 0x15c 0x7 - 0x158 0x7 - - // p9.21-29 - 0x154 0x7 - 0x150 0x7 - 0x044 0x7 - 0x184 0x7 - //0x1AC 0x5 // PRU0 r30.7 for the clock line - 0x1AC 0x7 // GPIO - 0x180 0x7 - 0x1A4 0x7 - 0x19C 0x7 - 0x194 0x7 - - // p9.41-42, but alternate functions to input - 0x1B4 0x7 // gpio0.20 as output - 0x164 0x7 // gpio0.7 as output - 0x1A8 0x27 // gpio3.18 as input - 0x1A0 0x27 // gpio3.18 as input // p8.7-19 0x090 0x7 @@ -91,34 +44,9 @@ gpio 3: 21, 19, 15, 14, 17, 16 0x028 0x7 0x03c 0x7 0x038 0x7 - 0x02c 0x7 - 0x08c 0x7 - 0x020 0x7 // p8.26-46 0x07c 0x7 - 0x0e0 0x7 - 0x0e8 0x7 - 0x0e4 0x7 - 0x0ec 0x7 - 0x0d8 0x7 - 0x0dc 0x7 - 0x0d4 0x7 - 0x0cc 0x7 - 0x0d4 0x7 - 0x0cc 0x7 - 0x0d0 0x7 - 0x0c8 0x7 - 0x0c0 0x7 - 0x0c4 0x7 - 0x0b8 0x7 - 0x0bc 0x7 - 0x0b0 0x7 - 0x0b4 0x7 - 0x0a8 0x7 - 0x0ac 0x7 - 0x0a0 0x7 - 0x0a4 0x7 >; }; }; diff --git a/src/demos/Makefile b/src/demos/Makefile index 5d23ac93..5a5dc871 100755 --- a/src/demos/Makefile +++ b/src/demos/Makefile @@ -8,12 +8,22 @@ BIN-y += life BIN-y += cube-life BIN-y += matrix-test BIN-y += identify +BIN-y += breakout +BIN-y += black +BIN-y += white +BIN-y += pong +BIN-y += invaders fire.srcs += fire.c life.srcs += life.c identify.srcs += identify.c cube-life.srcs += cube-life.c matrix-test.srcs += matrix-test.c +breakout.srcs += bricks.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_sprite.cc +black.srcs += black.c +white.srcs += white.c +pong.srcs += pong.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_sprite.cc +invaders.srcs += invaders.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_sprite.cc png.cc include ../../Makefile.common diff --git a/src/demos/ball_sprite.cc b/src/demos/ball_sprite.cc new file mode 100644 index 00000000..476583cc --- /dev/null +++ b/src/demos/ball_sprite.cc @@ -0,0 +1,49 @@ +#include "ball_sprite.hh" + +ball_sprite_t::ball_sprite_t() : + sprite_t(), + wall_left_(true), + wall_right_(true), + wall_up_(true), + wall_down_(true) +{ +} + +void ball_sprite_t::move_sprite(void) { + sprite_t::move_sprite(); + + if (wall_left_) { + if ((x_ < 0.0f) && (dx_ < 0)) { + x_ = 0.0f; + dx_ = -dx_; + } + } + + if (wall_right_) { + if ((x_ > 63.0f) && (dx_ > 0)) { + x_ = 63.0f; + dx_ = -dx_; + } + } + + if (wall_up_) { + if ((y_ < 0.0f) && (dy_ < 0)) { + y_ = 0.0f; + dy_ = -dy_; + } + } + + if (wall_down_) { + if ((y_ > 63.0f) && (dy_ > 0)) { + y_ = 63.0f; + dy_ = -dy_; + } + } +} + +void ball_sprite_t::set_walls(bool up, bool down, bool left, bool right) { + wall_left_ = left; + wall_right_ = right; + wall_up_ = up; + wall_down_ = down; +} diff --git a/src/demos/ball_sprite.hh b/src/demos/ball_sprite.hh new file mode 100644 index 00000000..3cfb0857 --- /dev/null +++ b/src/demos/ball_sprite.hh @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +#include "sprite.hh" + +class ball_sprite_t : public sprite_t { +public: + ball_sprite_t(); + + virtual void move_sprite(void) override; + void set_walls(bool up, bool down, bool left, bool right); + +private: + bool wall_left_; + bool wall_right_; + bool wall_up_; + bool wall_down_; +}; diff --git a/src/demos/black.c b/src/demos/black.c new file mode 100644 index 00000000..fe9adf6a --- /dev/null +++ b/src/demos/black.c @@ -0,0 +1,82 @@ +/** \file + * Test the matrix LCD PRU firmware with a multi-hue rainbow. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "ledscape.h" + +void drawpixel(uint32_t *pixels, uint8_t x, uint8_t y, uint32_t color, uint8_t flip) { + uint32_t pixelnum = ((flip ? (64 - y) : y) * 64) + (flip ? (64 - x ) : x); + pixels[pixelnum] = color; +} + +void render_game(uint32_t *pixels) { + for (int y_clear = 0; y_clear < 64; y_clear++) { + for (int x_clear = 0; x_clear < 64; x_clear++) { + drawpixel(pixels, x_clear, y_clear, 0x00000000, 0); + } + } +} + +int +main( + int argc, + const char ** argv +) +{ + int width = 64; + int height = 64; + + ledscape_config_t * config = &ledscape_matrix_default; + if (argc > 1) + { + config = ledscape_config(argv[1]); + if (!config) + return EXIT_FAILURE; + } + + if (config->type == LEDSCAPE_MATRIX) + { + config->matrix_config.width = width; + config->matrix_config.height = height; + } + + ledscape_t * const leds = ledscape_init(config, 0); + + printf("init done\n"); + time_t last_time = time(NULL); + unsigned last_i = 0; + + unsigned i = 0; + uint32_t * const p = calloc(width*height,4); + + render_game(p); + + i++; + ledscape_draw(leds, p); + + usleep(20000); + + // wait for the previous frame to finish; + //const uint32_t response = ledscape_wait(leds); + const uint32_t response = 0; + time_t now = time(NULL); + if (now != last_time) + { + printf("%d fps. starting %d previous %"PRIx32"\n", + i - last_i, i, response); + last_i = i; + last_time = now; + } + + + ledscape_close(leds); + + return EXIT_SUCCESS; +} diff --git a/src/demos/brick_sprite.hh b/src/demos/brick_sprite.hh new file mode 100644 index 00000000..eb8f9c35 --- /dev/null +++ b/src/demos/brick_sprite.hh @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +#include "sprite.hh" + +class brick_sprite_t : public sprite_t { +public: + uint8_t score (void) { return score_; } + uint8_t tone_number (void) { return tone_number_; } + + void set_score(uint8_t score) { score_ = score; } + void set_tone_number(uint8_t tone_number) { tone_number_ = tone_number; } + +private: + uint8_t tone_number_; + uint8_t score_; + +}; diff --git a/src/demos/bricks.cc b/src/demos/bricks.cc new file mode 100644 index 00000000..d9a3ff8a --- /dev/null +++ b/src/demos/bricks.cc @@ -0,0 +1,328 @@ +/** \file + * Test the matrix LCD PRU firmware with a multi-hue rainbow. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "ledscape.h" + +#include "controls.hh" +#include "screen.hh" +#include "sprite.hh" +#include "ball_sprite.hh" +#include "brick_sprite.hh" + +static controls_t *player_controls[3]; +static int player_score[2]; +static int player_lives[2]; +static int number_players; +static int current_player; + +static sprite_t paddle_sprite; +static ball_sprite_t ball_sprite; +static std::vector brick_sprites[2]; + +static Mix_Chunk *startup_bong; +static Mix_Chunk *wall_blip; +static Mix_Chunk *block_blip[3]; +static Mix_Chunk *paddle_blip; + +enum class game_state_t { + Attract, + Serving, + Playing, + Resetting, +}; + +static game_state_t game_state; + +static float ball_horizontal_speeds[] = { + -1.1f, + -0.9f, + -0.7f, + -0.5f, + 0.3f, + 0.5f, + 0.7f, + 0.9f, + 1.1f +}; + +uint32_t ball_data[] = {0x00808000, 0x00808000, 0x00808000, 0x00808000}; +uint32_t paddle_data[] = {0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF}; +uint32_t brick_data[][8] = { + {0x00800000, 0x00800000, 0x00800000, 0x00100000, 0x00800000, 0x00800000, 0x00800000, 0x00100000}, + {0x00008000, 0x00008000, 0x00008000, 0x00001000, 0x00008000, 0x00008000, 0x00008000, 0x00001000}, + {0x00004080, 0x00004080, 0x00004080, 0x00000A10, 0x00004080, 0x00004080, 0x00004080, 0x00000A10}, + {0x00804000, 0x00804000, 0x00804000, 0x00100A00, 0x00804000, 0x00804000, 0x00804000, 0x00100A00}, + {0x00800040, 0x00800040, 0x00800040, 0x0010000A, 0x00800040, 0x00800040, 0x00800040, 0x0010000A}, + {0x00204010, 0x00204010, 0x00204010, 0x0010200A, 0x00204010, 0x00204010, 0x00204010, 0x0010200A}, +}; + +static void reset_bricks(int for_player) { + brick_sprites[for_player].clear(); + for (int row_counter = 0; row_counter < 6; row_counter++) { + for (int column_counter = 0; column_counter < 16; column_counter++) { + brick_sprite_t brick_sprite; + brick_sprite.set_active(true); + brick_sprite.set_position(column_counter * 4, 10 + (row_counter * 2)); + brick_sprite.set_image(4,2, brick_data[row_counter]); + brick_sprite.set_score((6 - row_counter) * 10); + brick_sprite.set_tone_number((5 - row_counter) / 2); + brick_sprites[for_player].push_back(brick_sprite); + } + } +} + +static bool reset_round(void) { + current_player = (current_player + 1) % number_players; + if (player_lives[current_player] == 0) { + return false; + } + + ball_sprite.set_position(32,32); + ball_sprite.set_speed(0.3f, 0.5f); + ball_sprite.set_image(1,1,ball_data); + + game_state = game_state_t::Serving; + + return true; +} + +static void reset_game(int with_number_players) { + paddle_sprite.set_active(true); + paddle_sprite.set_position(28, 60); + paddle_sprite.set_image(8,2,paddle_data); + + reset_bricks(0); + reset_bricks(1); + + player_score[0] = 0; + player_score[1] = 0; + + player_lives[0] = 3; + player_lives[1] = 3; + + number_players = with_number_players; + current_player = 1; + + reset_round(); + + printf("\n\n\nGAME START\n\n\n"); +} + +void init_attract(void) { + paddle_sprite.set_active(false); + + ball_sprite.set_position(32,32); + ball_sprite.set_speed(0.5f, 0.5f); + ball_sprite.set_image(1,1,ball_data); + + current_player = 0; + reset_bricks(0); + + game_state = game_state_t::Attract; +} + +void render_game(Screen *screen) { + if (current_player == 1) { + screen->set_flip(true); + } else { + screen->set_flip(false); + } + screen->set_background_color(0x00000010); + screen->draw_start(); + + paddle_sprite.draw_onto(screen); + ball_sprite.draw_onto(screen); + + for (auto &brick_sprite : brick_sprites[current_player]) { + brick_sprite.draw_onto(screen); + } + + if (game_state == game_state_t::Attract) { + screen->draw_text(32,2,0x00808080,"GAME OVER!"); + screen->draw_text(40,2,0x00808080,"PRESS PLYR"); + screen->draw_text(48,2,0x00808080," 1 OR 2 "); + } else { + char score[7]; + char lives[1]; + sprintf(score, "%06d", player_score[current_player]); + screen->draw_text(0,2,0x00808080,score); + sprintf(lives, "%01d", player_lives[current_player]); + screen->draw_text(0,48,0x00808080,lives); + + } + + screen->draw_end(); + + player_controls[current_player]->refresh_status(); + + if (game_state == game_state_t::Attract) { + player_controls[2]->refresh_status(); + if (player_controls[2]->is_pressed(button_a)) { + reset_game(1); + } else if (player_controls[2]->is_pressed(button_b)) { + reset_game(2); + } + return; + } else { + if (player_controls[current_player]->is_pressed(joystick_left)) { + if (paddle_sprite.x_ > 0) { + paddle_sprite.x_--; + } + } + + if (player_controls[current_player]->is_pressed(joystick_right)) { + if (paddle_sprite.x_ < 56) { + paddle_sprite.x_++; + } + } + if (game_state == game_state_t::Serving) { + if (player_controls[current_player]->is_pressed(button_a)) { + game_state = game_state_t::Playing; + } + } + } + + // Move ball + if (game_state != game_state_t::Serving) { + ball_sprite.move_sprite(); + } + + if (ball_sprite.test_collision(paddle_sprite)) { + ball_sprite.y_ = 59.0f; + ball_sprite.dy_ = -ball_sprite.dy_; + ball_sprite.dx_ = ball_horizontal_speeds[(int)(ball_sprite.x_ - (paddle_sprite.x_ - 1))]; + Mix_PlayChannel(-1, paddle_blip, 0); + } + + if (ball_sprite.y_ >= 63.0f) { + if (game_state != game_state_t::Attract) { + player_lives[current_player]--; + if (!reset_round()) { + init_attract(); + } + return; + } else { + ball_sprite.dy_ = -ball_sprite.dy_; + ball_sprite.dx_ = ball_horizontal_speeds[rand()%7]; + } + } + + if (game_state == game_state_t::Playing) { + bool active_bricks = false; + for (auto &brick_sprite : brick_sprites[current_player]) { + active_bricks |= brick_sprite.is_active(); + if (brick_sprite.test_collision(ball_sprite)) { + brick_sprite.set_active(false); + game_state = game_state_t::Resetting; + ball_sprite.dy_ = -ball_sprite.dy_; + player_score[current_player] += brick_sprite.score(); + Mix_PlayChannel(-1, block_blip[brick_sprite.tone_number()], 0); + } + } + if (!active_bricks) { + reset_bricks(current_player); + } + } else { + if (game_state != game_state_t::Attract) { + if ((ball_sprite.y_ < 9) || (ball_sprite.y_ > 32)) { + game_state = game_state_t::Playing; + } + } + } +} + +static void init_sdl(void) { + if (SDL_Init(SDL_INIT_AUDIO) != 0) { + fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); + exit(1); + } + + int audio_rate = 44100; + Uint16 audio_format = AUDIO_S16SYS; + int audio_channels = 2; + int audio_buffers = 8192; + + if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) != 0) { + fprintf(stderr, "Unable to initialize audio: %s\n", Mix_GetError()); + exit(1); + } + + startup_bong = Mix_LoadWAV("/root/startup.wav"); + if (startup_bong == NULL) { + fprintf(stderr, "Unable to load startup.wav: %s\n", Mix_GetError()); + exit(1); + } + + Mix_PlayChannel(-1, startup_bong, 0); +} + +int +main( + int argc, + const char ** argv + ) +{ + int width = 64; + int height = 64; + + ledscape_config_t * config = &ledscape_matrix_default; + if (argc > 1) + { + config = ledscape_config(argv[1]); + if (!config) + return EXIT_FAILURE; + } + + if (config->type == LEDSCAPE_MATRIX) + { + config->matrix_config.width = width; + config->matrix_config.height = height; + } + + ledscape_t * const leds = ledscape_init(config, 0); + + player_controls[0] = new controls_t(1); + player_controls[1] = new controls_t(2); + player_controls[2] = new controls_t(3); + + init_attract(); + + printf("init done\n"); + uint32_t * const p = (uint32_t*)calloc(width*height,4); + + Screen *screen = new Screen(leds, p); + + init_sdl(); + + wall_blip = Mix_LoadWAV("/root/blip1.wav"); + paddle_blip = Mix_LoadWAV("/root/blip2.wav"); + block_blip[0] = Mix_LoadWAV("/root/blip3.wav"); + block_blip[1] = Mix_LoadWAV("/root/blip4.wav"); + block_blip[2] = Mix_LoadWAV("/root/blip5.wav"); + + while (1) + { + render_game(screen); + + usleep(20000); + + } + + ledscape_close(leds); + + return EXIT_SUCCESS; +} diff --git a/src/demos/controls.cc b/src/demos/controls.cc new file mode 100644 index 00000000..bd5c1075 --- /dev/null +++ b/src/demos/controls.cc @@ -0,0 +1,69 @@ +#include + +#include "controls.hh" + +#define BUTTON_PLAYERSTART_P1 70 +#define BUTTON_PLAYERSTART_P2 71 +#define BUTTON_P1_JOYUP 79 +#define BUTTON_P1_JOYDN 73 +#define BUTTON_P1_JOYLEFT 74 +#define BUTTON_P1_JOYRIGHT 75 +#define BUTTON_P1_ACTION_PRI 76 +#define BUTTON_P1_ACTION_SEC 77 +#define BUTTON_P2_JOYUP 8 +#define BUTTON_P2_JOYDN 10 +#define BUTTON_P2_JOYLEFT 9 +#define BUTTON_P2_JOYRIGHT 81 +#define BUTTON_P2_ACTION_PRI 11 +#define BUTTON_P2_ACTION_SEC 80 + +controls_t::controls_t (uint8_t player_number, bool flip_lr) { + pin_info_.resize(button_assignments_count); + if (player_number == 1) { + pin_info_[joystick_up] = new gpio_pin_t(BUTTON_P1_JOYUP); + pin_info_[joystick_down] = new gpio_pin_t(BUTTON_P1_JOYDN); + if (flip_lr) { + pin_info_[joystick_left] = new gpio_pin_t(BUTTON_P1_JOYRIGHT); + pin_info_[joystick_right] = new gpio_pin_t(BUTTON_P1_JOYLEFT); + } else { + pin_info_[joystick_left] = new gpio_pin_t(BUTTON_P1_JOYLEFT); + pin_info_[joystick_right] = new gpio_pin_t(BUTTON_P1_JOYRIGHT); + } + pin_info_[button_a] = new gpio_pin_t(BUTTON_P1_ACTION_PRI); + pin_info_[button_b] = new gpio_pin_t(BUTTON_P1_ACTION_SEC); + } else if (player_number == 2) { + pin_info_[joystick_up] = new gpio_pin_t(BUTTON_P2_JOYUP); + pin_info_[joystick_down] = new gpio_pin_t(BUTTON_P2_JOYDN); + if (flip_lr) { + pin_info_[joystick_left] = new gpio_pin_t(BUTTON_P2_JOYRIGHT); + pin_info_[joystick_right] = new gpio_pin_t(BUTTON_P2_JOYLEFT); + } else { + pin_info_[joystick_left] = new gpio_pin_t(BUTTON_P2_JOYLEFT); + pin_info_[joystick_right] = new gpio_pin_t(BUTTON_P2_JOYRIGHT); + } + pin_info_[button_a] = new gpio_pin_t(BUTTON_P2_ACTION_PRI); + pin_info_[button_b] = new gpio_pin_t(BUTTON_P2_ACTION_SEC); + } else if (player_number == 3) { + pin_info_[joystick_up] = new gpio_pin_t(BUTTON_P1_JOYUP); + pin_info_[joystick_down] = new gpio_pin_t(BUTTON_P1_JOYDN); + pin_info_[joystick_left] = new gpio_pin_t(BUTTON_P1_JOYLEFT); + pin_info_[joystick_right] = new gpio_pin_t(BUTTON_P1_JOYRIGHT); + pin_info_[button_a] = new gpio_pin_t(BUTTON_PLAYERSTART_P1); + pin_info_[button_b] = new gpio_pin_t(BUTTON_PLAYERSTART_P2); + } +} + +controls_t::~controls_t () { +} + +void controls_t::refresh_status() { + button_pressed_.clear(); + for (auto pin_info : pin_info_) { + button_pressed_.push_back(pin_info->is_pressed()); + } +} + +bool controls_t::is_pressed(button_assignments_t button) { + return button_pressed_[button]; +} + diff --git a/src/demos/controls.hh b/src/demos/controls.hh new file mode 100644 index 00000000..de4df6fb --- /dev/null +++ b/src/demos/controls.hh @@ -0,0 +1,29 @@ +#include +#include +#include + +#include "gpio_pin.hh" + +enum button_assignments_t { + joystick_up, + joystick_down, + joystick_left, + joystick_right, + button_a, + button_b, + button_assignments_count, +}; + +class controls_t { +public: + controls_t(uint8_t player_number, bool flip_lr = false); + ~controls_t(); + + void refresh_status(); + bool is_pressed(button_assignments_t button); + +private: + std::vector pin_info_; + std::vectorbutton_pressed_; +}; + diff --git a/src/demos/gpio_pin.cc b/src/demos/gpio_pin.cc new file mode 100644 index 00000000..d99f12af --- /dev/null +++ b/src/demos/gpio_pin.cc @@ -0,0 +1,45 @@ +#include + +#include +#include +#include +#include +#include + +#include "gpio_pin.hh" + +gpio_pin_t::gpio_pin_t (uint8_t button_number) : + button_number_(button_number) +{ + export_gpio(); + + char button_file_name[1024]; + snprintf(button_file_name, 1024, "/sys/class/gpio/gpio%d/value", button_number); + file_descriptor_ = open(button_file_name, O_RDONLY); + if (-1 == file_descriptor_) { + printf("Failed opening button %d\n", button_number); + throw 1; + } +} + +gpio_pin_t::~gpio_pin_t () { + close(file_descriptor_); +} + +void gpio_pin_t::export_gpio (void) { + FILE *exportfile = fopen("/sys/class/gpio/export", "w"); + if (NULL == exportfile) { + printf("Failed opening export device"); + return; + } + + fprintf(exportfile, "%d", button_number_); + fclose(exportfile); +} + +bool gpio_pin_t::is_pressed(void) { + uint8_t button_value; + lseek(file_descriptor_, 0, SEEK_SET); + read(file_descriptor_, &button_value, 1); + return (button_value == '0') ? true : false; +} diff --git a/src/demos/gpio_pin.hh b/src/demos/gpio_pin.hh new file mode 100644 index 00000000..f06b5398 --- /dev/null +++ b/src/demos/gpio_pin.hh @@ -0,0 +1,16 @@ +#include + +class gpio_pin_t { + +public: + gpio_pin_t (uint8_t button_number); + ~gpio_pin_t(); + + bool is_pressed(); + +private: + void export_gpio(); + + uint8_t button_number_; + int file_descriptor_; +}; diff --git a/src/demos/invaders.cc b/src/demos/invaders.cc new file mode 100644 index 00000000..c9b00417 --- /dev/null +++ b/src/demos/invaders.cc @@ -0,0 +1,311 @@ +/** \file + * Test the matrix LCD PRU firmware with a multi-hue rainbow. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "ledscape.h" + +#include "controls.hh" +#include "screen.hh" +#include "sprite.hh" +#include "ball_sprite.hh" +#include "brick_sprite.hh" +#include "png.hh" + +static controls_t *player_controls[3]; +static int player_score[2]; +static int number_players; +static int serving_player; + +static sprite_t paddle_sprite[2]; +static ball_sprite_t ball_sprite; +static png_t sprite_sheet; + +static Mix_Chunk *startup_bong; +static Mix_Chunk *paddle_blip; + +enum class game_state_t { + Attract, + Serving, + Playing, + Resetting, +}; + +static game_state_t game_state; + +static float ball_horizontal_speeds[] = { + -1.1f, + -0.9f, + -0.7f, + -0.5f, + 0.3f, + 0.5f, + 0.7f, + 0.9f, + 1.1f +}; + +uint32_t ball_data[] = {0x00808000, 0x00808000, 0x00808000, 0x00808000}; + +static bool reset_round(void) { + if ((player_score[0] == 7) || (player_score[1] == 7)) { + return false; + } + + if (serving_player == 0) { + ball_sprite.set_position(paddle_sprite[0].x_+4,58); + ball_sprite.set_speed(ball_horizontal_speeds[rand()%7], -0.5f); + } else { + ball_sprite.set_position(paddle_sprite[1].x_+4,6); + ball_sprite.set_speed(ball_horizontal_speeds[rand()%7], 0.5f); + } + ball_sprite.set_image(1,1,ball_data); + + game_state = game_state_t::Serving; + + return true; +} + +static void reset_game(int with_number_players) { + paddle_sprite[0].set_active(true); + paddle_sprite[0].set_position(28, 32); + paddle_sprite[0].set_image(0,0,7,7,&sprite_sheet); + + paddle_sprite[1].set_active(true); + paddle_sprite[1].set_position(28, 2); + paddle_sprite[1].set_image(28,0,7,7,&sprite_sheet); + + player_score[0] = 0; + player_score[1] = 0; + + serving_player = 0; + + number_players = with_number_players; + + reset_round(); + + printf("\n\n\nGAME START\n\n\n"); +} + +void init_attract(void) { + paddle_sprite[0].set_active(false); + paddle_sprite[1].set_active(false); + + ball_sprite.set_position(32,32); + ball_sprite.set_speed(0.5f, 0.5f); + ball_sprite.set_image(1,1,ball_data); + + game_state = game_state_t::Attract; +} + +void render_game(Screen *screen) { + screen->set_flip(false); + + screen->set_background_color(0x00000010); + screen->draw_start(); + + if (game_state == game_state_t::Attract) { + screen->draw_text(32,2,0x00808080,"GAME OVER!"); + screen->draw_text(40,2,0x00808080,"PRESS PLYR"); + screen->draw_text(48,2,0x00808080," 1 OR 2 "); + } + char score[7]; + sprintf(score, "%1d", player_score[1]); + screen->draw_text(0,59,0x00808080,score,number_players==2); + sprintf(score, "%1d", player_score[0]); + screen->draw_text(57,59,0x00808080,score); + + paddle_sprite[0].draw_onto(screen); + paddle_sprite[1].draw_onto(screen); + ball_sprite.draw_onto(screen); + + screen->draw_end(); + + player_controls[0]->refresh_status(); + player_controls[1]->refresh_status(); + + if (game_state == game_state_t::Attract) { + player_controls[2]->refresh_status(); + if (player_controls[2]->is_pressed(button_a)) { + reset_game(1); + } else if (player_controls[2]->is_pressed(button_b)) { + reset_game(2); + } + return; + } else { + for (int player = 0; player < number_players; player++) { + if (player_controls[player]->is_pressed(joystick_left)) { + if (paddle_sprite[player].x_ > 0) { + paddle_sprite[player].x_--; + } + } + + if (player_controls[player]->is_pressed(joystick_right)) { + if (paddle_sprite[player].x_ < 56) { + paddle_sprite[player].x_++; + } + } + } + if (game_state == game_state_t::Serving) { + ball_sprite.x_ = paddle_sprite[serving_player].x_ + 4; + if (player_controls[serving_player]->is_pressed(button_a)) { + game_state = game_state_t::Playing; + } + } + + if (number_players == 1) { + float computer_paddle_x_target = ball_sprite.x_ - 4; + + if (computer_paddle_x_target > paddle_sprite[1].x_) paddle_sprite[1].x_ += 0.8f; + if (computer_paddle_x_target < paddle_sprite[1].x_) paddle_sprite[1].x_ -= 0.8f; + + if (paddle_sprite[1].x_ < 0) { paddle_sprite[1].x_ = 0; } + if (paddle_sprite[1].x_ > 56) { paddle_sprite[1].x_ = 56; } + } + } + + // Move ball + if (game_state != game_state_t::Serving) { + ball_sprite.move_sprite(); + } + + if (ball_sprite.test_collision(paddle_sprite[0])) { + ball_sprite.y_ = 59.0f; + ball_sprite.dy_ = -ball_sprite.dy_ * 1.1f; + if (ball_sprite.dy_ < -2.0f) ball_sprite.dy_ = -2.0f; + ball_sprite.dx_ = ball_horizontal_speeds[(int)(ball_sprite.x_ - (paddle_sprite[0].x_ - 1))]; + Mix_PlayChannel(-1, paddle_blip, 0); + } + + if (ball_sprite.test_collision(paddle_sprite[1])) { + ball_sprite.y_ = 5.0f; + ball_sprite.dy_ = -ball_sprite.dy_ * 1.1f; + if (ball_sprite.dy_ > 2.0f) ball_sprite.dy_ = 2.0f; + ball_sprite.dx_ = ball_horizontal_speeds[(int)(ball_sprite.x_ - (paddle_sprite[1].x_ - 1))]; + Mix_PlayChannel(-1, paddle_blip, 0); + } + + if (ball_sprite.y_ >= 63.0f) { + if (game_state != game_state_t::Attract) { + player_score[1]++; + if (number_players == 2) { + serving_player = 1; + } else { + serving_player = 0; + } + if (!reset_round()) { + init_attract(); + } + return; + } else { + ball_sprite.dy_ = -ball_sprite.dy_; + ball_sprite.dx_ = ball_horizontal_speeds[rand()%7]; + } + } + + if (ball_sprite.y_ <= 0.0f) { + if (game_state != game_state_t::Attract) { + player_score[0]++; + serving_player = 0; + if (!reset_round()) { + init_attract(); + } + return; + } else { + ball_sprite.dy_ = -ball_sprite.dy_; + ball_sprite.dx_ = ball_horizontal_speeds[rand()%7]; + } + } +} + +static void init_sdl(void) { + if (SDL_Init(SDL_INIT_AUDIO) != 0) { + fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); + exit(1); + } + + int audio_rate = 44100; + Uint16 audio_format = AUDIO_S16SYS; + int audio_channels = 2; + int audio_buffers = 8192; + + if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) != 0) { + fprintf(stderr, "Unable to initialize audio: %s\n", Mix_GetError()); + exit(1); + } + + startup_bong = Mix_LoadWAV("/root/startup.wav"); + if (startup_bong == NULL) { + fprintf(stderr, "Unable to load startup.wav: %s\n", Mix_GetError()); + exit(1); + } + + Mix_PlayChannel(-1, startup_bong, 0); +} + +int +main( + int argc, + const char ** argv + ) +{ + int width = 64; + int height = 64; + + ledscape_config_t * config = &ledscape_matrix_default; + if (argc > 1) + { + config = ledscape_config(argv[1]); + if (!config) + return EXIT_FAILURE; + } + + if (config->type == LEDSCAPE_MATRIX) + { + config->matrix_config.width = width; + config->matrix_config.height = height; + } + + ledscape_t * const leds = ledscape_init(config, 0); + + sprite_sheet.read_file("/root/Invaders.png"); + + player_controls[0] = new controls_t(1); + player_controls[1] = new controls_t(2, true); + player_controls[2] = new controls_t(3); + + init_attract(); + + printf("init done\n"); + uint32_t * const p = (uint32_t*)calloc(width*height,4); + + Screen *screen = new Screen(leds, p); + + init_sdl(); + + paddle_blip = Mix_LoadWAV("/root/blip2.wav"); + + while (1) + { + render_game(screen); + + usleep(20000); + + } + + ledscape_close(leds); + + return EXIT_SUCCESS; +} diff --git a/src/demos/png.cc b/src/demos/png.cc new file mode 100644 index 00000000..9324043a --- /dev/null +++ b/src/demos/png.cc @@ -0,0 +1,74 @@ +#include "png.hh" + +png_t::png_t() { +} + +png_t::~png_t() { +} + +void abort_(const char * s, ...) +{ + va_list args; + va_start(args, s); + vfprintf(stderr, s, args); + fprintf(stderr, "\n"); + va_end(args); + abort(); +} + +void png_t::read_file(std::string filename) { + unsigned char header[8]; // 8 is the maximum size that can be checked + + /* open file and test for it being a png */ + FILE *fp = fopen(filename.c_str(), "rb"); + if (!fp) + abort_("[read_png_file] File %s could not be opened for reading", filename.c_str()); + fread(header, 1, 8, fp); + if (png_sig_cmp(header, 0, 8)) + abort_("[read_png_file] File %s is not recognized as a PNG file", filename.c_str()); + + + /* initialize stuff */ + png_ptr_ = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!png_ptr_) + abort_("[read_png_file] png_create_read_struct failed"); + + info_ptr_ = png_create_info_struct(png_ptr_); + if (!info_ptr_) + abort_("[read_png_file] png_create_info_struct failed"); + + if (setjmp(png_jmpbuf(png_ptr_))) + abort_("[read_png_file] Error during init_io"); + + png_init_io(png_ptr_, fp); + png_set_sig_bytes(png_ptr_, 8); + + png_read_info(png_ptr_, info_ptr_); + + width_ = png_get_image_width(png_ptr_, info_ptr_); + height_ = png_get_image_height(png_ptr_, info_ptr_); + color_type_ = png_get_color_type(png_ptr_, info_ptr_); + bit_depth_ = png_get_bit_depth(png_ptr_, info_ptr_); + + number_of_passes_ = png_set_interlace_handling(png_ptr_); + png_read_update_info(png_ptr_, info_ptr_); + + + /* read file */ + if (setjmp(png_jmpbuf(png_ptr_))) + abort_("[read_png_file] Error during read_image"); + + row_pointers_ = (png_bytep*) malloc(sizeof(png_bytep) * height_); + for (int y=0; y +#include +#include + +#include + +class png_t { +public: + png_t(); + ~png_t(); + + virtual void read_file(std::string filename); + virtual png_byte* row(uint16_t row_number); + +private: + int width_, height_; + png_byte color_type_; + png_byte bit_depth_; + + png_structp png_ptr_; + png_infop info_ptr_; + int number_of_passes_; + png_bytep * row_pointers_; + +}; diff --git a/src/demos/pong.cc b/src/demos/pong.cc new file mode 100644 index 00000000..95d415bb --- /dev/null +++ b/src/demos/pong.cc @@ -0,0 +1,308 @@ +/** \file + * Test the matrix LCD PRU firmware with a multi-hue rainbow. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "ledscape.h" + +#include "controls.hh" +#include "screen.hh" +#include "sprite.hh" +#include "ball_sprite.hh" +#include "brick_sprite.hh" + +static controls_t *player_controls[3]; +static int player_score[2]; +static int number_players; +static int serving_player; + +static sprite_t paddle_sprite[2]; +static ball_sprite_t ball_sprite; + +static Mix_Chunk *startup_bong; +static Mix_Chunk *paddle_blip; + +enum class game_state_t { + Attract, + Serving, + Playing, + Resetting, +}; + +static game_state_t game_state; + +static float ball_horizontal_speeds[] = { + -1.1f, + -0.9f, + -0.7f, + -0.5f, + 0.3f, + 0.5f, + 0.7f, + 0.9f, + 1.1f +}; + +uint32_t ball_data[] = {0x00808000, 0x00808000, 0x00808000, 0x00808000}; +uint32_t paddle_data[] = {0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF}; + +static bool reset_round(void) { + if ((player_score[0] == 7) || (player_score[1] == 7)) { + return false; + } + + if (serving_player == 0) { + ball_sprite.set_position(paddle_sprite[0].x_+4,58); + ball_sprite.set_speed(ball_horizontal_speeds[rand()%7], -0.5f); + } else { + ball_sprite.set_position(paddle_sprite[1].x_+4,6); + ball_sprite.set_speed(ball_horizontal_speeds[rand()%7], 0.5f); + } + ball_sprite.set_image(1,1,ball_data); + + game_state = game_state_t::Serving; + + return true; +} + +static void reset_game(int with_number_players) { + paddle_sprite[0].set_active(true); + paddle_sprite[0].set_position(28, 60); + paddle_sprite[0].set_image(8,3,paddle_data); + + paddle_sprite[1].set_active(true); + paddle_sprite[1].set_position(28, 2); + paddle_sprite[1].set_image(8,3,paddle_data); + + player_score[0] = 0; + player_score[1] = 0; + + serving_player = 0; + + number_players = with_number_players; + + reset_round(); + + printf("\n\n\nGAME START\n\n\n"); +} + +void init_attract(void) { + paddle_sprite[0].set_active(false); + paddle_sprite[1].set_active(false); + + ball_sprite.set_position(32,32); + ball_sprite.set_speed(0.5f, 0.5f); + ball_sprite.set_image(1,1,ball_data); + + game_state = game_state_t::Attract; +} + +void render_game(Screen *screen) { + screen->set_flip(false); + + screen->set_background_color(0x00000010); + screen->draw_start(); + + if (game_state == game_state_t::Attract) { + screen->draw_text(32,2,0x00808080,"GAME OVER!"); + screen->draw_text(40,2,0x00808080,"PRESS PLYR"); + screen->draw_text(48,2,0x00808080," 1 OR 2 "); + } + char score[7]; + sprintf(score, "%1d", player_score[1]); + screen->draw_text(0,59,0x00808080,score,number_players==2); + sprintf(score, "%1d", player_score[0]); + screen->draw_text(57,59,0x00808080,score); + + paddle_sprite[0].draw_onto(screen); + paddle_sprite[1].draw_onto(screen); + ball_sprite.draw_onto(screen); + + screen->draw_end(); + + player_controls[0]->refresh_status(); + player_controls[1]->refresh_status(); + + if (game_state == game_state_t::Attract) { + player_controls[2]->refresh_status(); + if (player_controls[2]->is_pressed(button_a)) { + reset_game(1); + } else if (player_controls[2]->is_pressed(button_b)) { + reset_game(2); + } + return; + } else { + for (int player = 0; player < number_players; player++) { + if (player_controls[player]->is_pressed(joystick_left)) { + if (paddle_sprite[player].x_ > 0) { + paddle_sprite[player].x_--; + } + } + + if (player_controls[player]->is_pressed(joystick_right)) { + if (paddle_sprite[player].x_ < 56) { + paddle_sprite[player].x_++; + } + } + } + if (game_state == game_state_t::Serving) { + ball_sprite.x_ = paddle_sprite[serving_player].x_ + 4; + if (player_controls[serving_player]->is_pressed(button_a)) { + game_state = game_state_t::Playing; + } + } + + if (number_players == 1) { + float computer_paddle_x_target = ball_sprite.x_ - 4; + + if (computer_paddle_x_target > paddle_sprite[1].x_) paddle_sprite[1].x_ += 0.8f; + if (computer_paddle_x_target < paddle_sprite[1].x_) paddle_sprite[1].x_ -= 0.8f; + + if (paddle_sprite[1].x_ < 0) { paddle_sprite[1].x_ = 0; } + if (paddle_sprite[1].x_ > 56) { paddle_sprite[1].x_ = 56; } + } + } + + // Move ball + if (game_state != game_state_t::Serving) { + ball_sprite.move_sprite(); + } + + if (ball_sprite.test_collision(paddle_sprite[0])) { + ball_sprite.y_ = 59.0f; + ball_sprite.dy_ = -ball_sprite.dy_ * 1.1f; + if (ball_sprite.dy_ < -2.0f) ball_sprite.dy_ = -2.0f; + ball_sprite.dx_ = ball_horizontal_speeds[(int)(ball_sprite.x_ - (paddle_sprite[0].x_ - 1))]; + Mix_PlayChannel(-1, paddle_blip, 0); + } + + if (ball_sprite.test_collision(paddle_sprite[1])) { + ball_sprite.y_ = 5.0f; + ball_sprite.dy_ = -ball_sprite.dy_ * 1.1f; + if (ball_sprite.dy_ > 2.0f) ball_sprite.dy_ = 2.0f; + ball_sprite.dx_ = ball_horizontal_speeds[(int)(ball_sprite.x_ - (paddle_sprite[1].x_ - 1))]; + Mix_PlayChannel(-1, paddle_blip, 0); + } + + if (ball_sprite.y_ >= 63.0f) { + if (game_state != game_state_t::Attract) { + player_score[1]++; + if (number_players == 2) { + serving_player = 1; + } else { + serving_player = 0; + } + if (!reset_round()) { + init_attract(); + } + return; + } else { + ball_sprite.dy_ = -ball_sprite.dy_; + ball_sprite.dx_ = ball_horizontal_speeds[rand()%7]; + } + } + + if (ball_sprite.y_ <= 0.0f) { + if (game_state != game_state_t::Attract) { + player_score[0]++; + serving_player = 0; + if (!reset_round()) { + init_attract(); + } + return; + } else { + ball_sprite.dy_ = -ball_sprite.dy_; + ball_sprite.dx_ = ball_horizontal_speeds[rand()%7]; + } + } +} + +static void init_sdl(void) { + if (SDL_Init(SDL_INIT_AUDIO) != 0) { + fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); + exit(1); + } + + int audio_rate = 44100; + Uint16 audio_format = AUDIO_S16SYS; + int audio_channels = 2; + int audio_buffers = 8192; + + if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) != 0) { + fprintf(stderr, "Unable to initialize audio: %s\n", Mix_GetError()); + exit(1); + } + + startup_bong = Mix_LoadWAV("/root/startup.wav"); + if (startup_bong == NULL) { + fprintf(stderr, "Unable to load startup.wav: %s\n", Mix_GetError()); + exit(1); + } + + Mix_PlayChannel(-1, startup_bong, 0); +} + +int +main( + int argc, + const char ** argv + ) +{ + int width = 64; + int height = 64; + + ledscape_config_t * config = &ledscape_matrix_default; + if (argc > 1) + { + config = ledscape_config(argv[1]); + if (!config) + return EXIT_FAILURE; + } + + if (config->type == LEDSCAPE_MATRIX) + { + config->matrix_config.width = width; + config->matrix_config.height = height; + } + + ledscape_t * const leds = ledscape_init(config, 0); + + player_controls[0] = new controls_t(1); + player_controls[1] = new controls_t(2, true); + player_controls[2] = new controls_t(3); + + init_attract(); + + printf("init done\n"); + uint32_t * const p = (uint32_t*)calloc(width*height,4); + + Screen *screen = new Screen(leds, p); + + init_sdl(); + + paddle_blip = Mix_LoadWAV("/root/blip2.wav"); + + while (1) + { + render_game(screen); + + usleep(20000); + + } + + ledscape_close(leds); + + return EXIT_SUCCESS; +} diff --git a/src/demos/robin-hood-test.c b/src/demos/robin-hood-test.c new file mode 100644 index 00000000..11bc3fc3 --- /dev/null +++ b/src/demos/robin-hood-test.c @@ -0,0 +1,436 @@ +/** \file + * Test the matrix LCD PRU firmware with a multi-hue rainbow. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "ledscape.h" + + +// Borrowed by OctoWS2811 rainbow test +static unsigned int +h2rgb( + unsigned int v1, + unsigned int v2, + unsigned int hue +) +{ + if (hue < 60) + return v1 * 60 + (v2 - v1) * hue; + if (hue < 180) + return v2 * 60; + if (hue < 240) + return v1 * 60 + (v2 - v1) * (240 - hue); + + return v1 * 60; +} + + +// Convert HSL (Hue, Saturation, Lightness) to RGB (Red, Green, Blue) +// +// hue: 0 to 359 - position on the color wheel, 0=red, 60=orange, +// 120=yellow, 180=green, 240=blue, 300=violet +// +// saturation: 0 to 100 - how bright or dull the color, 100=full, 0=gray +// +// lightness: 0 to 100 - how light the color is, 100=white, 50=color, 0=black +// +static uint32_t +makeColor( + unsigned int hue, + unsigned int saturation, + unsigned int lightness +) +{ + unsigned int red, green, blue; + unsigned int var1, var2; + + if (hue > 359) + hue = hue % 360; + if (saturation > 100) + saturation = 100; + if (lightness > 100) + lightness = 100; + + // algorithm from: http://www.easyrgb.com/index.php?X=MATH&H=19#text19 + if (saturation == 0) { + red = green = blue = lightness * 255 / 100; + } else { + if (lightness < 50) { + var2 = lightness * (100 + saturation); + } else { + var2 = ((lightness + saturation) * 100) - (saturation * lightness); + } + var1 = lightness * 200 - var2; + red = h2rgb(var1, var2, (hue < 240) ? hue + 120 : hue - 240) * 255 / 600000; + green = h2rgb(var1, var2, hue) * 255 / 600000; + blue = h2rgb(var1, var2, (hue >= 120) ? hue - 120 : hue + 240) * 255 / 600000; + } + return (red << 16) | (green << 8) | blue; +} + + + +static uint32_t rainbowColors[180]; + + +// phaseShift is the shift between each row. phaseShift=0 +// causes all rows to show the same colors moving together. +// phaseShift=180 causes each row to be the opposite colors +// as the previous. +// +// cycleTime is the number of milliseconds to shift through +// the entire 360 degrees of the color wheel: +// Red -> Orange -> Yellow -> Green -> Blue -> Violet -> Red +// +static void +rainbow( + uint32_t * const pixels, + unsigned width, + unsigned height, + unsigned phaseShift, + unsigned cycle +) +{ + const unsigned color = cycle % 180; + const unsigned dim = 128; + + static unsigned count = 0; + + count += 1; + + for (unsigned x=0; x < width; x++) { + for (unsigned y=0; y < height; y++) { + const int index = (color + x + y*phaseShift/4) % 180; + const uint32_t in = rainbowColors[index]; + uint8_t * const out = &pixels[x + y*width]; +#if 1 + out[0] = ((in >> 0) & 0xFF) * dim / 128; // * y / 16; + out[1] = ((in >> 8) & 0xFF) * dim / 128; // * y / 16; + out[2] = ((in >> 16) & 0xFF) * dim / 128; // * y / 16; +#else + if(y==((count >> 3) & 0x1F) && x<20) { + out[0] = 0xff; + out[1] = 0xff; + out[2] = 0x00; + } + else { + out[0] = 0x00; + out[1] = 0x00; + out[2] = 0xff; + } +#endif + } + } +} + + +static void +gradient( + uint32_t * const pixels, + unsigned width, + unsigned height, + unsigned phaseShift, + unsigned cycle +) +{ + cycle >>= 3; + for (unsigned x=0; x < width; x++) { + for (unsigned y=0; y < height; y++) { + uint8_t * const out = &pixels[x + y*width]; +#if 0 + //out[0] = ((x+cycle) % 32) * 8; + //out[1] = ((y+cycle) % 16) * 16; + uint8_t b = 0xFF; + out[1] = b * ((((x + y + cycle) >> 5) ) & 1); +#else + uint32_t b = 0; + + if (x % 32 < (x/32 + 4) && y % 32 < (y/32+1)) + { + b = 0xFFFFFF; + } else + if (x < 32) + { + if (y < 32) + b = 0xFF0000; + else + if (y < 64) + b = 0x0000FF; + else + if (y < 96) + b = 0x00FF00; + else + b = 0x411111; + } else + if (x < 64) + { + if (y < 32) + b = 0xFF00FF; + else + if (y < 64) + b = 0x00FFFF; + else + if (y < 96) + b = 0xFFFF00; + else + b = 0x114111; + } else { + b = 0x111141; + } + + out[0] = (b >> 16) & 0xFF; + out[1] = (b >> 8) & 0xFF; + out[2] = (b >> 0) & 0xFF; + //*out = b; +#endif + } + } +} + +#include +#include +#include +#include +#include + +#define PNG_DEBUG 3 +#include + +void abort_(const char * s, ...) +{ + va_list args; + va_start(args, s); + vfprintf(stderr, s, args); + fprintf(stderr, "\n"); + va_end(args); + abort(); +} + +int png_x, png_y; + +int png_width, png_height; +png_byte color_type; +png_byte bit_depth; + +png_structp png_ptr; +png_infop info_ptr; +int number_of_passes; +png_bytep * row_pointers; + +void read_png_file(char* file_name) +{ + char header[8]; // 8 is the maximum size that can be checked + + /* open file and test for it being a png */ + FILE *fp = fopen(file_name, "rb"); + if (!fp) + abort_("[read_png_file] File %s could not be opened for reading", file_name); + fread(header, 1, 8, fp); + if (png_sig_cmp(header, 0, 8)) + abort_("[read_png_file] File %s is not recognized as a PNG file", file_name); + + + /* initialize stuff */ + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!png_ptr) + abort_("[read_png_file] png_create_read_struct failed"); + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + abort_("[read_png_file] png_create_info_struct failed"); + + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[read_png_file] Error during init_io"); + + png_init_io(png_ptr, fp); + png_set_sig_bytes(png_ptr, 8); + + png_read_info(png_ptr, info_ptr); + + png_width = png_get_image_width(png_ptr, info_ptr); + png_height = png_get_image_height(png_ptr, info_ptr); + color_type = png_get_color_type(png_ptr, info_ptr); + bit_depth = png_get_bit_depth(png_ptr, info_ptr); + + number_of_passes = png_set_interlace_handling(png_ptr); + png_read_update_info(png_ptr, info_ptr); + + + /* read file */ + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[read_png_file] Error during read_image"); + + row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * png_height); + for (png_y=0; png_y> 2; + out[1] = ptr[1] >> 2; + out[2] = ptr[0] >> 2; + } + } +} + +#define BUTTON_PLAYERSTART_P1 70 +#define BUTTON_PLAYERSTART_P2 71 +#define BUTTON_P1_JOYUP 79 +#define BUTTON_P1_JOYDN 73 +#define BUTTON_P1_JOYLEFT 74 +#define BUTTON_P1_JOYRIGHT 75 +#define BUTTON_P1_ACTION_PRI 76 +#define BUTTON_P1_ACTION_SEC 77 + +void export_button_gpio (uint8_t button_number) { + FILE *exportfile = fopen("/sys/class/gpio/export", "w"); + if (NULL == exportfile) { + printf("Failed opening export device"); + return; + } + + fprintf(exportfile, "%d", button_number); + fclose(exportfile); +} + +uint8_t button_pressed(uint8_t button_number) { + char button_file_name[1024]; + snprintf(button_file_name, 1024, "/sys/class/gpio/gpio%d/value", button_number); + FILE *button_file = fopen(button_file_name, "r"); + if (NULL == button_file) { + printf("Failed opening button %d\n", button_number); + return 0; + } + int button_value; + fscanf(button_file, "%d", &button_value); + fclose(button_file); + return (button_value == 0) ? 1 : 0; +} + +int +main( + int argc, + const char ** argv +) +{ + int width = 64; + int height = 64; + + ledscape_config_t * config = &ledscape_matrix_default; + if (argc > 1) + { + config = ledscape_config(argv[1]); + if (!config) + return EXIT_FAILURE; + } + + if (config->type == LEDSCAPE_MATRIX) + { + config->matrix_config.width = width; + config->matrix_config.height = height; + } + + ledscape_t * const leds = ledscape_init(config, 0); + + export_button_gpio(BUTTON_PLAYERSTART_P1); + export_button_gpio(BUTTON_PLAYERSTART_P2); + export_button_gpio(BUTTON_P1_JOYUP); + export_button_gpio(BUTTON_P1_JOYDN); + export_button_gpio(BUTTON_P1_JOYLEFT); + export_button_gpio(BUTTON_P1_JOYRIGHT); + export_button_gpio(BUTTON_P1_ACTION_PRI); + export_button_gpio(BUTTON_P1_ACTION_SEC); + + printf("init done\n"); + time_t last_time = time(NULL); + unsigned last_i = 0; + + // pre-compute the 180 rainbow colors + for (int i=0; i<180; i++) + { + int hue = i * 2; + int saturation = 100; + int lightness = 50; + rainbowColors[i] = makeColor(hue, saturation, lightness); + } + + read_png_file("/root/robin-hood.png"); + + unsigned i = 0; + uint32_t * const p = calloc(width*height,4); + + while (1) + { +/* + if (1) + rainbow(p, width, height, 10, i++); + else + gradient(p, width, height, 10, i++); +*/ + process_file(p); + i++; + ledscape_draw(leds, p); + + if (button_pressed(BUTTON_PLAYERSTART_P1)) { + printf("PLAYER 1 START\n"); + } + if (button_pressed(BUTTON_PLAYERSTART_P2)) { + printf("PLAYER 2 START\n"); + } + if (button_pressed(BUTTON_P1_JOYUP)) { + printf("P1-UP\n"); + } + if (button_pressed(BUTTON_P1_JOYDN)) { + printf("P1-DOWN\n"); + } + if (button_pressed(BUTTON_P1_JOYLEFT)) { + printf("P1-LEFT\n"); + } + if (button_pressed(BUTTON_P1_JOYRIGHT)) { + printf("P1-RIGHT\n"); + } + if (button_pressed(BUTTON_P1_ACTION_PRI)) { + printf("P1-PRI\n"); + } + if (button_pressed(BUTTON_P1_ACTION_SEC)) { + printf("P1-SEC\n"); + } + + + usleep(20000); + + // wait for the previous frame to finish; + //const uint32_t response = ledscape_wait(leds); + const uint32_t response = 0; + time_t now = time(NULL); + if (now != last_time) + { + printf("%d fps. starting %d previous %"PRIx32"\n", + i - last_i, i, response); + last_i = i; + last_time = now; + } + + } + + ledscape_close(leds); + + return EXIT_SUCCESS; +} diff --git a/src/demos/screen.cc b/src/demos/screen.cc new file mode 100644 index 00000000..4691b9c4 --- /dev/null +++ b/src/demos/screen.cc @@ -0,0 +1,76 @@ +#include +#include "screen.hh" + +extern const uint8_t fixed_font[][5]; + +Screen::Screen(ledscape_t * const leds, uint32_t *pixels): + pixels_(pixels), + leds_(leds), + flip_(false) +{ + set_background_color(0x00000000); + draw_start(); + ledscape_printf(&pixels_[9], 64, 0x00401010, "LedGames\n Engine"); + ledscape_printf(&pixels_[64*32 + 17], 64, 0x00101040, "Keith"); + ledscape_printf(&pixels_[64*40 + 2], 64, 0x00101040, "Henrickson"); + draw_end(); + sleep(1); +} + +void Screen::drawpixel(uint32_t x, uint32_t y, uint32_t color) { + uint32_t pixelnum = ((flip_ ? (63 - y) : y) * 64) + (flip_ ? (63 - x ) : x); + pixels_[pixelnum] = color; +} + +void Screen::set_background_color(uint32_t color) { + background_color_ = color; +} + +void Screen::draw_char(uint8_t row, uint8_t column, const uint32_t color, char c, bool flip) { + if (c < 0x20 || c > 127) + c = '?'; + + const uint8_t* const f = fixed_font[c - 0x20]; + for (int x = 0 ; x < 5 ; x++) { + uint8_t bits = f[x]; + for (int y = 0 ; y < 7 ; y++, bits >>= 1) { + if (flip) { + drawpixel((4-x) + column, (6-y) + row, (bits & 1) ? color : 0); + } else { + drawpixel(x + column, y + row, (bits & 1) ? color : 0); + } + } + } +} + +void Screen::draw_text(uint8_t row, uint8_t column, uint32_t color, std::string output, bool flip) { + if (flip) { + column += (output.length() - 1) * 6; + } + for (unsigned i = 0 ; i < output.length() ; i++) { + char c = output[i]; + if (!c) + break; + + draw_char(row, column, color, c, flip); + if (flip) { + column -= 6; + } else { + column += 6; + } + } +} + +void Screen::draw_start(void) { + for (int counter = 0; counter < (64*64); counter++) { + pixels_[counter] = background_color_; + } +} + +void Screen::draw_end(void) { + ledscape_draw(leds_, pixels_); +} + +void Screen::set_flip(bool do_flip) { + flip_ = do_flip; +} diff --git a/src/demos/screen.hh b/src/demos/screen.hh new file mode 100644 index 00000000..69e4bc4e --- /dev/null +++ b/src/demos/screen.hh @@ -0,0 +1,26 @@ +#pragma once +#include +#include + +#include "ledscape.h" + +class Screen { +public: + Screen(ledscape_t * const leds, uint32_t *pixels); + + void drawpixel(uint32_t x, uint32_t y, uint32_t color); + void set_background_color(uint32_t color); + void draw_start(void); + void draw_end(void); + void draw_text(uint8_t row, uint8_t column, uint32_t color, std::string output, bool flip = false); + void set_flip(bool do_flip); + +private: + void draw_char(uint8_t row, uint8_t column, const uint32_t color, char c, bool flip); + + uint32_t *pixels_; + ledscape_t * const leds_; + bool flip_; + + uint32_t background_color_; +}; diff --git a/src/demos/sprite.cc b/src/demos/sprite.cc new file mode 100644 index 00000000..b6b5b696 --- /dev/null +++ b/src/demos/sprite.cc @@ -0,0 +1,85 @@ +#include "sprite.hh" + +sprite_t::sprite_t() : + x_(0), + y_(0), + dx_(0), + dy_(0), + active_(true) +{ +} + +sprite_t::~sprite_t() { +} + +bool sprite_t::is_active(void) { + return active_; +} + +void sprite_t::set_active(bool active) { + active_ = active; +} + +void sprite_t::set_position(float x, float y) { + x_ = x; + y_ = y; +} + +void sprite_t::set_speed(float dx, float dy) { + dx_ = dx; + dy_ = dy; +} + +void sprite_t::move_sprite(void) { + x_ += dx_; + y_ += dy_; +} + +void sprite_t::set_image(uint8_t width, uint8_t height, uint32_t *pixels) { + sprite_data_.resize(width * height); + sprite_data_.assign(pixels, pixels+(width * height)); + + width_ = width; + height_ = height; +} + +void sprite_t::set_image(uint16_t x_offset, uint16_t y_offset, uint8_t width, uint8_t height, png_t *png_image) { + sprite_data_.resize(width * height); + + width_ = width; + height_ = height; + + for (uint8_t y = 0; y < height; y++) { + png_byte* row = png_image->row(y + y_offset); + for (uint8_t x = 0; x < width; x++) { + uint8_t *sprite_pixel = (uint8_t*)&(sprite_data_[x + (y * width)]); + uint8_t *png_pixel = (uint8_t*)&(row[(x + x_offset) * 4]); + sprite_pixel[0] = png_pixel[2]; + sprite_pixel[1] = png_pixel[1]; + sprite_pixel[2] = png_pixel[0]; + } + } +} + +void sprite_t::draw_onto(Screen *screen) { + if (!active_) return; + + for (uint8_t pixel_y = 0; pixel_y < height_; pixel_y++) { + for (uint8_t pixel_x = 0; pixel_x < width_; pixel_x++) { + screen->drawpixel(pixel_x + x_, pixel_y + y_, sprite_data_[(pixel_y * width_) + pixel_x]); + } + } +} + +bool sprite_t::test_collision(const sprite_t &other_sprite) { + if (!active_) return false; + + uint8_t visible_x = x_; + uint8_t visible_y = y_; + uint8_t other_visible_x = other_sprite.x_; + uint8_t other_visible_y = other_sprite.y_; + + return !((visible_x + width_ - 1) < other_visible_x || (visible_y + height_ - 1) < (other_visible_y) || + x_ > (other_visible_x + other_sprite.width_ - 1) || + y_ > (other_visible_y + other_sprite.height_ - 1) ); +} diff --git a/src/demos/sprite.hh b/src/demos/sprite.hh new file mode 100644 index 00000000..c73bca54 --- /dev/null +++ b/src/demos/sprite.hh @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include + +#include "screen.hh" +#include "png.hh" + +class sprite_t { +public: + sprite_t(); + ~sprite_t(); + + virtual void set_position(float x, float y); + virtual void set_speed(float dx, float dy); + virtual void move_sprite(void); + virtual void set_image(uint8_t width, uint8_t height, uint32_t *pixels); + virtual void set_image(uint16_t x_offset, uint16_t y_offset, uint8_t width, uint8_t height, png_t *png_image); + virtual void draw_onto(Screen *screen); + virtual void set_active(bool active); + virtual bool is_active(void); + virtual bool test_collision(const sprite_t &other_sprite); + + float x_; + float y_; + float dx_; + float dy_; + + uint8_t width_; + uint8_t height_; + + bool active_; + + std::vector sprite_data_; +}; diff --git a/src/demos/white.c b/src/demos/white.c new file mode 100644 index 00000000..27f0b1c6 --- /dev/null +++ b/src/demos/white.c @@ -0,0 +1,82 @@ +/** \file + * Test the matrix LCD PRU firmware with a multi-hue rainbow. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "ledscape.h" + +void drawpixel(uint32_t *pixels, uint8_t x, uint8_t y, uint32_t color, uint8_t flip) { + uint32_t pixelnum = ((flip ? (64 - y) : y) * 64) + (flip ? (64 - x ) : x); + pixels[pixelnum] = color; +} + +void render_game(uint32_t *pixels) { + for (int y_clear = 0; y_clear < 64; y_clear++) { + for (int x_clear = 0; x_clear < 64; x_clear++) { + drawpixel(pixels, x_clear, y_clear, 0xffffffff, 0); + } + } +} + +int +main( + int argc, + const char ** argv +) +{ + int width = 64; + int height = 64; + + ledscape_config_t * config = &ledscape_matrix_default; + if (argc > 1) + { + config = ledscape_config(argv[1]); + if (!config) + return EXIT_FAILURE; + } + + if (config->type == LEDSCAPE_MATRIX) + { + config->matrix_config.width = width; + config->matrix_config.height = height; + } + + ledscape_t * const leds = ledscape_init(config, 0); + + printf("init done\n"); + time_t last_time = time(NULL); + unsigned last_i = 0; + + unsigned i = 0; + uint32_t * const p = calloc(width*height,4); + + render_game(p); + + i++; + ledscape_draw(leds, p); + + usleep(20000); + + // wait for the previous frame to finish; + //const uint32_t response = ledscape_wait(leds); + const uint32_t response = 0; + time_t now = time(NULL); + if (now != last_time) + { + printf("%d fps. starting %d previous %"PRIx32"\n", + i - last_i, i, response); + last_i = i; + last_time = now; + } + + + ledscape_close(leds); + + return EXIT_SUCCESS; +} diff --git a/src/script/run-ledscape b/src/script/run-ledscape index d488c872..e86b6d4e 100755 --- a/src/script/run-ledscape +++ b/src/script/run-ledscape @@ -4,8 +4,12 @@ cd "$DIRNAME/.." # Enable the octoscroller overlay # Note that we can't do this at boot because it won't load then, for some reason +echo GPIO > /sys/devices/bone_capemgr*/slots echo CAPE-BONE-OCTO > /sys/devices/bone_capemgr*/slots +amixer sset PCM 100 +aplay /root/bach.wav & + # Wait for unknown and unimaginable things to happen sleep 10 @@ -18,5 +22,5 @@ then CONFIGFILE="$USBMOUNT/ledscape.config" fi -exec ./bin/matrix-test "$CONFIGFILE" >/dev/null +exec ./bin/breakout > /dev/null #exec ./bin/matrix-udp-rx -m "Starting LEDscape" -c "$CONFIGFILE" >/dev/null From 7bc132a374f3ba3d015dd0ba62acfb6bc8bb61d1 Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Sun, 8 Feb 2015 20:24:21 -0800 Subject: [PATCH 313/332] Move ledgames stuff to it's own directory --- Makefile | 1 + src/demos/Makefile | 10 - src/demos/robin-hood-test.c | 436 ------------------------ src/ledgames/Makefile | 21 ++ src/{demos => ledgames}/ball_sprite.cc | 0 src/{demos => ledgames}/ball_sprite.hh | 0 src/{demos => ledgames}/black.c | 0 src/{demos => ledgames}/brick_sprite.hh | 0 src/{demos => ledgames}/bricks.cc | 0 src/{demos => ledgames}/controls.cc | 0 src/{demos => ledgames}/controls.hh | 0 src/{demos => ledgames}/gpio_pin.cc | 0 src/{demos => ledgames}/gpio_pin.hh | 0 src/{demos => ledgames}/invaders.cc | 0 src/{demos => ledgames}/png.cc | 0 src/{demos => ledgames}/png.hh | 0 src/{demos => ledgames}/pong.cc | 0 src/{demos => ledgames}/screen.cc | 0 src/{demos => ledgames}/screen.hh | 0 src/{demos => ledgames}/sprite.cc | 0 src/{demos => ledgames}/sprite.hh | 0 src/{demos => ledgames}/white.c | 0 22 files changed, 22 insertions(+), 446 deletions(-) delete mode 100644 src/demos/robin-hood-test.c create mode 100755 src/ledgames/Makefile rename src/{demos => ledgames}/ball_sprite.cc (100%) rename src/{demos => ledgames}/ball_sprite.hh (100%) rename src/{demos => ledgames}/black.c (100%) rename src/{demos => ledgames}/brick_sprite.hh (100%) rename src/{demos => ledgames}/bricks.cc (100%) rename src/{demos => ledgames}/controls.cc (100%) rename src/{demos => ledgames}/controls.hh (100%) rename src/{demos => ledgames}/gpio_pin.cc (100%) rename src/{demos => ledgames}/gpio_pin.hh (100%) rename src/{demos => ledgames}/invaders.cc (100%) rename src/{demos => ledgames}/png.cc (100%) rename src/{demos => ledgames}/png.hh (100%) rename src/{demos => ledgames}/pong.cc (100%) rename src/{demos => ledgames}/screen.cc (100%) rename src/{demos => ledgames}/screen.hh (100%) rename src/{demos => ledgames}/sprite.cc (100%) rename src/{demos => ledgames}/sprite.hh (100%) rename src/{demos => ledgames}/white.c (100%) diff --git a/Makefile b/Makefile index e09bfaf4..218e90ba 100755 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ SUBDIR-y += src/perlin SUBDIR-y += src/mta SUBDIR-y += src/net SUBDIR-y += src/script +SUBDIR-y += src/ledgames all: for dir in $(SUBDIR-y); do \ diff --git a/src/demos/Makefile b/src/demos/Makefile index 5a5dc871..5d23ac93 100755 --- a/src/demos/Makefile +++ b/src/demos/Makefile @@ -8,22 +8,12 @@ BIN-y += life BIN-y += cube-life BIN-y += matrix-test BIN-y += identify -BIN-y += breakout -BIN-y += black -BIN-y += white -BIN-y += pong -BIN-y += invaders fire.srcs += fire.c life.srcs += life.c identify.srcs += identify.c cube-life.srcs += cube-life.c matrix-test.srcs += matrix-test.c -breakout.srcs += bricks.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_sprite.cc -black.srcs += black.c -white.srcs += white.c -pong.srcs += pong.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_sprite.cc -invaders.srcs += invaders.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_sprite.cc png.cc include ../../Makefile.common diff --git a/src/demos/robin-hood-test.c b/src/demos/robin-hood-test.c deleted file mode 100644 index 11bc3fc3..00000000 --- a/src/demos/robin-hood-test.c +++ /dev/null @@ -1,436 +0,0 @@ -/** \file - * Test the matrix LCD PRU firmware with a multi-hue rainbow. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "ledscape.h" - - -// Borrowed by OctoWS2811 rainbow test -static unsigned int -h2rgb( - unsigned int v1, - unsigned int v2, - unsigned int hue -) -{ - if (hue < 60) - return v1 * 60 + (v2 - v1) * hue; - if (hue < 180) - return v2 * 60; - if (hue < 240) - return v1 * 60 + (v2 - v1) * (240 - hue); - - return v1 * 60; -} - - -// Convert HSL (Hue, Saturation, Lightness) to RGB (Red, Green, Blue) -// -// hue: 0 to 359 - position on the color wheel, 0=red, 60=orange, -// 120=yellow, 180=green, 240=blue, 300=violet -// -// saturation: 0 to 100 - how bright or dull the color, 100=full, 0=gray -// -// lightness: 0 to 100 - how light the color is, 100=white, 50=color, 0=black -// -static uint32_t -makeColor( - unsigned int hue, - unsigned int saturation, - unsigned int lightness -) -{ - unsigned int red, green, blue; - unsigned int var1, var2; - - if (hue > 359) - hue = hue % 360; - if (saturation > 100) - saturation = 100; - if (lightness > 100) - lightness = 100; - - // algorithm from: http://www.easyrgb.com/index.php?X=MATH&H=19#text19 - if (saturation == 0) { - red = green = blue = lightness * 255 / 100; - } else { - if (lightness < 50) { - var2 = lightness * (100 + saturation); - } else { - var2 = ((lightness + saturation) * 100) - (saturation * lightness); - } - var1 = lightness * 200 - var2; - red = h2rgb(var1, var2, (hue < 240) ? hue + 120 : hue - 240) * 255 / 600000; - green = h2rgb(var1, var2, hue) * 255 / 600000; - blue = h2rgb(var1, var2, (hue >= 120) ? hue - 120 : hue + 240) * 255 / 600000; - } - return (red << 16) | (green << 8) | blue; -} - - - -static uint32_t rainbowColors[180]; - - -// phaseShift is the shift between each row. phaseShift=0 -// causes all rows to show the same colors moving together. -// phaseShift=180 causes each row to be the opposite colors -// as the previous. -// -// cycleTime is the number of milliseconds to shift through -// the entire 360 degrees of the color wheel: -// Red -> Orange -> Yellow -> Green -> Blue -> Violet -> Red -// -static void -rainbow( - uint32_t * const pixels, - unsigned width, - unsigned height, - unsigned phaseShift, - unsigned cycle -) -{ - const unsigned color = cycle % 180; - const unsigned dim = 128; - - static unsigned count = 0; - - count += 1; - - for (unsigned x=0; x < width; x++) { - for (unsigned y=0; y < height; y++) { - const int index = (color + x + y*phaseShift/4) % 180; - const uint32_t in = rainbowColors[index]; - uint8_t * const out = &pixels[x + y*width]; -#if 1 - out[0] = ((in >> 0) & 0xFF) * dim / 128; // * y / 16; - out[1] = ((in >> 8) & 0xFF) * dim / 128; // * y / 16; - out[2] = ((in >> 16) & 0xFF) * dim / 128; // * y / 16; -#else - if(y==((count >> 3) & 0x1F) && x<20) { - out[0] = 0xff; - out[1] = 0xff; - out[2] = 0x00; - } - else { - out[0] = 0x00; - out[1] = 0x00; - out[2] = 0xff; - } -#endif - } - } -} - - -static void -gradient( - uint32_t * const pixels, - unsigned width, - unsigned height, - unsigned phaseShift, - unsigned cycle -) -{ - cycle >>= 3; - for (unsigned x=0; x < width; x++) { - for (unsigned y=0; y < height; y++) { - uint8_t * const out = &pixels[x + y*width]; -#if 0 - //out[0] = ((x+cycle) % 32) * 8; - //out[1] = ((y+cycle) % 16) * 16; - uint8_t b = 0xFF; - out[1] = b * ((((x + y + cycle) >> 5) ) & 1); -#else - uint32_t b = 0; - - if (x % 32 < (x/32 + 4) && y % 32 < (y/32+1)) - { - b = 0xFFFFFF; - } else - if (x < 32) - { - if (y < 32) - b = 0xFF0000; - else - if (y < 64) - b = 0x0000FF; - else - if (y < 96) - b = 0x00FF00; - else - b = 0x411111; - } else - if (x < 64) - { - if (y < 32) - b = 0xFF00FF; - else - if (y < 64) - b = 0x00FFFF; - else - if (y < 96) - b = 0xFFFF00; - else - b = 0x114111; - } else { - b = 0x111141; - } - - out[0] = (b >> 16) & 0xFF; - out[1] = (b >> 8) & 0xFF; - out[2] = (b >> 0) & 0xFF; - //*out = b; -#endif - } - } -} - -#include -#include -#include -#include -#include - -#define PNG_DEBUG 3 -#include - -void abort_(const char * s, ...) -{ - va_list args; - va_start(args, s); - vfprintf(stderr, s, args); - fprintf(stderr, "\n"); - va_end(args); - abort(); -} - -int png_x, png_y; - -int png_width, png_height; -png_byte color_type; -png_byte bit_depth; - -png_structp png_ptr; -png_infop info_ptr; -int number_of_passes; -png_bytep * row_pointers; - -void read_png_file(char* file_name) -{ - char header[8]; // 8 is the maximum size that can be checked - - /* open file and test for it being a png */ - FILE *fp = fopen(file_name, "rb"); - if (!fp) - abort_("[read_png_file] File %s could not be opened for reading", file_name); - fread(header, 1, 8, fp); - if (png_sig_cmp(header, 0, 8)) - abort_("[read_png_file] File %s is not recognized as a PNG file", file_name); - - - /* initialize stuff */ - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - - if (!png_ptr) - abort_("[read_png_file] png_create_read_struct failed"); - - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) - abort_("[read_png_file] png_create_info_struct failed"); - - if (setjmp(png_jmpbuf(png_ptr))) - abort_("[read_png_file] Error during init_io"); - - png_init_io(png_ptr, fp); - png_set_sig_bytes(png_ptr, 8); - - png_read_info(png_ptr, info_ptr); - - png_width = png_get_image_width(png_ptr, info_ptr); - png_height = png_get_image_height(png_ptr, info_ptr); - color_type = png_get_color_type(png_ptr, info_ptr); - bit_depth = png_get_bit_depth(png_ptr, info_ptr); - - number_of_passes = png_set_interlace_handling(png_ptr); - png_read_update_info(png_ptr, info_ptr); - - - /* read file */ - if (setjmp(png_jmpbuf(png_ptr))) - abort_("[read_png_file] Error during read_image"); - - row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * png_height); - for (png_y=0; png_y> 2; - out[1] = ptr[1] >> 2; - out[2] = ptr[0] >> 2; - } - } -} - -#define BUTTON_PLAYERSTART_P1 70 -#define BUTTON_PLAYERSTART_P2 71 -#define BUTTON_P1_JOYUP 79 -#define BUTTON_P1_JOYDN 73 -#define BUTTON_P1_JOYLEFT 74 -#define BUTTON_P1_JOYRIGHT 75 -#define BUTTON_P1_ACTION_PRI 76 -#define BUTTON_P1_ACTION_SEC 77 - -void export_button_gpio (uint8_t button_number) { - FILE *exportfile = fopen("/sys/class/gpio/export", "w"); - if (NULL == exportfile) { - printf("Failed opening export device"); - return; - } - - fprintf(exportfile, "%d", button_number); - fclose(exportfile); -} - -uint8_t button_pressed(uint8_t button_number) { - char button_file_name[1024]; - snprintf(button_file_name, 1024, "/sys/class/gpio/gpio%d/value", button_number); - FILE *button_file = fopen(button_file_name, "r"); - if (NULL == button_file) { - printf("Failed opening button %d\n", button_number); - return 0; - } - int button_value; - fscanf(button_file, "%d", &button_value); - fclose(button_file); - return (button_value == 0) ? 1 : 0; -} - -int -main( - int argc, - const char ** argv -) -{ - int width = 64; - int height = 64; - - ledscape_config_t * config = &ledscape_matrix_default; - if (argc > 1) - { - config = ledscape_config(argv[1]); - if (!config) - return EXIT_FAILURE; - } - - if (config->type == LEDSCAPE_MATRIX) - { - config->matrix_config.width = width; - config->matrix_config.height = height; - } - - ledscape_t * const leds = ledscape_init(config, 0); - - export_button_gpio(BUTTON_PLAYERSTART_P1); - export_button_gpio(BUTTON_PLAYERSTART_P2); - export_button_gpio(BUTTON_P1_JOYUP); - export_button_gpio(BUTTON_P1_JOYDN); - export_button_gpio(BUTTON_P1_JOYLEFT); - export_button_gpio(BUTTON_P1_JOYRIGHT); - export_button_gpio(BUTTON_P1_ACTION_PRI); - export_button_gpio(BUTTON_P1_ACTION_SEC); - - printf("init done\n"); - time_t last_time = time(NULL); - unsigned last_i = 0; - - // pre-compute the 180 rainbow colors - for (int i=0; i<180; i++) - { - int hue = i * 2; - int saturation = 100; - int lightness = 50; - rainbowColors[i] = makeColor(hue, saturation, lightness); - } - - read_png_file("/root/robin-hood.png"); - - unsigned i = 0; - uint32_t * const p = calloc(width*height,4); - - while (1) - { -/* - if (1) - rainbow(p, width, height, 10, i++); - else - gradient(p, width, height, 10, i++); -*/ - process_file(p); - i++; - ledscape_draw(leds, p); - - if (button_pressed(BUTTON_PLAYERSTART_P1)) { - printf("PLAYER 1 START\n"); - } - if (button_pressed(BUTTON_PLAYERSTART_P2)) { - printf("PLAYER 2 START\n"); - } - if (button_pressed(BUTTON_P1_JOYUP)) { - printf("P1-UP\n"); - } - if (button_pressed(BUTTON_P1_JOYDN)) { - printf("P1-DOWN\n"); - } - if (button_pressed(BUTTON_P1_JOYLEFT)) { - printf("P1-LEFT\n"); - } - if (button_pressed(BUTTON_P1_JOYRIGHT)) { - printf("P1-RIGHT\n"); - } - if (button_pressed(BUTTON_P1_ACTION_PRI)) { - printf("P1-PRI\n"); - } - if (button_pressed(BUTTON_P1_ACTION_SEC)) { - printf("P1-SEC\n"); - } - - - usleep(20000); - - // wait for the previous frame to finish; - //const uint32_t response = ledscape_wait(leds); - const uint32_t response = 0; - time_t now = time(NULL); - if (now != last_time) - { - printf("%d fps. starting %d previous %"PRIx32"\n", - i - last_i, i, response); - last_i = i; - last_time = now; - } - - } - - ledscape_close(leds); - - return EXIT_SUCCESS; -} diff --git a/src/ledgames/Makefile b/src/ledgames/Makefile new file mode 100755 index 00000000..6956b37c --- /dev/null +++ b/src/ledgames/Makefile @@ -0,0 +1,21 @@ +######### +# +# Build the various demos +# +# +BIN-y += robin-hood-test +BIN-y += breakout +BIN-y += black +BIN-y += white +BIN-y += pong +BIN-y += invaders + +robin-hood-test.srcs += robin-hood-test.c +breakout.srcs += bricks.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_sprite.cc +black.srcs += black.c +white.srcs += white.c +pong.srcs += pong.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_sprite.cc +invaders.srcs += invaders.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_sprite.cc png.cc + +include ../../Makefile.common + diff --git a/src/demos/ball_sprite.cc b/src/ledgames/ball_sprite.cc similarity index 100% rename from src/demos/ball_sprite.cc rename to src/ledgames/ball_sprite.cc diff --git a/src/demos/ball_sprite.hh b/src/ledgames/ball_sprite.hh similarity index 100% rename from src/demos/ball_sprite.hh rename to src/ledgames/ball_sprite.hh diff --git a/src/demos/black.c b/src/ledgames/black.c similarity index 100% rename from src/demos/black.c rename to src/ledgames/black.c diff --git a/src/demos/brick_sprite.hh b/src/ledgames/brick_sprite.hh similarity index 100% rename from src/demos/brick_sprite.hh rename to src/ledgames/brick_sprite.hh diff --git a/src/demos/bricks.cc b/src/ledgames/bricks.cc similarity index 100% rename from src/demos/bricks.cc rename to src/ledgames/bricks.cc diff --git a/src/demos/controls.cc b/src/ledgames/controls.cc similarity index 100% rename from src/demos/controls.cc rename to src/ledgames/controls.cc diff --git a/src/demos/controls.hh b/src/ledgames/controls.hh similarity index 100% rename from src/demos/controls.hh rename to src/ledgames/controls.hh diff --git a/src/demos/gpio_pin.cc b/src/ledgames/gpio_pin.cc similarity index 100% rename from src/demos/gpio_pin.cc rename to src/ledgames/gpio_pin.cc diff --git a/src/demos/gpio_pin.hh b/src/ledgames/gpio_pin.hh similarity index 100% rename from src/demos/gpio_pin.hh rename to src/ledgames/gpio_pin.hh diff --git a/src/demos/invaders.cc b/src/ledgames/invaders.cc similarity index 100% rename from src/demos/invaders.cc rename to src/ledgames/invaders.cc diff --git a/src/demos/png.cc b/src/ledgames/png.cc similarity index 100% rename from src/demos/png.cc rename to src/ledgames/png.cc diff --git a/src/demos/png.hh b/src/ledgames/png.hh similarity index 100% rename from src/demos/png.hh rename to src/ledgames/png.hh diff --git a/src/demos/pong.cc b/src/ledgames/pong.cc similarity index 100% rename from src/demos/pong.cc rename to src/ledgames/pong.cc diff --git a/src/demos/screen.cc b/src/ledgames/screen.cc similarity index 100% rename from src/demos/screen.cc rename to src/ledgames/screen.cc diff --git a/src/demos/screen.hh b/src/ledgames/screen.hh similarity index 100% rename from src/demos/screen.hh rename to src/ledgames/screen.hh diff --git a/src/demos/sprite.cc b/src/ledgames/sprite.cc similarity index 100% rename from src/demos/sprite.cc rename to src/ledgames/sprite.cc diff --git a/src/demos/sprite.hh b/src/ledgames/sprite.hh similarity index 100% rename from src/demos/sprite.hh rename to src/ledgames/sprite.hh diff --git a/src/demos/white.c b/src/ledgames/white.c similarity index 100% rename from src/demos/white.c rename to src/ledgames/white.c From 86039721f03055ab1afc70f756389d69c2952055 Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Mon, 16 Feb 2015 14:21:19 -0800 Subject: [PATCH 314/332] Draws some invaders --- src/ledgames/invaders.cc | 175 ++++++++++++++++++++------------------- 1 file changed, 90 insertions(+), 85 deletions(-) diff --git a/src/ledgames/invaders.cc b/src/ledgames/invaders.cc index c9b00417..fd15443b 100644 --- a/src/ledgames/invaders.cc +++ b/src/ledgames/invaders.cc @@ -26,16 +26,21 @@ static controls_t *player_controls[3]; static int player_score[2]; +static int player_lives[2]; static int number_players; -static int serving_player; +static int current_player; -static sprite_t paddle_sprite[2]; +static sprite_t paddle_sprite; static ball_sprite_t ball_sprite; -static png_t sprite_sheet; +static std::vector invader_sprites[2]; static Mix_Chunk *startup_bong; +static Mix_Chunk *wall_blip; +static Mix_Chunk *block_blip[3]; static Mix_Chunk *paddle_blip; +static png_t sprite_sheet; + enum class game_state_t { Attract, Serving, @@ -58,19 +63,29 @@ static float ball_horizontal_speeds[] = { }; uint32_t ball_data[] = {0x00808000, 0x00808000, 0x00808000, 0x00808000}; +uint32_t paddle_data[] = {0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF}; + +static void reset_invaders(int for_player) { + invader_sprites[for_player].clear(); + for (int row_counter = 0; row_counter < 4; row_counter++) { + for (int column_counter = 0; column_counter < 6; column_counter++) { + brick_sprite_t invader_sprite; + invader_sprite.set_active(true); + invader_sprite.set_position(column_counter * 10, 10 + (row_counter * 8)); + invader_sprite.set_image(row_counter * 28,0,7,7,&sprite_sheet); + invader_sprites[for_player].push_back(invader_sprite); + } + } +} static bool reset_round(void) { - if ((player_score[0] == 7) || (player_score[1] == 7)) { + current_player = (current_player + 1) % number_players; + if (player_lives[current_player] == 0) { return false; } - - if (serving_player == 0) { - ball_sprite.set_position(paddle_sprite[0].x_+4,58); - ball_sprite.set_speed(ball_horizontal_speeds[rand()%7], -0.5f); - } else { - ball_sprite.set_position(paddle_sprite[1].x_+4,6); - ball_sprite.set_speed(ball_horizontal_speeds[rand()%7], 0.5f); - } + + ball_sprite.set_position(32,32); + ball_sprite.set_speed(0.3f, 0.5f); ball_sprite.set_image(1,1,ball_data); game_state = game_state_t::Serving; @@ -79,20 +94,21 @@ static bool reset_round(void) { } static void reset_game(int with_number_players) { - paddle_sprite[0].set_active(true); - paddle_sprite[0].set_position(28, 32); - paddle_sprite[0].set_image(0,0,7,7,&sprite_sheet); + paddle_sprite.set_active(true); + paddle_sprite.set_position(28, 60); + paddle_sprite.set_image(8,2,paddle_data); - paddle_sprite[1].set_active(true); - paddle_sprite[1].set_position(28, 2); - paddle_sprite[1].set_image(28,0,7,7,&sprite_sheet); + reset_invaders(0); + reset_invaders(1); player_score[0] = 0; player_score[1] = 0; - - serving_player = 0; + + player_lives[0] = 3; + player_lives[1] = 3; number_players = with_number_players; + current_player = 1; reset_round(); @@ -100,41 +116,51 @@ static void reset_game(int with_number_players) { } void init_attract(void) { - paddle_sprite[0].set_active(false); - paddle_sprite[1].set_active(false); + paddle_sprite.set_active(false); ball_sprite.set_position(32,32); ball_sprite.set_speed(0.5f, 0.5f); ball_sprite.set_image(1,1,ball_data); + current_player = 0; + reset_invaders(0); + game_state = game_state_t::Attract; } void render_game(Screen *screen) { - screen->set_flip(false); - + if (current_player == 1) { + screen->set_flip(true); + } else { + screen->set_flip(false); + } screen->set_background_color(0x00000010); screen->draw_start(); + paddle_sprite.draw_onto(screen); + ball_sprite.draw_onto(screen); + + for (auto &invader_sprite : invader_sprites[current_player]) { + invader_sprite.draw_onto(screen); + } + if (game_state == game_state_t::Attract) { screen->draw_text(32,2,0x00808080,"GAME OVER!"); screen->draw_text(40,2,0x00808080,"PRESS PLYR"); screen->draw_text(48,2,0x00808080," 1 OR 2 "); + } else { + char score[7]; + char lives[1]; + sprintf(score, "%06d", player_score[current_player]); + screen->draw_text(0,2,0x00808080,score); + sprintf(lives, "%01d", player_lives[current_player]); + screen->draw_text(0,48,0x00808080,lives); + } - char score[7]; - sprintf(score, "%1d", player_score[1]); - screen->draw_text(0,59,0x00808080,score,number_players==2); - sprintf(score, "%1d", player_score[0]); - screen->draw_text(57,59,0x00808080,score); - paddle_sprite[0].draw_onto(screen); - paddle_sprite[1].draw_onto(screen); - ball_sprite.draw_onto(screen); - screen->draw_end(); - player_controls[0]->refresh_status(); - player_controls[1]->refresh_status(); + player_controls[current_player]->refresh_status(); if (game_state == game_state_t::Attract) { player_controls[2]->refresh_status(); @@ -145,35 +171,22 @@ void render_game(Screen *screen) { } return; } else { - for (int player = 0; player < number_players; player++) { - if (player_controls[player]->is_pressed(joystick_left)) { - if (paddle_sprite[player].x_ > 0) { - paddle_sprite[player].x_--; - } + if (player_controls[current_player]->is_pressed(joystick_left)) { + if (paddle_sprite.x_ > 0) { + paddle_sprite.x_--; } + } - if (player_controls[player]->is_pressed(joystick_right)) { - if (paddle_sprite[player].x_ < 56) { - paddle_sprite[player].x_++; - } + if (player_controls[current_player]->is_pressed(joystick_right)) { + if (paddle_sprite.x_ < 56) { + paddle_sprite.x_++; } } if (game_state == game_state_t::Serving) { - ball_sprite.x_ = paddle_sprite[serving_player].x_ + 4; - if (player_controls[serving_player]->is_pressed(button_a)) { + if (player_controls[current_player]->is_pressed(button_a)) { game_state = game_state_t::Playing; } } - - if (number_players == 1) { - float computer_paddle_x_target = ball_sprite.x_ - 4; - - if (computer_paddle_x_target > paddle_sprite[1].x_) paddle_sprite[1].x_ += 0.8f; - if (computer_paddle_x_target < paddle_sprite[1].x_) paddle_sprite[1].x_ -= 0.8f; - - if (paddle_sprite[1].x_ < 0) { paddle_sprite[1].x_ = 0; } - if (paddle_sprite[1].x_ > 56) { paddle_sprite[1].x_ = 56; } - } } // Move ball @@ -181,30 +194,16 @@ void render_game(Screen *screen) { ball_sprite.move_sprite(); } - if (ball_sprite.test_collision(paddle_sprite[0])) { + if (ball_sprite.test_collision(paddle_sprite)) { ball_sprite.y_ = 59.0f; - ball_sprite.dy_ = -ball_sprite.dy_ * 1.1f; - if (ball_sprite.dy_ < -2.0f) ball_sprite.dy_ = -2.0f; - ball_sprite.dx_ = ball_horizontal_speeds[(int)(ball_sprite.x_ - (paddle_sprite[0].x_ - 1))]; - Mix_PlayChannel(-1, paddle_blip, 0); - } - - if (ball_sprite.test_collision(paddle_sprite[1])) { - ball_sprite.y_ = 5.0f; - ball_sprite.dy_ = -ball_sprite.dy_ * 1.1f; - if (ball_sprite.dy_ > 2.0f) ball_sprite.dy_ = 2.0f; - ball_sprite.dx_ = ball_horizontal_speeds[(int)(ball_sprite.x_ - (paddle_sprite[1].x_ - 1))]; + ball_sprite.dy_ = -ball_sprite.dy_; + ball_sprite.dx_ = ball_horizontal_speeds[(int)(ball_sprite.x_ - (paddle_sprite.x_ - 1))]; Mix_PlayChannel(-1, paddle_blip, 0); } if (ball_sprite.y_ >= 63.0f) { if (game_state != game_state_t::Attract) { - player_score[1]++; - if (number_players == 2) { - serving_player = 1; - } else { - serving_player = 0; - } + player_lives[current_player]--; if (!reset_round()) { init_attract(); } @@ -215,17 +214,19 @@ void render_game(Screen *screen) { } } - if (ball_sprite.y_ <= 0.0f) { + if (game_state == game_state_t::Playing) { + bool active_invaders = false; + for (auto &invader_sprite : invader_sprites[current_player]) { + active_invaders |= invader_sprite.is_active(); + } + if (!active_invaders) { + reset_invaders(current_player); + } + } else { if (game_state != game_state_t::Attract) { - player_score[0]++; - serving_player = 0; - if (!reset_round()) { - init_attract(); + if ((ball_sprite.y_ < 9) || (ball_sprite.y_ > 32)) { + game_state = game_state_t::Playing; } - return; - } else { - ball_sprite.dy_ = -ball_sprite.dy_; - ball_sprite.dx_ = ball_horizontal_speeds[rand()%7]; } } } @@ -279,11 +280,11 @@ main( } ledscape_t * const leds = ledscape_init(config, 0); - + sprite_sheet.read_file("/root/Invaders.png"); player_controls[0] = new controls_t(1); - player_controls[1] = new controls_t(2, true); + player_controls[1] = new controls_t(2); player_controls[2] = new controls_t(3); init_attract(); @@ -295,7 +296,11 @@ main( init_sdl(); + wall_blip = Mix_LoadWAV("/root/blip1.wav"); paddle_blip = Mix_LoadWAV("/root/blip2.wav"); + block_blip[0] = Mix_LoadWAV("/root/blip3.wav"); + block_blip[1] = Mix_LoadWAV("/root/blip4.wav"); + block_blip[2] = Mix_LoadWAV("/root/blip5.wav"); while (1) { From a10ce3036e372cf6ca84eb89b9d0b3c0f9df7448 Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Mon, 16 Feb 2015 19:03:03 -0800 Subject: [PATCH 315/332] Sprites move and animate. --- src/ledgames/Makefile | 2 +- src/ledgames/invader_sprite.cc | 12 + src/ledgames/invader_sprite.hh | 15 ++ src/ledgames/invaders.cc | 399 ++++++++++++++------------------- src/ledgames/screen.cc | 93 ++++---- src/ledgames/sprite.cc | 15 +- src/ledgames/sprite.hh | 7 +- 7 files changed, 258 insertions(+), 285 deletions(-) create mode 100644 src/ledgames/invader_sprite.cc create mode 100644 src/ledgames/invader_sprite.hh diff --git a/src/ledgames/Makefile b/src/ledgames/Makefile index 6956b37c..8491cc76 100755 --- a/src/ledgames/Makefile +++ b/src/ledgames/Makefile @@ -15,7 +15,7 @@ breakout.srcs += bricks.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_spri black.srcs += black.c white.srcs += white.c pong.srcs += pong.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_sprite.cc -invaders.srcs += invaders.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_sprite.cc png.cc +invaders.srcs += invaders.cc gpio_pin.cc controls.cc screen.cc sprite.cc invader_sprite.cc png.cc include ../../Makefile.common diff --git a/src/ledgames/invader_sprite.cc b/src/ledgames/invader_sprite.cc new file mode 100644 index 00000000..270e5fe9 --- /dev/null +++ b/src/ledgames/invader_sprite.cc @@ -0,0 +1,12 @@ +#include "invader_sprite.hh" + +invader_sprite_t::invader_sprite_t() : + sprite_t() +{ +} + +void invader_sprite_t::move_sprite(void) { + sprite_t::move_sprite(); + + frame_ = (int)x_ % 2; +} diff --git a/src/ledgames/invader_sprite.hh b/src/ledgames/invader_sprite.hh new file mode 100644 index 00000000..0d4c2edb --- /dev/null +++ b/src/ledgames/invader_sprite.hh @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#include "sprite.hh" + +class invader_sprite_t : public sprite_t { +public: + invader_sprite_t(); + + virtual void move_sprite(void) override; + +private: +}; diff --git a/src/ledgames/invaders.cc b/src/ledgames/invaders.cc index fd15443b..e93f9e52 100644 --- a/src/ledgames/invaders.cc +++ b/src/ledgames/invaders.cc @@ -1,6 +1,6 @@ /** \file - * Test the matrix LCD PRU firmware with a multi-hue rainbow. - */ +* Test the matrix LCD PRU firmware with a multi-hue rainbow. +*/ #include #include #include @@ -20,8 +20,7 @@ #include "controls.hh" #include "screen.hh" #include "sprite.hh" -#include "ball_sprite.hh" -#include "brick_sprite.hh" +#include "invader_sprite.hh" #include "png.hh" static controls_t *player_controls[3]; @@ -30,9 +29,8 @@ static int player_lives[2]; static int number_players; static int current_player; -static sprite_t paddle_sprite; -static ball_sprite_t ball_sprite; -static std::vector invader_sprites[2]; +static sprite_t ship_sprite; +static std::vector invader_sprites[2]; static Mix_Chunk *startup_bong; static Mix_Chunk *wall_blip; @@ -42,275 +40,218 @@ static Mix_Chunk *paddle_blip; static png_t sprite_sheet; enum class game_state_t { - Attract, - Serving, - Playing, - Resetting, + Attract, + Serving, + Playing, + Resetting, }; static game_state_t game_state; -static float ball_horizontal_speeds[] = { - -1.1f, - -0.9f, - -0.7f, - -0.5f, - 0.3f, - 0.5f, - 0.7f, - 0.9f, - 1.1f -}; - -uint32_t ball_data[] = {0x00808000, 0x00808000, 0x00808000, 0x00808000}; -uint32_t paddle_data[] = {0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x0000FFFF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF}; - static void reset_invaders(int for_player) { - invader_sprites[for_player].clear(); - for (int row_counter = 0; row_counter < 4; row_counter++) { - for (int column_counter = 0; column_counter < 6; column_counter++) { - brick_sprite_t invader_sprite; - invader_sprite.set_active(true); - invader_sprite.set_position(column_counter * 10, 10 + (row_counter * 8)); - invader_sprite.set_image(row_counter * 28,0,7,7,&sprite_sheet); - invader_sprites[for_player].push_back(invader_sprite); - } - } + invader_sprites[for_player].clear(); + for (int row_counter = 0; row_counter < 4; row_counter++) { + for (int column_counter = 0; column_counter < 6; column_counter++) { + invader_sprite_t invader_sprite; + invader_sprite.set_active(true); + invader_sprite.set_speed(0.05, 0.0); + invader_sprite.set_position(column_counter * 10, 10 + (row_counter * 8)); + invader_sprite.set_image(row_counter * 28,0,7,7,&sprite_sheet, 0); + invader_sprite.set_image((row_counter * 28) + 7,0,7,7,&sprite_sheet, 1); + invader_sprites[for_player].push_back(invader_sprite); + } + } } static bool reset_round(void) { - current_player = (current_player + 1) % number_players; - if (player_lives[current_player] == 0) { - return false; - } - - ball_sprite.set_position(32,32); - ball_sprite.set_speed(0.3f, 0.5f); - ball_sprite.set_image(1,1,ball_data); + current_player = (current_player + 1) % number_players; + if (player_lives[current_player] == 0) { + return false; + } - game_state = game_state_t::Serving; + game_state = game_state_t::Serving; - return true; + return true; } static void reset_game(int with_number_players) { - paddle_sprite.set_active(true); - paddle_sprite.set_position(28, 60); - paddle_sprite.set_image(8,2,paddle_data); + ship_sprite.set_active(true); + ship_sprite.set_position(28, 55); + ship_sprite.set_image(168,0,7,7,&sprite_sheet); - reset_invaders(0); - reset_invaders(1); + reset_invaders(0); + reset_invaders(1); - player_score[0] = 0; - player_score[1] = 0; + player_score[0] = 0; + player_score[1] = 0; - player_lives[0] = 3; - player_lives[1] = 3; + player_lives[0] = 3; + player_lives[1] = 3; - number_players = with_number_players; - current_player = 1; + number_players = with_number_players; + current_player = 1; - reset_round(); + reset_round(); - printf("\n\n\nGAME START\n\n\n"); + printf("\n\n\nGAME START\n\n\n"); } void init_attract(void) { - paddle_sprite.set_active(false); + ship_sprite.set_active(false); - ball_sprite.set_position(32,32); - ball_sprite.set_speed(0.5f, 0.5f); - ball_sprite.set_image(1,1,ball_data); - - current_player = 0; - reset_invaders(0); + current_player = 0; + reset_invaders(0); - game_state = game_state_t::Attract; + game_state = game_state_t::Attract; } void render_game(Screen *screen) { - if (current_player == 1) { - screen->set_flip(true); - } else { - screen->set_flip(false); - } - screen->set_background_color(0x00000010); - screen->draw_start(); - - paddle_sprite.draw_onto(screen); - ball_sprite.draw_onto(screen); - - for (auto &invader_sprite : invader_sprites[current_player]) { - invader_sprite.draw_onto(screen); - } - - if (game_state == game_state_t::Attract) { - screen->draw_text(32,2,0x00808080,"GAME OVER!"); - screen->draw_text(40,2,0x00808080,"PRESS PLYR"); - screen->draw_text(48,2,0x00808080," 1 OR 2 "); - } else { - char score[7]; - char lives[1]; - sprintf(score, "%06d", player_score[current_player]); - screen->draw_text(0,2,0x00808080,score); - sprintf(lives, "%01d", player_lives[current_player]); - screen->draw_text(0,48,0x00808080,lives); - - } + if (current_player == 1) { + screen->set_flip(true); + } else { + screen->set_flip(false); + } + screen->set_background_color(0x00000000); + screen->draw_start(); + + ship_sprite.draw_onto(screen); + + for (auto &invader_sprite : invader_sprites[current_player]) { + invader_sprite.move_sprite(); + invader_sprite.draw_onto(screen); + } + + if (game_state == game_state_t::Attract) { + screen->draw_text(32,2,0x00808080,"GAME OVER!"); + screen->draw_text(40,2,0x00808080,"PRESS PLYR"); + screen->draw_text(48,2,0x00808080," 1 OR 2 "); + } else { + char score[7]; + char lives[1]; + sprintf(score, "%06d", player_score[current_player]); + screen->draw_text(0,2,0x00808080,score); + sprintf(lives, "%01d", player_lives[current_player]); + screen->draw_text(0,48,0x00808080,lives); + + } - screen->draw_end(); + screen->draw_end(); - player_controls[current_player]->refresh_status(); + player_controls[current_player]->refresh_status(); - if (game_state == game_state_t::Attract) { - player_controls[2]->refresh_status(); - if (player_controls[2]->is_pressed(button_a)) { - reset_game(1); - } else if (player_controls[2]->is_pressed(button_b)) { - reset_game(2); - } - return; - } else { - if (player_controls[current_player]->is_pressed(joystick_left)) { - if (paddle_sprite.x_ > 0) { - paddle_sprite.x_--; - } - } + if (game_state == game_state_t::Attract) { + player_controls[2]->refresh_status(); + if (player_controls[2]->is_pressed(button_a)) { + reset_game(1); + } else if (player_controls[2]->is_pressed(button_b)) { + reset_game(2); + } + return; + } else { + if (player_controls[current_player]->is_pressed(joystick_left)) { + if (ship_sprite.x_ > 0) { + ship_sprite.x_--; + } + } - if (player_controls[current_player]->is_pressed(joystick_right)) { - if (paddle_sprite.x_ < 56) { - paddle_sprite.x_++; - } - } - if (game_state == game_state_t::Serving) { - if (player_controls[current_player]->is_pressed(button_a)) { - game_state = game_state_t::Playing; - } - } - } - - // Move ball - if (game_state != game_state_t::Serving) { - ball_sprite.move_sprite(); - } - - if (ball_sprite.test_collision(paddle_sprite)) { - ball_sprite.y_ = 59.0f; - ball_sprite.dy_ = -ball_sprite.dy_; - ball_sprite.dx_ = ball_horizontal_speeds[(int)(ball_sprite.x_ - (paddle_sprite.x_ - 1))]; - Mix_PlayChannel(-1, paddle_blip, 0); - } - - if (ball_sprite.y_ >= 63.0f) { - if (game_state != game_state_t::Attract) { - player_lives[current_player]--; - if (!reset_round()) { - init_attract(); - } - return; - } else { - ball_sprite.dy_ = -ball_sprite.dy_; - ball_sprite.dx_ = ball_horizontal_speeds[rand()%7]; - } - } - - if (game_state == game_state_t::Playing) { - bool active_invaders = false; - for (auto &invader_sprite : invader_sprites[current_player]) { - active_invaders |= invader_sprite.is_active(); + if (player_controls[current_player]->is_pressed(joystick_right)) { + if (ship_sprite.x_ < 57) { + ship_sprite.x_++; + } + } + } + + if (game_state == game_state_t::Playing) { + bool active_invaders = false; + for (auto &invader_sprite : invader_sprites[current_player]) { + active_invaders |= invader_sprite.is_active(); + } + if (!active_invaders) { + reset_invaders(current_player); + } } - if (!active_invaders) { - reset_invaders(current_player); - } - } else { - if (game_state != game_state_t::Attract) { - if ((ball_sprite.y_ < 9) || (ball_sprite.y_ > 32)) { - game_state = game_state_t::Playing; - } - } - } } static void init_sdl(void) { - if (SDL_Init(SDL_INIT_AUDIO) != 0) { - fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); - exit(1); - } - - int audio_rate = 44100; - Uint16 audio_format = AUDIO_S16SYS; - int audio_channels = 2; - int audio_buffers = 8192; - - if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) != 0) { - fprintf(stderr, "Unable to initialize audio: %s\n", Mix_GetError()); - exit(1); - } - - startup_bong = Mix_LoadWAV("/root/startup.wav"); - if (startup_bong == NULL) { - fprintf(stderr, "Unable to load startup.wav: %s\n", Mix_GetError()); - exit(1); - } - - Mix_PlayChannel(-1, startup_bong, 0); + if (SDL_Init(SDL_INIT_AUDIO) != 0) { + fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); + exit(1); + } + + int audio_rate = 44100; + Uint16 audio_format = AUDIO_S16SYS; + int audio_channels = 2; + int audio_buffers = 8192; + + if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) != 0) { + fprintf(stderr, "Unable to initialize audio: %s\n", Mix_GetError()); + exit(1); + } + + startup_bong = Mix_LoadWAV("/root/startup.wav"); + if (startup_bong == NULL) { + fprintf(stderr, "Unable to load startup.wav: %s\n", Mix_GetError()); + exit(1); + } + + Mix_PlayChannel(-1, startup_bong, 0); } int -main( - int argc, - const char ** argv - ) + main( + int argc, +const char ** argv + ) { - int width = 64; - int height = 64; - - ledscape_config_t * config = &ledscape_matrix_default; - if (argc > 1) - { - config = ledscape_config(argv[1]); - if (!config) - return EXIT_FAILURE; - } - - if (config->type == LEDSCAPE_MATRIX) - { - config->matrix_config.width = width; - config->matrix_config.height = height; - } - - ledscape_t * const leds = ledscape_init(config, 0); - - sprite_sheet.read_file("/root/Invaders.png"); - - player_controls[0] = new controls_t(1); - player_controls[1] = new controls_t(2); - player_controls[2] = new controls_t(3); + int width = 64; + int height = 64; + + ledscape_config_t * config = &ledscape_matrix_default; + if (argc > 1) + { + config = ledscape_config(argv[1]); + if (!config) + return EXIT_FAILURE; + } + + if (config->type == LEDSCAPE_MATRIX) + { + config->matrix_config.width = width; + config->matrix_config.height = height; + } + + ledscape_t * const leds = ledscape_init(config, 0); + + sprite_sheet.read_file("/root/Invaders.png"); + + player_controls[0] = new controls_t(1); + player_controls[1] = new controls_t(2); + player_controls[2] = new controls_t(3); - init_attract(); + init_attract(); - printf("init done\n"); - uint32_t * const p = (uint32_t*)calloc(width*height,4); + printf("init done\n"); + uint32_t * const p = (uint32_t*)calloc(width*height,4); - Screen *screen = new Screen(leds, p); + Screen *screen = new Screen(leds, p); - init_sdl(); + init_sdl(); - wall_blip = Mix_LoadWAV("/root/blip1.wav"); - paddle_blip = Mix_LoadWAV("/root/blip2.wav"); - block_blip[0] = Mix_LoadWAV("/root/blip3.wav"); - block_blip[1] = Mix_LoadWAV("/root/blip4.wav"); - block_blip[2] = Mix_LoadWAV("/root/blip5.wav"); + wall_blip = Mix_LoadWAV("/root/blip1.wav"); + paddle_blip = Mix_LoadWAV("/root/blip2.wav"); + block_blip[0] = Mix_LoadWAV("/root/blip3.wav"); + block_blip[1] = Mix_LoadWAV("/root/blip4.wav"); + block_blip[2] = Mix_LoadWAV("/root/blip5.wav"); - while (1) - { - render_game(screen); + while (1) + { + render_game(screen); - usleep(20000); + usleep(20000); - } + } - ledscape_close(leds); + ledscape_close(leds); - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/src/ledgames/screen.cc b/src/ledgames/screen.cc index 4691b9c4..5792a5c3 100644 --- a/src/ledgames/screen.cc +++ b/src/ledgames/screen.cc @@ -4,73 +4,76 @@ extern const uint8_t fixed_font[][5]; Screen::Screen(ledscape_t * const leds, uint32_t *pixels): - pixels_(pixels), - leds_(leds), - flip_(false) +pixels_(pixels), +leds_(leds), +flip_(false) { - set_background_color(0x00000000); - draw_start(); - ledscape_printf(&pixels_[9], 64, 0x00401010, "LedGames\n Engine"); - ledscape_printf(&pixels_[64*32 + 17], 64, 0x00101040, "Keith"); - ledscape_printf(&pixels_[64*40 + 2], 64, 0x00101040, "Henrickson"); - draw_end(); - sleep(1); + set_background_color(0x00000000); + draw_start(); + ledscape_printf(&pixels_[9], 64, 0x00401010, "LedGames\n Engine"); + ledscape_printf(&pixels_[64*32 + 17], 64, 0x00101040, "Keith"); + ledscape_printf(&pixels_[64*40 + 2], 64, 0x00101040, "Henrickson"); + draw_end(); + sleep(1); } void Screen::drawpixel(uint32_t x, uint32_t y, uint32_t color) { - uint32_t pixelnum = ((flip_ ? (63 - y) : y) * 64) + (flip_ ? (63 - x ) : x); - pixels_[pixelnum] = color; + if ((x > 63) || (y > 63)) { + return; + } + uint32_t pixelnum = ((flip_ ? (63 - y) : y) * 64) + (flip_ ? (63 - x ) : x); + pixels_[pixelnum] = color; } void Screen::set_background_color(uint32_t color) { - background_color_ = color; + background_color_ = color; } void Screen::draw_char(uint8_t row, uint8_t column, const uint32_t color, char c, bool flip) { - if (c < 0x20 || c > 127) - c = '?'; + if (c < 0x20 || c > 127) + c = '?'; - const uint8_t* const f = fixed_font[c - 0x20]; - for (int x = 0 ; x < 5 ; x++) { - uint8_t bits = f[x]; - for (int y = 0 ; y < 7 ; y++, bits >>= 1) { - if (flip) { - drawpixel((4-x) + column, (6-y) + row, (bits & 1) ? color : 0); - } else { - drawpixel(x + column, y + row, (bits & 1) ? color : 0); - } - } - } + const uint8_t* const f = fixed_font[c - 0x20]; + for (int x = 0 ; x < 5 ; x++) { + uint8_t bits = f[x]; + for (int y = 0 ; y < 7 ; y++, bits >>= 1) { + if (flip) { + drawpixel((4-x) + column, (6-y) + row, (bits & 1) ? color : 0); + } else { + drawpixel(x + column, y + row, (bits & 1) ? color : 0); + } + } + } } void Screen::draw_text(uint8_t row, uint8_t column, uint32_t color, std::string output, bool flip) { - if (flip) { - column += (output.length() - 1) * 6; - } - for (unsigned i = 0 ; i < output.length() ; i++) { - char c = output[i]; - if (!c) - break; + if (flip) { + column += (output.length() - 1) * 6; + } + for (unsigned i = 0 ; i < output.length() ; i++) { + char c = output[i]; + if (!c) + break; - draw_char(row, column, color, c, flip); - if (flip) { - column -= 6; - } else { - column += 6; - } - } + draw_char(row, column, color, c, flip); + if (flip) { + column -= 6; + } else { + column += 6; + } + } } void Screen::draw_start(void) { - for (int counter = 0; counter < (64*64); counter++) { - pixels_[counter] = background_color_; - } + for (int counter = 0; counter < (64*64); counter++) { + pixels_[counter] = background_color_; + } } void Screen::draw_end(void) { - ledscape_draw(leds_, pixels_); + ledscape_draw(leds_, pixels_); } void Screen::set_flip(bool do_flip) { - flip_ = do_flip; + flip_ = do_flip; } diff --git a/src/ledgames/sprite.cc b/src/ledgames/sprite.cc index b6b5b696..aaf91e31 100644 --- a/src/ledgames/sprite.cc +++ b/src/ledgames/sprite.cc @@ -5,6 +5,7 @@ sprite_t::sprite_t() : y_(0), dx_(0), dy_(0), + frame_(0), active_(true) { } @@ -35,16 +36,16 @@ void sprite_t::move_sprite(void) { y_ += dy_; } -void sprite_t::set_image(uint8_t width, uint8_t height, uint32_t *pixels) { - sprite_data_.resize(width * height); - sprite_data_.assign(pixels, pixels+(width * height)); +void sprite_t::set_image(uint8_t width, uint8_t height, uint32_t *pixels, uint8_t anim_frame) { + sprite_data_[anim_frame].resize(width * height); + sprite_data_[anim_frame].assign(pixels, pixels+(width * height)); width_ = width; height_ = height; } -void sprite_t::set_image(uint16_t x_offset, uint16_t y_offset, uint8_t width, uint8_t height, png_t *png_image) { - sprite_data_.resize(width * height); +void sprite_t::set_image(uint16_t x_offset, uint16_t y_offset, uint8_t width, uint8_t height, png_t *png_image, uint8_t anim_frame) { + sprite_data_[anim_frame].resize(width * height); width_ = width; height_ = height; @@ -52,7 +53,7 @@ void sprite_t::set_image(uint16_t x_offset, uint16_t y_offset, uint8_t width, ui for (uint8_t y = 0; y < height; y++) { png_byte* row = png_image->row(y + y_offset); for (uint8_t x = 0; x < width; x++) { - uint8_t *sprite_pixel = (uint8_t*)&(sprite_data_[x + (y * width)]); + uint8_t *sprite_pixel = (uint8_t*)&(sprite_data_[anim_frame][x + (y * width)]); uint8_t *png_pixel = (uint8_t*)&(row[(x + x_offset) * 4]); sprite_pixel[0] = png_pixel[2]; sprite_pixel[1] = png_pixel[1]; @@ -66,7 +67,7 @@ void sprite_t::draw_onto(Screen *screen) { for (uint8_t pixel_y = 0; pixel_y < height_; pixel_y++) { for (uint8_t pixel_x = 0; pixel_x < width_; pixel_x++) { - screen->drawpixel(pixel_x + x_, pixel_y + y_, sprite_data_[(pixel_y * width_) + pixel_x]); + screen->drawpixel(pixel_x + x_, pixel_y + y_, sprite_data_[frame_][(pixel_y * width_) + pixel_x]); } } } diff --git a/src/ledgames/sprite.hh b/src/ledgames/sprite.hh index c73bca54..bb9b6053 100644 --- a/src/ledgames/sprite.hh +++ b/src/ledgames/sprite.hh @@ -15,8 +15,8 @@ public: virtual void set_position(float x, float y); virtual void set_speed(float dx, float dy); virtual void move_sprite(void); - virtual void set_image(uint8_t width, uint8_t height, uint32_t *pixels); - virtual void set_image(uint16_t x_offset, uint16_t y_offset, uint8_t width, uint8_t height, png_t *png_image); + virtual void set_image(uint8_t width, uint8_t height, uint32_t *pixels, uint8_t anim_frame = 0); + virtual void set_image(uint16_t x_offset, uint16_t y_offset, uint8_t width, uint8_t height, png_t *png_image, uint8_t anim_frame = 0); virtual void draw_onto(Screen *screen); virtual void set_active(bool active); virtual bool is_active(void); @@ -29,8 +29,9 @@ public: uint8_t width_; uint8_t height_; + uint8_t frame_; bool active_; - std::vector sprite_data_; + std::vector sprite_data_[4]; }; From b81673bb159a9f710a4797316c2892a4e0f2b1bd Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Sun, 8 Mar 2015 22:03:54 -0700 Subject: [PATCH 316/332] Automatically build both required dtbo files --- .gitignore | 1 + Makefile | 1 + Makefile.common | 9 +++- dts/CAPE-BONE-OCTO-00A0.dtbo | Bin 1858 -> 0 bytes dts/Makefile | 3 ++ dts/gpio.dts | 95 +++++++++++++++++++++++++++++++++++ 6 files changed, 107 insertions(+), 2 deletions(-) delete mode 100644 dts/CAPE-BONE-OCTO-00A0.dtbo create mode 100644 dts/Makefile create mode 100644 dts/gpio.dts diff --git a/.gitignore b/.gitignore index 869ac7be..f9ec9be9 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ am335x/pasm/pasm *~ *~ bin/* +*.dtbo diff --git a/Makefile b/Makefile index 218e90ba..7ef3c475 100755 --- a/Makefile +++ b/Makefile @@ -3,6 +3,7 @@ # Top level Makefile. # Mostly just recurse into subdirectories. +SUBDIR-y += dts SUBDIR-y += src/ledscape SUBDIR-y += src/demos SUBDIR-y += src/perlin diff --git a/Makefile.common b/Makefile.common index 3e629717..83de3a50 100644 --- a/Makefile.common +++ b/Makefile.common @@ -144,6 +144,8 @@ clean: SLOT_FILE=/sys/devices/bone_capemgr.9/slots DTS=CAPE-BONE-OCTO DTB=/lib/firmware/$(DTS)-00A0.dtbo +GPIODTS=GPIO +GPIODTB=/lib/firmware/$(GPIODTS)-00A0.dtbo dts: LEDscape.dts @SLOT="`grep LEDSCAPE $(SLOT_FILE) | cut -d: -f1`"; \ @@ -156,11 +158,14 @@ dts: LEDscape.dts -firmware: $(DTB) - echo $(DTS) > $(SLOT_FILE) +firmware: $(DTB) $(GPIODTB) $(DTB): cape-bone-octo.dts FORCE dtc -O dtb -o $@ -b 0 -@ $< + +$(GPIODTB): gpio.dts FORCE + dtc -O dtb -o $@ -b 0 -@ $< + FORCE: ########### diff --git a/dts/CAPE-BONE-OCTO-00A0.dtbo b/dts/CAPE-BONE-OCTO-00A0.dtbo deleted file mode 100644 index 8c464516fa7c982d3f973653e5770eb51493b34b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1858 zcmZ{lziSjh6vt=%6-5Gy1j~qs3f^vRe;7BxBAyBIScScVz_a+Ad5yMod%kQ(p&azow(oXU$^g`l zLOb4Ssjd0Bo9g`a#rbkb;Miekr<=`d&ALxnfamdrDNWY}T7#@f)*^eE>?GMMWNowt z=?&5wq&G-!klrA@L3*RqPhphVL~Bv31+lgU5?cd>t%1PSbP#|A0ay~~kQ|;NIao*z z7LtRdNS#7;ip5E74JQRl{RZ{pq_$>KPLpz)l+&b~Cgn6K)}&aIVoi#*C>9I0wX$G~ zVl9fbDAt-3agwL0kjqJYFVOLm3uP&Bdw~qInR2yp{SQG?zrX(Q7snkZT9t|K_8kXY zp~PMoaJMVZ@_4+9acZ)+B@G)F2_mxK|Au(^1Pt-JhXhGK4=rW z&eX*I=Shr1%vv3z55(+RADkD?=#p3DF;7YFItKj@>-gq$<|aLvP2+yXAJ&DMr?o~O zrg>g#jJ+D3-;X-3KUhUM$0e9!y^i1SJ*Hs^I$7eYO|Gt5%VV7=h~3O<`%=VilBr=H zv|-=CeUy4pC}h#`^VD0FYM#R14ZWbKlBHevBYs diff --git a/dts/Makefile b/dts/Makefile new file mode 100644 index 00000000..f8abaf8a --- /dev/null +++ b/dts/Makefile @@ -0,0 +1,3 @@ +include ../Makefile.common + +all: firmware diff --git a/dts/gpio.dts b/dts/gpio.dts new file mode 100644 index 00000000..cd3899a8 --- /dev/null +++ b/dts/gpio.dts @@ -0,0 +1,95 @@ +/dts-v1/; +/plugin/; + +/{ + compatible = "ti,beaglebone", "ti,beaglebone-black"; + board-name = "CustomizeThis"; + part-number = "CustomizeThis"; + version = "00A0"; + + exclusive-use = + "P8.45" /* gpio2_6 */, + "P8.46" /* gpio2_7 */, + "P8.43" /* gpio2_8 */, + "P8.44" /* gpio2_9 */, + "P8.41" /* gpio2_10 */, + "P8.42" /* gpio2_11 */, + "P8.39" /* gpio2_12 */, + "P8.40" /* gpio2_13 */, + "P8.37" /* gpio2_14 */, + "P8.38" /* gpio2_15 */, + "P8.36" /* gpio2_16 */, + "P8.34" /* gpio2_17 */, + "P8.27" /* gpio2_22 */, + "P8.29" /* gpio2_23 */, + "P8.28" /* gpio2_24 */, + "P8.30" /* gpio2_25 */, + "P8.35" /* gpio0_8 */, + "P8.33" /* gpio0_9 */, + "P8.31" /* gpio0_10 */, + "P8.32" /* gpio0_11 */, + "gpio2_6", + "gpio2_7", + "gpio2_8", + "gpio2_9", + "gpio2_10", + "gpio2_11", + "gpio2_12", + "gpio2_13", + "gpio2_14", + "gpio2_15", + "gpio2_16", + "gpio2_17", + "gpio2_22", + "gpio2_23", + "gpio2_24", + "gpio2_25", + "gpio0_8", + "gpio0_9", + "gpio0_10", + "gpio0_11"; + + fragment@0 { + target = <&am33xx_pinmux>; + + __overlay__ { + pinctrl_generated: RNS_Generated_Pins { + pinctrl-single,pins = < + 0x0a0 0x37 /* P8_45 40 GPIO 70 in Mode: 7 */ + 0x0a4 0x37 /* P8_46 41 GPIO 71 in Mode: 7 */ + 0x0a8 0x37 /* P8_43 42 GPIO 72 in Mode: 7 */ + 0x0ac 0x37 /* P8_44 43 GPIO 73 in Mode: 7 */ + 0x0b0 0x37 /* P8_41 44 GPIO 74 in Mode: 7 */ + 0x0b4 0x37 /* P8_42 45 GPIO 75 in Mode: 7 */ + 0x0b8 0x37 /* P8_39 46 GPIO 76 in Mode: 7 */ + 0x0bc 0x37 /* P8_40 47 GPIO 77 in Mode: 7 */ + 0x0c0 0x37 /* P8_37 48 GPIO 78 in Mode: 7 */ + 0x0c4 0x37 /* P8_38 49 GPIO 79 in Mode: 7 */ + 0x0c8 0x37 /* P8_36 50 GPIO 80 in Mode: 7 */ + 0x0cc 0x37 /* P8_34 51 GPIO 81 in Mode: 7 */ + 0x0e0 0x37 /* P8_27 56 GPIO 86 in Mode: 7 */ + 0x0e4 0x37 /* P8_29 57 GPIO 87 in Mode: 7 */ + 0x0e8 0x37 /* P8_28 58 GPIO 88 in Mode: 7 */ + 0x0ec 0x37 /* P8_30 59 GPIO 89 in Mode: 7 */ + 0x0d0 0x37 /* P8_35 52 GPIO 8 in Mode: 7 */ + 0x0d4 0x37 /* P8_33 53 GPIO 9 in Mode: 7 */ + 0x0d8 0x37 /* P8_31 54 GPIO 10 in Mode: 7 */ + 0x0dc 0x37 /* P8_32 55 GPIO 11 in Mode: 7 */ + >; + }; + }; + }; + + fragment@1 { + target = <&ocp>; + __overlay__ { + test_helper: helper { + compatible = "bone-pinmux-helper"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_generated>; + status = "okay"; + }; + }; + }; +}; + From d55a82fe3e9650339bc0b1fafa994851fb16b83a Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Sun, 8 Mar 2015 22:06:33 -0700 Subject: [PATCH 317/332] Invaders game progress --- src/ledgames/invaders.cc | 15 +++++++++++++++ src/ledgames/sprite.cc | 8 ++++++++ src/ledgames/sprite.hh | 4 +++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/ledgames/invaders.cc b/src/ledgames/invaders.cc index e93f9e52..35d16225 100644 --- a/src/ledgames/invaders.cc +++ b/src/ledgames/invaders.cc @@ -116,8 +116,23 @@ void render_game(Screen *screen) { ship_sprite.draw_onto(screen); + bool change_direction = false; for (auto &invader_sprite : invader_sprites[current_player]) { invader_sprite.move_sprite(); + if (invader_sprite.is_active()) { + if ((invader_sprite.get_x_position() < 0) || (invader_sprite.get_x_position() > 50)) { + change_direction = true; + } + } + } + + if (change_direction) { + for (auto &invader_sprite : invader_sprites[current_player]) { + invader_sprite.set_speed(-0.05, 0); + } + } + + for (auto &invader_sprite : invader_sprites[current_player]) { invader_sprite.draw_onto(screen); } diff --git a/src/ledgames/sprite.cc b/src/ledgames/sprite.cc index aaf91e31..fdfdc115 100644 --- a/src/ledgames/sprite.cc +++ b/src/ledgames/sprite.cc @@ -84,3 +84,11 @@ bool sprite_t::test_collision(const sprite_t &other_sprite) { x_ > (other_visible_x + other_sprite.width_ - 1) || y_ > (other_visible_y + other_sprite.height_ - 1) ); } + +float sprite_t::get_x_position(void) { + return x_; +} + +float sprite_t::get_y_position(void) { + return y_; +} diff --git a/src/ledgames/sprite.hh b/src/ledgames/sprite.hh index bb9b6053..16ecb7cc 100644 --- a/src/ledgames/sprite.hh +++ b/src/ledgames/sprite.hh @@ -21,7 +21,9 @@ public: virtual void set_active(bool active); virtual bool is_active(void); virtual bool test_collision(const sprite_t &other_sprite); - + virtual float get_x_position(void); + virtual float get_y_position(void); + float x_; float y_; float dx_; From e570b29983e103bdbec428cea60763e7f8a9ac94 Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Sat, 14 Mar 2015 18:04:28 -0700 Subject: [PATCH 318/332] Updated .gitignore to ignore DS_Store files Added in acrylic cutting files --- .gitignore | 1 + acrylic/LedBasePlate-X5.cdr | Bin 0 -> 447578 bytes acrylic/LedBasePlate-X7.cdr | Bin 0 -> 457699 bytes acrylic/LedMount-X5.cdr | Bin 0 -> 20080 bytes acrylic/LedMount-X7.cdr | Bin 0 -> 22677 bytes 5 files changed, 1 insertion(+) create mode 100755 acrylic/LedBasePlate-X5.cdr create mode 100755 acrylic/LedBasePlate-X7.cdr create mode 100755 acrylic/LedMount-X5.cdr create mode 100755 acrylic/LedMount-X7.cdr diff --git a/.gitignore b/.gitignore index f9ec9be9..015a664f 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ am335x/pasm/pasm *~ bin/* *.dtbo +.DS_Store diff --git a/acrylic/LedBasePlate-X5.cdr b/acrylic/LedBasePlate-X5.cdr new file mode 100755 index 0000000000000000000000000000000000000000..71a41318f1456e1e808b5837f12ac3e9ba0e8358 GIT binary patch literal 447578 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%0D?^o)aKBg*`udT;u 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

=?1EK2G&ok5A@Nt*R7g%c{ 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

yln1|KS|2)ysa` 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

lZ=utzYlz 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

B_2U5Jij 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 Z&0BcPMI`&EuXNgxP{qW<(dsdWlC&cZ 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 ^kD(^?vJIHF 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

sQ!9AYPwOIT5Z;(wp%o)<5qR*vQ3S; zZ#z!Cl>aSgs{AmTJWH6SEEz@f){dv;TW8XmeJg0)v0YzkbTnU7ncChhvi84{1SKI_~+#V-!OIQ-)9i^DGtzc>tuLn=5F ztQk)$!J&Td3fic;>vMy)*7G`JyE|o;ftT{^lTM{N7j(tCSGR_Hw=@L#ch&fYo~rPS zIbZ6Yb~)E2u3O-A;&t1W^r6x*isXE_vi zB)QZ##dw^o4fE}<2n;%3;v0P>$20kAx<~q@e+rt$;gAjvMQg^&-&Xms_Xz=Gm3Cr8_p&C%X1j#dr;tMFn3f43E8<=AU#u!7uH%e~Q02 zWPn34IMi;LL0iG0LuL1;P7Up+UHXnUTTH^v)mUbBm)KOc-hXm;A z7Kb!&$XO&o%fX>>%k=NvyOw_(IJEoq+2cA7FKRho9n_EP?J~}3Xf&%TuC#2;EVk)M z$a6Ryk?nduAj9W3ue9*ry)u%1`=|JeLoPT}f>0f(yE`N9C;I0>!j_KULs^NU$ zyk10mw^3FlV(y%3izX%q63NMdcxJg@bj}F8?3fvS>7RmT$gw%(EfS|ytH;vT&C@;& z>|FNx!hu~+t{>I8eOul66yom2Uc-!{7L(GnTC=+73d^?O5}PjX0*8JVw257g?>X!2 z(DVNkEDq_4LbL!JYF3T?*0FioyVE^-n=F!65@2iWZKf^{d8w>e@W@<+&Y89^c-( z{qEyKT4(O7IW+&K6I6W4AThPmC^xdjv^1dJyxOzIs==w!w#BC0sl&X~qtm3sxBH)h zW`RQ{IFv3FqfM)%-}Y^q^5n{nMRysW76?bc*i<=yg6L9^v}X%;wCE*$ZtebwmagPY{<+)`d}<>{{N zgKze0G(9?QRd`d&EBT^+Soj&^c;7zLG`B8`Y=;i3e5*FQBC{69Qo|;<3cW_J%6|%) z0}gpJhts+RB5!(DO5VS+as1^6TNe(z+PS^+!#=h0XUELa?`k&Ev#-@35% z3vb^LFYI?yr+~}NJl-^md80|sd z*nbLIFp-B=Pv?8tJCFbB4JF}$C+p-|-fvl0LAP(pr+W@0emHg_3ixAt{^pMMHkJb~v^>lB__m*u$!9?c)o@^-C! z8QrLqMYpX@qI-6Pem{25`;*Rb=eH(WHm@!9EdI1JGFy0)R8`rL>h7`nZgSA{ ztK|`+FLp=uKRF%K{pfmJ=cA{Z)(4*x8t?tp)!zqc{8PN?96`=p6(Y@V#_^Za`I4D* z*@S4idWJvUq~u0-EwiIX*O*hCjYiaXiypPyrbBJFYf;A?8q{^CI`!Cff_m>hPW|^B zr-A<%rv?N`%L8GqQaWBRi_VpZrVC|#>59otbi+(bx?`RZJ-kqtYA)5JhRfBd`ARiv zz3LdXU#&`=)*Pj-YgMSn+9T9w-C^qYk3r)n45KkKg=jR!>a3N72cfR?Llq-9!%J`@@2Kg+dsyp!S_ z@OzAB?70yCi~+xp!XA&v@=ll7+IEMe#unR*)+XzMj%xFgla&^w?L!5d!;IlHZlO5M zTsejofkWl41+?nOCR(L=_Mpb??i?y;!USF#2M!4f#A)_Q8Cn7k)jJo^+QXY@t@@F7)doh7 zD=b}ai4(aA-KRi8h`%^0r>z_+gE?`}HE5$g^3FnY{_FANINKqO|3&5cg9GbQ((e?wIzH}Z_dDEqB`o~EluPcq_ zai=P*3r`k1)zoLZx0a>&bmzqf4Wvg$oK1{Kybu+VaWOO?=S*lo-oQ}7;*bCisY+tB z5FDyEOrkB@mA;=mu<=ums>-WAEz>`G4ZJV6nZ|OkONyOavU5GUk~91UqEkZ#Lz8082PS1)@QKbj;}ey8YN%jym_D3l zfJ5=}(X1OKOpOS8Se7 ze^^$~nShMwbKV*0=iQTX&bTM!o*F7>(s*8)2o9OxPznz98|1&8RG#<#)ZPs*&mTGR z=&G98wM$w)eWwiK8xZdnH(FI?RM|Jjl{%jcEAs61&-Xv&nHxUnl9P1SIVQm0#2i zPwzKOi8^VL=ih8z=2mZ2V_#$2U{&SVY*OLgW>DtWp<5PlQl~6t$e^j&890v~A|C``cIl_H56=z86OfYwxK$R)2a=v*Q^O|7%FHQIHXS#pyhLgzO*eJ`RvR(nOnCuPrLAV`+)y<;s={g47 zF!pl4Vjk#l(K^iPynUqES*IAIGp_M^r#ut22K;i!ccUMUDyx26e@zb_dW#4!0%K3aqHSU$VUeHrLbI%7Rc8+%~ovm-#xtrf`^fJEY z>T7V-(_i;@p8&1j0)x~qhlQND6h36oTv;AkJ&ETKo9K?{-l1)>#c#d(@Qf0o98wr=1(2WjUT&M89wr`(R<)+tMiASz2^NO2lad5 zPABd~3>ma=Ecb`Daa_M&7w77EI&FBvhvj36=-TONbkm|}x_xahJ*ezS)%QAnGdyJV z*<981qm7!;dq;KscdnYcZ#}iN-}vZgz7Eh;e-)yq_A)|W?Pa9FP(f=)aa|r1B0Wze zxa&Vm7b&7k$E46z3K4X}TwkiZ)Q#?6V@K6DSx|#*M$~MFKDF7cLml^MQP+K%)N{W& z^*M0jyZ^!C--8bw`xbFn^;_hSak*1~bYB!Cbsr>o3+Z&x6uLk5ATd74&*QisgwQAIU{c-BN;TUz>s7k#y9;LpURA|8F!!#5K+cH#i_VAP1 zYy4dKREjT^&JYQsb4Pj7MY6VZmAnbvJWYr0R#c}dbB2d+A>44+IPuG-4bt4Z|1}yiknBVa`h1AV+g{&Z4q)Ze)ehelDt!<)dl^=EyXAG zn@fg*UmSjM_{HIWDThc7htLILGyxnkHcX`XJ7&>>!z*Z>#&()zr1~z^#^_nRtHb?p zU!R-)!C_ZCBjYZ(#HXHhNX|NKlaW7Qm0Q$jUR>H^T2;|*RA1F()L1?g&?s;SpC(Ad z;a4XulcHJcC(@$rvuN?bm9+T8j_>&f$KPgKnLJ5#cD@ti8TflhK+FZ-u(UJo(YgIj z3B^5jsTG~p*)<&&h4pP_RgJYK)%BI8b=5-wi$erBM8c;{0f$_0C{dn8%MYxiWokRW zmFTIxF0e3rnC0MpGr=wNQiN~PnZTf&KCkf7PM6r~cKf8p7Msl0Cac1ZD$|maB^H%U zg_bpSLjjGJWpjuIhcs}=UpIl4ZJR}__OGN>$9I0K)IIU4)Xd^RzMbc_RF}x}v7YGz zA^t_3J|Wd@Zc)umjtM6l95TCV?F)N~EQ`8xt;<`pZL1rG0v3lzaEO^Vf~GGWMGL^8 zVw)msElBOLonLCS)n8VbSlutS_W3=_F=jB)ExRYeySzOhu(8=Us;$vGxwFP2tEbGR zpf}sLpf}yVtUcACvS}#zi$g3pWP(ExI8=c{JvcO|?)=!GrSWH-k@dX_OTR1m_VK4v zUGlr)ysBCwgPQ7sBik$eA^8pGibH&>KqfkW}y z@w9rYBC{6cTl3MK@0&F>UNjrp+^sS9zf@wIIFRjB(2?v}RUhNuR1qH5UKAA5o$H_6 zo9Ua=AMcho5aV9b8SP%)G8C{lL`@Z>@!*iXRFal}L+w`9T9B`;Dm&k{YiK-c*SEdX zXcl&AqBB!MCX>D!3yjEUG&#II%A&Fl!*%CvPC!ySOXNyS#NM;BXM2 z3Cw<&C6csk?KoNo4y}7ueC{~1^L3}X=Ho6s+Z!#$L8q%MlRFCS3u?1ms!Ec*nsVX- z+S8)KyA#6W`eH)U2f_mLP6hcFbp`pCwG9O{7966%A(7b+0}kcj&;Sk{yO)3LKD_f~ zubSqAULCtD?S{d9wdTpqrMCGMxlWb&=^l;gNq+4KaiQH&F)@8%QKo#RT|hXNW04l&@61`b7w#cA!DvESOaOnX1DbLpQK_HTdiyNbq@ zi|V#L1G)kACyf${n=EqEYi!Ho%AM;%i#=NW3j9xc-ez9p(`a4kQtMD}Tjknp zQQ_TcTprwRP!`*vU!L7=R8`SD6wm~4hzEz zlV)vB{ZK#?!69)9KP{XkNb47hyzW^w>W@pCCS1L@RcY|)&aK_g_aCc$qH2;chlb1%|v@h#D44k=S>jx9gllrkjHq%k}+Z89G%Qxy2r zwm|6d;7YNpx7Lk2^LVRL=c}Dt8ei{KDSmlWKjopOO~h?|ci*d~{w^0S!)(vlMw_2; zj5j*vnxxn7nWEL_m!{qml5xB{I!m=XaY&#k;E+9O7_FT#>}BtK{_EEk3ZHqnZbHYa zEeq;CZQoS-Vb6h#cSkj%pKBQhJT$a%yKClbf79B-@|uIM$?q-!hQE0P>0a^)(YhEI zrhXwT;`q6kDAjX`(L(`Em*J+xay%bf6?pDmoWgVF52XG9IYz~PyNnbl)EE7ONgwnl%rJLui>a?-i$=d5`r$o0hSaQEZ4VmwrD zCU_17G!q3v=2FaGCpSY z-csH4t-Y4vYZqO;S04I0FMSNO{tPhEcoAZJ;(3J0v1hSns!tQmhXPtOitEiuF>>yz z5NZE&0$Q?p$a|4=*#OnydAx(K>Bvu|b2{ZaP7oHmgzhEyt+$R#ob^?I;aWR-s|r z57X!!hiLqeaJrq3w4CK9I`o(d83u==!O~bi1Ms-9J}@o=`eY z^%tsA)5R*(YRM65zw|J5UUrDOEk8)TmLH(LEB4dCmHTMe%Dpsl)lksfHH?(~HjHFa zF`jrTFBnLtk8q)LM_JM(WAy2o2^w_kq@#3?!Xc_M?Eux7v6t%4+(S(jcT>w*yQuB# zozwwvp0k6x&Dl=9<|af$$&vrU_851)?-`nIw%}CreY5r_z)|3uv;&IvQ`h zi$>b1ehl`|eeD-${>&rN{*hC>+kLwfpF38W0k_QaLT;FrgkLkRjJj%6A9Ka9Bkq#^ zsf1J71BpM2UmSjM_+QDv9~``uL}?h}i#QI4)PoCXiuyX5V7!|~+aCK6>aO?7KhWZ- zXN2QJ=QxjhcFBIXtuljdSmcFWGcAt1YEl_<#i$|fvSCN!IsN{mex08O4U*-d{_rRL z=8Muu`1XlwWogE?sWfZ<0-B+=o~9b?`Ica%_AbiB=y`~r-9z6{_q%S<0XG~I!miq; z#ay<^Nw{cUlycs*BK@p!edeIi$(%0TlR0hrJ?TFS8Vn8r;1DoRgvKnEpebv{((J8M zY3{xSH22tgnx(hzYnp||>jWpWCsE$c_W}d`Zg@q6UvY_xyWo(Lde%BC>$F8d-hgRY zVV`kbNr!$@S(9N~L9KCT_RoR_!;cCChoHG4G!7inz#(^w0xjITfEKE5p!qucKWCe1 zy-c;Yd>H59ek;^3_;7WR6SlA{}Fk=B7v1t!{mX4~5Qk?iVyJ<2=cVo*@> z8Lx=kJ_HAyb}7{z*17fVR^^R#W|fWQrZsg%=8fg~maT<93l@hUa0o+ukq8c1;83_( zftEAtQI2f*TBdp6eTk9o^8#zTd+APozsGsToD1{M?Dq{V?(&GO>Tpe~YjMhJY;-7V zF1M;^&bO#)%(1Gk%(Q7K{#npa76*PBK3kY3gG0`$F|>FyXFbZ{4WFyj55B1|(0f*D z>2N2kfk)hW3r)-$&? zETFV5FubP1C$6E`Gp#w_J-;>ErK~LpJQ5shYvY_7%YGI#Yz&)26tf=&9P+`TeA8rF zw?pY`iSTxhRUA> zn*(B;7)2qPu~3W_fkXAiNwjJE{EzMX*S|cedhp>%O@phA`Yxv`%tG4=Y?5j+oN|kk zJW8`;{cBPp!y4m5<65GE)7ry>@;d_kN;(4ksu}|P>Z^VhG#ng4!66PDvKENZ5^$*9 z$XbW-zH8t57rjRh-s@I3xY(-a(o@u6| zqynen$Q+NVpiKXIpR}-M_mucn=ah_g$CT1``}oQxhuFI6p9PJOVRJ~HIh+TBzUiEn$i&3=Ai_v(9B4(_{f{+M1@zouhthkjr|qiI}fja6oJxkFKKv0H_Afp4vA zZb+j;PHc;9PFkx~PI0ScdR3!UN?rBOf<}Tv_+);XI#ZAqDT&a!<&qyyt{?yB>1~P+ zukKoT`89@53RGy_o;R%bFJ{Mwl52+vnq{lG%HPQ zGAS);GA^vHH_5H9`dQE@aEJhhj2Qy7Y`*aKre)%U3*!f!Z3qipKJv z1&x;Gq0y80X!dk|S~YL@$M$7nPtUBAzI|i!luLgoFCTcgXLs|xBbuc*)vPkEXnV$7 zFbEAeV;b+;Yng7{X_sr#?p&zf;#H#E99XX26j`CxlnfM=YqYi$|14+>IK;~hqXpCW zX#HG)m%Ypyh&2)y?`>4*f2zE^{n@Tvm5&ac$oWIfG~up}Q^<8AAFoU1p$=!Qqb*N6 zBpUU*rt0>1WoUK>WT|zA=csnZ=c=5{%2nws`)Sa)(cCm;A}=jf81}JkHs6D@N&=Ve ztdQ(`vT<7L>ut-cU+vtU|L4J@$c`>iYu+qTZ>U@PDPJ=l0Ch%_t3Zz;-z*y z(&yNHdd*&--c6Bq?rMJeK=?`#7#^S0%Xm9!(c)ezRPr;@kRZIo~%gO8T~a zedMLdg`Iu@w4K!DO5^ACLILhkSqj+nT zhiSHlALQ8mENI3kE?PT^Tp1K1{SPI$o8C+pD*v`zCX237h^HIphf?JgzI6WvSE{CL zNA-7`Q?va>-)s)+e{oXL`RuN$`O)XN`iDR@wfAA_$KOY5sJ=_kRC$}Gb@)xT_RoSA zi;>GG1xW9O;iU2HD4tR}LnMr>OsI@Efr zCUsO+r|#R;sQ1oeG+>u14c)CmBljGkaeEKZlzj(j=Ki0>?+wF9R}Vj_|6PC-(b2;) z=uDAlswCx4myUO#Yo=J!Ei;Yj?zy^DWq~HuUVMTYFFj5zm#b2{l`7PE)nV$f`VjS5 zbC3qEIY2|#?x#`f_R)m(duZxUqq}7osXaZ66xBdPKbce!GdT{z-s-}35>do3uP3G*QmUH(~yLo%4)4bi(ZT>FmrL>d!Dea&^3%1jU z1tK6F>M3&owl9^PXAd@PsBKGQ~9YQ z<_e!BBWcJQ85+4&o<<*-MI+Uh(lFzVG|+Ar_3=9L)gwgxgL91DTf1bFS5}#pFU<38 zpP7_6JTaiaYJ#o-r+|0f6M`NGt1@kkoB zTAD_KL+t)pG)8SHjWpayLu~g@KaZoIy@Isfxkeeja!9mzVUuC|)FRjMv1zgEL!%0h zKMd-;?(4Vu-qq{zzpXPEa9Q(m(4fYZfS&>NLY(Ce4sP>=Y2c!fG;)_t4ZR4__n})TaHw;?C zuj%(jUeXzi9?&`$*{yvslYK8iM#D2EKjLCOMk6dlpSSx|}BIY@u=H z2fsu*X}k^gF@E72V*AJ~+U>qWlJ9Nn3?>f~e$})z`igOF{3XM-r1ScHDSg^~DIL0} z<6893Mg9z^4>)*&gZCUE8ix2He&uMI3J#gOX3wU|e0)W7tyMtk+spXLvHF(zrLZ%=A?J&w%|e3Mk|e=$%rqq zHcX@i+h@^&L(9MColyRmZJ_cd-OAv3l8gQQNFSf;fx!`%Jfo5Zof5MLY%>dbtO|=e zEvrjg&6>)p4V%i!Oxp8{%(^r3E&7vw27hq~M2r&)4yntfXwHTSv`ATzmK<3ArASTr zU4fqJiyU*KhiMK@w_-g4E`|8To%Rk*?{SOG?Ql#fYPQQQZLldTueENdC^l=T$Tx2- z%C_pv%CzoF`590@aPS6)AjCLv^F?X;@=-K@{RCPH4(0ooe=I+y{Hjz(^+}9a z*Guuvp{K&V;=2NZGFrSM^Xgp_imRM5%gP)ID~s)Gs&cIAt1_&cOH*x6<|Nzqr2P#3 z;t;~@$pMGVWus`}y79Dp+stp(`+)~T)T=J^2ohzzS9qMWl?HkME9ozHboVqi92Gk!Me5UZxFlIl@JQ13` zOp+FZL)EsKU+VTQdsDBX{G?9f_?>bCvkUoV?!9TYp{?;Q@wE}&8D&91`2~JaCD~p{ z6=@z>)yeK9HSw;swNcIum65J(1re@YnLh*Sk2uR`G9L|}E=ZHXA$O@HEnPQ`)@+^e zv1#|Rm(53%A2z8Uzh13tex}IO{bZJPNPUu1e0hvVMnQN$er8a3Ns51bMZ8aXb&Pjm zZKQWiZHRk)RfuP6VX$Xs_RoOD!517N!66kK@|Q}`^0l(Ge(Uu2ZM&8}?>MyWeyiHC z%k?^DePzaOEqRt9RcQ|Kg$ZsMS<$}v$>AX-u^}-P5rL`Ip#k}|K><~Dem-^8e!eY5 ze!eGjeg-sv!yyVB(lJ&RE)}O$Yh}MSZkhJ>gRCvcERJ%uK)w)EN);dPi);NbZmpF%YbaCunFMB*SjHseJETTryX6F=`xbenhL*b| z$5lBbrPtUc7S&iM)YjO>HJ8}MbmaaFXb@uF0L0x1m^*Xl45yWgM|^EwE&Zl@)1)V7 zx6i+QY466t!6Pc|y(f&S+H{=q8jJ#xt1P0U%Is1Ci(Ilj^Sle3bAn3kvZ5=jGE=L} zGYhIsv+AqN(priwk~?yL1}qLi@_aNI913O&(war0AKF(*JwLT+;{7Yivwy$7dqdyF z!-pGBA2%%N)^^BfGw_RTG>ZtXwNCV^bjolp_sp{?4Ja}%jx04UPA)en&acoft}Qpn zZ!I#+Ihpe_puy7IG<4!Hnx?=W=nsy1jdfuTYO+vlftm2%T9a3x>+_TK;{qqd#A_{bClZv$K@`^Ra@4bhR5JEyagd`9k5D1;nd+)sqC`AMj6&0{xIX18$R#Yt5_5Y2}c`v?; z2RxVW#e1=SaJLt;_sr}yPGV~%uJ2qK{`AG7{{=`w9kSL*L-iJE=-4Iw_TnMgk$Z>b zuRYaXbK$k&{;pSM+D*@FZA!;5gv>_-R@?~1Uv!@(3b@OQ@wp{Pqz{WyNmrvY-G&l# zu!EU-n1P~vr-9mh$AQj#=fT13{{=`v+dm)OQ#Njt{CsAc;K0MwSKhWz@a0qoIJlx}cY?RyGKfTO|o?Yb9O|ESI?cc%9_=i9_={r?l2Le9_-uI%T4k z^U2C6=_AHA@*~kD_yfb;?>&dYejC7Kybkg9d>P3hK9BQtdzQj?eVP@387l~M8Y>TS zc+wbb_qhFk0bpQk9`Y};X8AXa}(>O+dm&#RR2q3eaSD~J()j^loNhhYDfHZ zHV*npwDSAObnyPc#n8V6;3!{02_92XM8d~-68=M~r|bJ{3TCo^>h!Lh?(nXjVfVI` z`M&_A3z7F7bCD~T=%3g~dgnx-Jd0cf^9>p-`|m8URk39B|iX0mGOI z95XTmSP~(`+6^LYaS&&Rg%o?t?<_~>U-?dsKg*o$f7D{^ejIoCUzlv1jSTh7Le31$ zMq1y_m#l_OvkT$Sq7+bG9R(VjgFt^556lm;z+Q<8ZbwN#QzHOd0}p;$SP0g^K)9|m z#OOIfqP_#98Q4RPp)C{{*+8YSHPoB@FI;VxM!NfCkmj4RNX74kQhBgtb`tDc5DtpV z{XuoDH|TDrg2@hdu-WYj*nJov9drWbAqU_n+JXOJTL@ONf$$?%5Tk4f2`Uzls$ve= zN6nz2JPxN$2Ax)R1kkSWI64|g=DiJo%7QxPWzHneM6O>nwKywWa4A(n>#U?v& z++q#*Z5BY(^>;?U8e`cb-LiW zUK?*={R)fb^daLIbYA1Dy(o6qHzQ}w> z9P*kV-0*&mA7MXn9p{X=Jo_vE&*A?j2lQUyw?h`V3UfesWC28~F9WgRI!LhI0dcrP z5JOjk2tNY|4YPotLPd$jE}SquMd`C%P&VSa1<_C5Sdy>_}eM>*-H$m+Vc;(q2^qh1>_{9Bo$X)zM=r#PK;6b;s zz`p?k)PaxgUjop5+@E(r;#HSIir!ktu-F0V7zIcnX+Q$o1Y(2ie@8^)zJ;WCehSQC zP5Ksd-uP7VUwJhIy{Y_u=!@zCW)FG{-9qp`Koi$KovK@-; z6rm8W{UeWR`8kv0`aUI?HW3%idmfP-@+3GbW`tjqe8;CUbC}tff0fZuI7mNV)aTh> z)I}M{ZKGXFYi8VvZ)Dt!`5O?7Hg6!>ykWcLAQ5exEVOY7wAVnX@ph=NQT$crs{N(d z)9QU58~-{pkU5?h7BCtmj=U9|l6;k)oq3sCoY&8;DeUuVDeh(Uly=h3m$uL^7B(`6 zvTD7CldHXN$Ndcuq7DMoA#&GjNI5VUa#4q3t<_Lzv<+&k6~0xwXn(Bmu%0Mk5yo?T zy&oh83x{JO#RH=F)bl~<*=P9q1zo)I;tozj*-4*{@@DV8idwG=B~|Q!+%nF!)DrH^ zguekH|Ht9ads=B|XXPs|f-=ojP-D3DSA(U(=Xz)DceU;|&nxKeqXj;k;q-ve%kd&{ zUsP=B>CohywxI077XRYXM!%YhI^WjH8sFZkQchoa5${q#f#21PJip=OzwwVl5bE&f z{iKZjbD;3ZLa5YS3H63sel%Mg`q=EK{rb3@&6666$L$ht?qIfGXkUs@+$D}oI}w?X z(-@jwR1=(ERuNcHSsKt(UF_dgo$J?ImF?eOloc?Pl^J+F^>08Z>JW_f=AU6>~XD}#kr8r3pt%35T8g2OKXS~=T=3g6qSl{ z$_s_1Rk^|SHCaI&wP}H8YEpwPl%xa?W+w};rTq;EUG-mwKkuXD?30Hwr3Fx@zT$VY z{^rl^W(VJN*=ap(ceVacvj=gYn!!0!%n51B2@p4?g``#`M(38qCKlyIWtL}#7geQ+ zs%w%(Cu-wEdr;1o#fb)T<3v}}{|1Oq2O;Y4=N*W=eR5ENUauR}m;XGWzv*L_>Hb%} zHkyyRT&%C3AQCUs(|k^qvxUtCezDbA!Ko#w5jnYu@kJSN>E+2W`Bm{zm9?=^&2>>x zJ#~?h=gOlZFXu%?Udj9$|2Twfk%44%O%&{vgQ~;x;JDhd@9laUCVNcxJwI=){@@J8 zYN(yy-rGcBpRD!@t}Efil;sOj^0GuZ>1nY=iODJDu?gt3#Fy8G#WmH1#&_3+i2Eu+ z#h3C!#Y0(t1Hw=T(PkM)MUO?%-q}#AI1gIYmVW8dUH|r+$)2Z|tW|HFbF#eHI724JW(3mXp<2!OOT*;F~^_{Wl;S zb%;XSKNFpg^4+uGxPttTQ^yv*Kd-&&`BkHB_lM0@1_tcSPM>qd9q%Tx%G+syxy@dY zDGk1fF*Sk=QDsS_dmke1a1f z)*O%;*ch74tB)!0s!b`O*W{H^YAVagHLVro+Vf?UipzP_vZ2hs0g-6?$FG%!f=$v; zw?pPv=K=bHJJC{%KY6~0aC|Vwz2R#5-+(C8;m`X?B^#xnd7ISK znLX0at{#%TGpe#+a9np|-xFiSlcUxK)pwj6^M-Mxq$?gikpnb=;G%ap_kv$6>s)Xm zr7tRtcs3~$-%^4GvYJm?n+rc098CXUsuuU&&OkKjY8fy|cHmC3u&j5!1nRqB57N6x3gKM>4fi&K z>GGz)%jtEwx5MiOw%x0CADdVG9P5|2{t9F*lz@i$$jx3k^tvBw(=LGh8s= z@?9OjmgDTd)VbMyIYF@b+)J?feA)ePKE}|Z3fMI#50sWA zf$I85(AgdY#`}3-eb@_Jj!}W6K?0VxJMi@IATYo}m=OlV#!irG>HxWB_E2JO3)L3Z zaNN=gPFYz(pY`9k*C>fx=#oJ?F3BME_h%!eutGWq_RL9uLyN;eWwk$OZS)4i?NqSb zLjjHAmyMTWFORrqCtqZ@`)mxm5$=wyHzQHZ{oJrV0hy|3+;uI{q~TNqmeTkuYB}0G3IyV6ChNY>~sl zp1Jm*xWE!r7a4=j5(6+^ssonGwZMM424GgG0e+<_c&t1MlvOIgT%`;?tB-)+Y9$b? zJ`AC26d`(z0>u9n@Ln$k4D>!hRg?oC<$2(*u^563S3!vNCJ4sw0s&J2`~#1IZ?qP0 zQuV<*-vn3{7C^7J25PGK8T-kyFr-5jkr%>pAuiVy!3d2dFSy6GwD7Pz+NW> zOw@sOP!9Nq=YmjmF@))@f+&kk5b3f9!YGG9$WsS_NFV$Y%)mF>27HPgz^fYbo7sf> zNoyngpmYF9(4N zb0O^5B8bvm39)9IAl7*gM3Iyr%tsT1!A2kuTY-Ou1Mmv5zkDj(zO(8*zA{=VpQ&B+ zPoC$QlOBWKuL(DN#_kve zL8{$eNODt#IEF4n`I-L+3v>J`OmO=gkm>o+w}>_AQ^k41YUIDBw+miS&I+HAheQwE z?}T5+KZv;O_DFc1Fc#25e8KG|zVw-i|2k}!1^?Z%(aY@|h*w?+DVi%F!)PO9+U$jN zoXYQHs^0fFuGLhO(B*?DhV(WlmG#Omm-pPKRPdBl8~T{m5;^L5I`$sva{RFS&4i2Y zcVf>HAB1<29tF3N$N4A8&wOVBcx$A9{pVTG&RGzRwqDYa1(2b!9C8ddLY~zg$Z=8m zmPywCl;UmkE-n!NDk6e59vsho#7_^p?~@;KlUXLdMypR4qO>IqQ2LTDdR|ZIA>B;u z@Vpz-N*NI~QJ)AJXixoT0(?;ipY1Xr+%XGc_sT;m+IrdQ%b~zv0~A~A`BCJoGL=U( zc$dYrdy(Yl{v=xHbuT0;a5x|_Y>1Z`bBSFTf1Xv9e3o%MwTIr7ewsdzev*1E?Ku5b zd>!L{WEJy~u#)*iFcbecaJI=nDB8U7XzOJho)7tI%b-|q{qJ(K-CxQbRVGUahA;DI z4v*7(NO$4_IaedX1eb*3@VcB-E!v4Giu}2QF(bg+cT?*y8>wZ+5?)q3`r!rB6GaM`Sbi9}C z<#{!k&*_g13F-}xjyNSu6rTvlOgipYm{!lN%BwRr512+$K~=K zgy--^LuUf`=)T@}s|-YLk%bg=UFM?Kh|*(Aph{=$*LstklZ`gY&+D*;qvak>*Yla= zi|IVhnFK*lM@)D`OITc7y)ZSoIxsiA+`lZl*smeCz_&9m-|uo>w%^r^O#aP;bpHLw zH2z4~O#I`(M>{VXbx1=U3J%SIierm^*Xpd9YBJt2al-1zSQEzJPBqbSu$WFho8#lt znHnHyi4Tpai;jt_2v15b4#~>M4=T>d4y?(`2t1je7I>i`C2%M!S#TpMQE)dpQScyQ zCcqzc2td0#7A0fXEOh%b2da)P`q8Mp`a`SH_Lm)&haa{&>krox9QwEz#xT5IzIr zk`Rb?o)~q=LeJ0AgYrCylV7u^xf#0_{Twrc6Snb zEb@2AK-K=)znhQD``D?m>}9Y1hKJ|P4qWT8(>d4XYTMrA;oeX~^C~N22jms{g{9>N z$0lS&CPk$uq>EBAvxAa~@&XcT3;2m0g?`DG^Zk>qru!${j`NSd6EhPKh&qJ+`Q9S* zSQMexs@i?CeweP5mrg~wiF2w8o?OvcdE<)F-V6OUS{-LF*7cnPd}*sEBfE*|msHCQiLMHW z3M~(f4=9OA;T5H1co*bmGYTqmX$7r$)WY+*jDl-v%$(bC%g(Q?7bvhobxHSZLOmeNM&#;^f3NhzTZd$Cj2>Nj;f~(Uj_Vexb%PFOMg6Xr^s_`yaSs4kK&QWzEjs1p zAJFa_!Z{ff$!v`fQ(6)diOpFlZpX_~am~lmu+3-FaLqT8@O5`%+-mMc&IAZihot3_ zP`p|Kj<1vWbY`Q(*!7JPHy-Ylz4SzNY4=0DZOwPhRLXDI8E0R0aZDH>5W_E07=h4ck20%*tz{dg!9Rfu$h2Rbo}(C z5>UBZ;#d0$P+GV@8uXj-$CeyU|KNn}@A@tB2?KmXAjHmbb@wmN%YrX95xzNI=i^oi)5***;6Ybwrl5F0zkgeaI@w9w*lVb7u8O8j?iy49JImk$Z zG&0yFi}YTag|y$7N9w<>l`i{wU|#muqbm}>YHo`7YOq`I)m(x1#qlWXi<>6(3su+S zE8CFp)!)SRYp5CKYmBAS*A#1qZ@D(M-^%T*zc<=jeLv-3@%^%+`HwM2vmY;KWV{?f zuCz)cJv}l=>lIm~=Jh;@BG@3C2?yrI!I5PmP+!Lfy{+D0wwnfa2S|WZB!H)~D|j8n zfUlYp1Zy}zq^2z-Xj?<3jujN?T0phFIkf1TLbrhlTr)I=2QzZL0YQ2?q>$$GQb^@3 z86@x50?9PkEE|J1cQ7a{=E1R*4A5Ce0^`kiu-=9N%uY1y_Mnlq4~?AzXmA{~gpfn# z5UpSeNrz1!OUVd|l?p_o-9-N<%-WCLD?v_N#2PKf~5h)}I7E4CL2AM$E zA~=#V8CFtJ(#bv2Kx;b;JVQiJT@BxeTyNmw;BL{n;rq6uXZAjRu z1sOXvpA57<2i3kvh? z;pieO&|YE+M$3%Aa)mxPtkePQDlH(a)&S4dYQS8hipJ7W@L#I}A?uDn^g1O-Tz?oc z*DFBL1_daak%}|u_*W1lW)wk$FiV093ni(rObQQcWgKDaY%AC+Zvu*Q^+9#MHfS$U z2g8NOz$SkaZ2@oQE?@}`0zF0vs2NAWvsfL-HCo`&tOLXj zJs_Ml0Jn>VfEzLb>`fDJ88!Xk{M77=(<`%2j_=GT9X^^**ngdo|7#rFQ3v9o*+5sC z1Kw&2fTO<*c$RCy*L4eU7`wqc;1DpQjsQJP6{v-pK&jFJa+5xIv>O8Pj4=@UO#nY= z2Cg^Ee_}^1zG0qPPC37_dhhhk`iz9t-tY!i{(R~9Ebs!y_4J^euz&*AA{B)Or zzr|Vzz-$FS${yhQDgrzFD6o<=fsv~Vv~okB)SH0kNi!gITLAIA6%Yn&e&L7hzPXOr ze{y;1Fo}8P_}XdG>ABOC^L3p$}|KK&1D>bsfOO8`xBF$MZ*JEyQ@97%N$gYCSD4qh zXU^~OPcTz14_v-E&IC}=y^9CxK;JhDxagibPvxY!Zc~J7?vuC=pH(zwe6c@#5AyyNo8 z?Yiq%mzns-fwWTwSbJsxf4@8kkIaWK&7}}wv=*Xlw?Vku0SIBJfWTiH_z}jxxk*+( z*x3%>SS6UR^cwtUO0)YX@+s0skMopC_iOZ5_z~uq>vPt9msiXi*msm6+((a#_%HaG z02=B*MjhB_-vpw~8>Tc5qBNF5tl=7nv)TqRt_L83dhAyyPw%@R#QY0iZ2yUqj(zWy z@BWTa?)ipVPk&85>Ggtm#^)JfkT>S`(C;?(DgO%YrOze&8|FE;NlK6VC*n*1eVr6| zqI-Jo4p|WHnGI2B^Tw$yfkgc^kZiFH5-|sVipi>9BiRNYLj~6F1W}j?-z4`J>@4ay zqsaR)rHVJ|(G+msy)*a@pFyh*ByAys!ZWSDLJmF{@(OR~G#hd8G3L?qwtxiA#}gdaUW>Ke&%k zF6yB*hM%T(M0Qg8quMCxvx4zvTK;ihZIOl`v^S&C-b_Z% zjVzUgkf*isN1^eSPsKI|-sEG|$1})gBMDxZ8&Q1HU}z}oLST$hnb{iC$mor&XAH+yF&;#eGam<+u*UrgyBLY193dkxyT@|?vM!Ic0s(Lg`XbU$jgtY^(l|3 zVmFG*y-&rJdJn`GvF}Fbvmb`$`aBKD=DhTo3Gn*!EC}s95lRBOCNlTWhQcHBf0b!0 z`&4DHaiY$A-&m!S+T9|8*-#eE`Fyeu>9jb2buvQa+Y}NLR2!5ms`Sr}EcGjiE#%e4 z=W*K-a<~@~vv{|~8NMT7X}(VcslLy-DZVeJ1$B@F-Uew1M@iZy13CLTns}^kN>xxhLJrqb<>o)f6lAt%-;XDho{z6$WQS|<9;*oj{_e)Kci8P^sQ)n?~#Qn1^G{n#}>Ulp|kpN zyUC85Ew)E5)?$sj%RC%g3+TkUEFWfBsz0wFAykkhjuxdvB}K(YWQ$|MN)jSP4as4m zu4GZzmE^FnyU`-i!%&gvsXq#TI)J@e@}Kt?V^NPx^!zBV~nql-~TmAgY@3C+DS&zn)0>Bq}T4Hl#%MT+9$6QZJGGsR)iMG3;F+GIgg zM{;1)K(ZkEPE1hLs3<7%X#k4Tc zVC&^hE9IURXT#Pyf_+T|g-~3~qG#vvxG7nJz_|3V(8v^VWN1>FSddVVz>lv^@{K#0 z%#FX8?3-{W)-P^E@FcaW|ItW)uLLxdR`RIP8db`x;mVGj>PAkbhx}dgj_?+IB z^QSG9I@_EK8js`c%4^APc@<1rS_y{}R}c^onHw4sk`)sXkdYF@OUsS-Nv%lqN^MPI zrkzjnPQMfDoiY-}P8tiG3E-gPi_rE?L0yVANJ9Nq$q((jrJwa3lD$8uv|#X}&ZaYG z%@4PBIp|fN#Mu-c_rPV;(J2YlY<6ThpD!#C2KyI9g>mx}qrLL7#q`{=cuH<_f@kj8 z1Zw`BSX%aoh@LSPI1|7{9U_)VLdHt8JJ(A5Xx=FCre~YvmStK(AjTx zsG-+Rr?d-emEGo!O=_W%qnf-}A@#mI|C*pcPE~javm!o%Ql1%2Dl3h3FKZIJmGz3< zEAB=UOGZOU1!Dm-0lq6GAqH*loaGWwy;9u%4{wKL?pO!#B#_=$LXH#5=dt*izuAw**+t3(=Y3zw| zX}TBgTK7nZs~qRg1O%YRAOUUv!X*eaEkWL$S%}=dITyL|aIM6-kpprachy(d-!R%+ zeAP-deZa|B+>f^tog?A=&oan9XM7m+?f@V1X^}7ClsEu;Dm}=#vsmcZ*%)Gfswc$0 z>#oqDeJsGK`8f}TI~@>$j-R#=fr@)&Lv4)%xq9y$S&4F~!2kUk(z|G}un1|!tI8WQVnKY}rr3{O^ z$C>8$&N9vJKVX>OnV?x*o%EauNSuSbER#mAx5^^tdt{NWKcB;RIbWjY?Pi&hw~F&K z->9yNpU~MF_S$%V;49lBoR?S)#!C-9&zB5i_ZM7q+zWv<=0${^!;1t5+m~6+)-Ovj z7B8Ey=C8W3X0L}`O<%oqH5vPeor!PRQpn9ZN#uN+G}6&0gES4#Mk+rqk|>zkDw{r~ zFh6$c*ox38?T!2?qaEH;R{Lq6Fo#K>h$?QM=xVN0TutXGfsW%;xSriqyn*%SOe4$B z#U|#T>r73*beNfZxoB?u^^v*Jmyal)rsZBKg7hDkMA}bDA@!G}kNp1l+7XKs43(f zGlmLPBRH;R0H@XUVNhKUo@wa8^Jy8VLy(S>5=h-y38d(nB$7Tp3rT>LQsJ;wHURd{ z@rJ_-DWJBD0D7xjz;vAh*lx51m(5l{+-eT=?WVxlVGIGgjL^-f0mSb4^Vts_DA=bB zmHV~e_BC7>@?1fS)HAYjD-^y0rC#4Gng>dHNkw`w<3&PZ_& zI{qL!{sRQze?bry$V(7mp(F;DN!h?UX;XAg3}EkUZBUd`gJbeXL2Hf@=+9LElX(Zh zYTkaZo4*&F=kEsGf}P;8U^~zjYyc zoulCJ=or{PQw6&THL!iJ_S0rc{j1G4^(pIL>L0CPTK?;>R|YT&vw)x^2PCz5;HkeD zD3&XLf?Wq>=4K!U?gT>gUcjdv09>I0xK=BH%W-AEbf^HP_ZT=2sDjfiHE?{W4i3*W z!2Y$yFS|+2Z?;pKpKZQreYE+dHE9DH(*drVq`(Pvz#g0h9*S~6IW`aIx{HBfu>u&F zbwHzS1yBAi@QBzC?#T*3$U6e~3KhUL90S*rYJlz50GErJfEm^X=Mf!n9M}Ej@JjES z{iNQM-IV@&yYKpM?SAV`*n!S;01kC+7I4=O2CX#1zL(W zc;@N@sm%B{vCixlq1EDtTbK2B+y&cjt~c$cT*e&UVO}}Cbo$^t?)=5!5$1>OeHXC& zj|-Sj2e_dQu792d?UDudpXVTdKA)tv5P}R=K(N&Y2y)#C{146Bexfr3BqH{2e*4JpIvTXzdK%a{bf6d z1MBGk!UidD+aZl!c4dHvcDLY=JcJ%w2w{3FAl!TdggNg7Az9&PfRE}|Ua;;IJKFRE zGsXHHHOJu%xy0oau?GLbt(o`?*F}Dcy-0oRa*sZOc}2g0og@$8rU)1D->~Q0emeCM ze%nt6xc_-3woMwm(DwJ=DGQ-!cSjsu0MREl{lk+`BiDlILZuQLn;M=@z;`+R=wY4)K~Ah^zgH^b93$8J47HSV+Oy8LlYEljPCDy75Bb)1*Nsq@M4tM)Dps9@Cvl``9di<$kxLe`_;Jn!ec9Pig&+3ZP5 zCi|nubo}Gsg^nNmr+d*gk&2$DxrgMw6&+nLS*pGAd4=(o(PFzp!#Oyui>aRGXX3n^ zI->jtEg~VMAt;Jf9gx5&^UL5DaSH?UIaR?q?ADMh_Sw)3pF5%H+;M&?_Z2&Z_l};- z`#_!!AfpcKHBu1r=R0E2Yi7ny87Md~`*WG{yooB!Wn;BQ8}C%u92_jbYV~E3%ugjV z9b3d)LVcuwQYi{!l?02q`GKkYZ2vq#x?j04#kVOmiPtSk@Vzcd;Ex5w^Ive{_-`0u z{(H)Ffah9C;GnH3TK(s{2mbsY5YoR(_RD^(QkwI!UVX{KMuYXk)z%04OE8+VIWJN$ z!HN`2Qm5k|2i~9NL`gxLH*cHNkMg}TlXZvXo;9m3yx*d?Zm8aJe_w^OMn@sRv?-h7 zP?hG5FHZFH%oPW-GNL0nNf8PBI8lZmI;1EhTv#g#6}E>7g_pxaLmvl)hCcHR4SDSq z67r5V9Y8@H_-J=Wq1~B=&P(AIsjt<$r6-Obn)RgZ=)7BPI%_XAS?uesaa3?`} z6(uCQf_#Q+W;TbMlHCLT!H`#rn+3r|P z9oDe8l4z4%O2Z}>vOQvR{pjIYLUwRQq_2N!VjwpqJJ>s^ER>maTtrXm6){srgskLo zzE|Qaws*oC#&iG+or6E!o3u;<3RXz`s9h~F(Y9XVQQszs;S2j_U+7g|+1X{hv$4%a zrMwxVpI1+?POYY3#N}S@;Uzq3aG}79pC8WUm!BjPP!Q_ZWi%PWT%Kardx0g$J4JefZb8VNu zQ{AvXruGE~TRFjUEqh0s4)8~hLEL-<3g#gX8fGKIr{s{qi*iW+?fJ;*Tic|YhmS0( zyrQ!)@3Pr}lzuz4=sv8Wu-Dznubb-V-Q|s=o$@1+I)oIr_GkvSEyc^}WC7d$WG%ehyJ50B_L_}y$Ph-GKR__?zC^L6UG#GFxZsP$pBK7e&PRJVoJ;YvJy$@r zI#)-tJl93HIDdm?dHxN>>dZ$E>(f(&>3~RiWHLt@xmhEPTs$d@boa_2ZCB-xrm;mx z)z~)a!Y4}e(jRH85|0{f3w>a9kblqVnD-sL4)wODG4U455_i+r*7=6e(f&pZ#^y$< ztL2R%y!nlKH`ANlZYH%&vdInhk!#Oa~-NA@@oUB+_zi* zqV2T&#o2B4J8-Yb@38$wzvB-WK-M8WDEaf*4n=J^byy1q4r{^~$~&d$I9G!pEiDLA ziS~ES0D>gmlSCq6fkZH@mEyrRSqAKr_kbhwT|r~96X-9q0rQoXV87Z7uxpLcO_(9j zH|POpqYel*YeU2qO-S6T4msOYp=|pxXxx4jI(MkRWt0ayr{hE;I({cQ{sjbyzlk8B z&m@olSSaBQD0d|=>xGz@)>WZV_ zy;2$cS1EyLl_JEgR)EYk2cdY)0jODf08Xsk4?WXTeF7c-EP}*cMG)aAg7|_A!hrb_ z?yyu618bygVXKTe?3rZ5c0co&SkOfDjS%6WK2N(VMfU#Tx&aNxKiMa+G z0yltt%x17n-v%~CJHWbX7g!zN4OZ=Yz_NEQSYF--7Pt3<#Z#0w2f*Uv0Wkl15X^rb z1T#4J6Xly39QZm7V7v9d4t57+!1?eja6Kjuc-{GcvsePIn3do{TMHQfP2d!{6&zA_ zfPMZhu&dYuwhjBh=Hz~`={^9~{RhE%_z+k=YzZ15^!@`33$pnaP{2`E@9ijIdK;_#nzVw$ z{|4A?kpioI(%`&L2Ji=G0r7}DkhSIm*<=Zj>{kJiv>phYEr1Kz3D~&3;F5U&oQn^E zQ}tnRY*GS;c4e^dRRQ~fqhNRM7}z~m1=~rrA2y%WKU@D$|6mR3?`%MI!Uj}cPXpMa z4mNwF0lP;Ai2G-O=V5uEY0L+@(GsB9t^x{S1CYJ90WoMdxJ4fTT&f~q^N)Z_xe8$F zkAc$(HE=ww0gnBe;BZ6xr~Ol%Z}x9>r|drKP1^qa^9)G)r9Egqvj??tdrOqjm4|7`Zs;it*CBN#k!0^Lz(&>C?D&3^+N zQ3vN8(m>oU4fH>s%Q-k3xJTy!Pj?CM%vS-=c@wZbcL9@o@E0xQ$aiwA+E-$l)@MSV z-X~m{(Fbgu>3f$}^LNgtt=>3YvU%-z&-S^)OZ%seQ+AJ?e_7tgfaxt4FuH~Xy{ppz zPN)NR>wo*-Yr72i?w<_-%5x!5docu>u7W`OO~3t!yT5U~6h5;8kA0v;Xul&T8cq;1 z&0e_`TD@?sv>SJ6bR2VT$2@lIbA9MIjJxOX40qf4BW4);(|!mCR+n&Kb{-GL=kQ?k zZ-DbANx-8XG_?P@Xm#z6{ZLw)G+-1+JVDgctd~fZCJ^`k8 znPE0JsBunL$?4cZk9_3awvr!UAX#2C#?iQfOBOLASm_u?9cWnN*1l{HD6U;WgignsE7VfTmKbWC= zgYRoL#1YzF^onvmM^D0?p=PBj4yCfV=4AB$JM z9!}N09OPqmjvr{(!wti9vc>q5tW=K{dah?9wTxEpS=+W?qzAgHIx<#ygWz!7OByGOAfc^j7Zz+F5oU?LX{1 z)?0dx*GG?RudldF@1IVY-oG6G4Zy9J1O_^O0NPuTX!9nb*Q|^^GE=#Va<2sm?P)ni8@`;46_p=u3b~Gz@;`I+^xb-Oe*1~QVV?Yn7Q8N-dSEvKIyE} zoK&xCoHU=;tW?eiati0OTN39xCW-UI`QHFMIxY+C-5``0bWTz>Oa98)CH=nW;H>9m zN9T=}>#n$7XtAR|%Sov_g`j;hj%wN%#kQ*!`MZ<}L);1l(WG4eBwD6#HZzr1!cOAU zapF0hTrp>W7w7xjJI-&CBKDhdkM;Y8jrIGE`8R-ocK4s&6Qa#4Mw>T%qvW@O?NV>b z_REY_ACbRPt+jlx)NK3NJcq*_8F;PZNuDM(VlUgWC|^uLSg>1mNCYV@D4v!Sn8Awk zFJ#B?Yq*hqCwbw1{k{}t3 zm-t+~MeMOsxXxM8fo`c0VWb3+ zm=+t7%8CrmXN!U=xk5p!Z;;@;Z&2_fj!^iPE);$w34_1jgu!23{|z9a>wt$gXE^GS zyg~x<)<}FP-zf2{VY}r0*8Q?q8r7Hf)fjK-D6>7(Sb){2%=R!YN~2q6C;2$1#{1(F zVnaM)qN1tc5y`BOupG8PRL=DeZT9sGJ?rZ$8sYkfzhU@?eIN&jzTg8yUvd8ic%tjT z4{gpr@7<>@Lw*;oMBdh{m3Y#!N#a)9ZkbChs!O^Xj5fDc*&M7b#i*AQxEtnXQ?1g{ zy`2(L{BY5U!5(4pk{c6aO|1Tq&R-%6JvuNsyiBONP{tDQTg&$S(0)X{9Pv9ZqTKt-jKYJRDk zL3*L5WkN2?Av%laDoPg+gHppO{Ny+WCo#j@E1}4T5ns=x#h>O;bOhm6Ob4N*MN{LXL|dFM!~e6H4~Uils3#(pc2=0ya6VmP1VIf zwPkH)yK`IYl~WqA+Oc&+ldx)|4gid6x)@^rC1_&w^w+F+ZP$&#(4&&F}EW z<_~$}3t!U-`5#E`IiKC!v%lc}4d9^j5HT0|o*|FiFPBBGAD@j3oSKbX=%0g}?%ycc zd|qKrRj<~nf^L%?X`Qx*#V0WuVXXv1!EuTuuhGlitKJtws|~`Fsw0Vnsw7X>%3PXr zWfk4AvYp{jImmFTdP%`lej>V*e#K!+zq$S!z@LYJSPprZCxr}G%OaOrXCY_1Ws$DI z*~p2ZwGy=h2jq$`sxQwxZ?q-;to4EL9;ai1F1#+UlWgME&a|SoaqT@$2r&582%Jkx zBEhjG$HT6wByXq457TjTJ(H#w(RZ}U7ZMv0r({3Mg7^~!Yov22*M%Tt( z^)Ya|8fa{HCEVQVN}`qdm0TOsE7i8fS32yBu3oh>y7C(R{i~J909cq@2J?U8c_M;b zFGP^OS_!1BRT8Q1kwQubWRcvv@<`hFYKi#qJ+k3XmF5MGX)fnHFOcH!pg#(F z({VQwLHa8Yq`e72>N+HllJk;C)^%AV@%20;=IsW_|BsNnj;cCq1HONqb7+tdP`bOj zI}e?Q?(XgeNeO8|kX8^C6&t(7c8q(}F~{y!tn1y}^E~VIW_Z{8$7dba=&WnA_ddw? z2Qw9~RapvN>2YPeGUrctdY~CI>vVMEl*!s;IBdb?GjjUecqRtKh%xnbMyaQnPFhKV?3N+qe zhU%|;l#;KK)SR!%EGb`gIAXq<@`TOV@(0YhEcco75%HW07I*s=BkBAtMVkICN7mt6 znY`WidIjt69ZFW;2b3*-Y*aD-u~*gf=UL)`s>zR!#Fs@Km;jg}doa8opzAb1!&TDY zPnjVfmr~MEj2e#$%n_)`7KnzNzG%tqfsTAG=+5tmeu8!wy37V+gsjLHAm*4WVv1#= z#^ehCL+lhcz#$2J+$5=sdx_JMI`}|J2cIlz>t=wF-DLi8fVxWn#kT>nezHRn@=+pD zm>PsKG+$I17oN9=2G#yl-X`&XB zDjF~=qA9aHS~1I@J&P1Nvq+#PizxcB3S$WCa*SaU#8ftZ%xB}nN_JlINst%2*m#!ihm<<^=oapPu zgWiGs=$Wt_J@Q4+y;>Yy+a%GYPa2)aWYBpN`FFR=q0>HjQfvxHKTq6NMEXh>K#CJL>&e2g}G3ZRzKv)0g83aR%1p^G&Fwlw<16+8J;m41@aYE>wBZ^*?66nz) zjqW|N=r$~mZW|QPb(`_9OBg*J z1wE!z(S4^Hx*t$Sw^JJEc106i|JFj+S6V+@KWl$;{iXfI6}3OPq2_xxRDbJ+s*CyW z8r+p>=%@V8bC3vaR*W*`#3%qlq2^-HRi27o ziZl#Tpkag(GsbGNVuCRTCfM>|yt^RA28m!)f)s}5$zy1x3I;W4{0ivS{^38M_nooc zV9s~5(N~|HCSSY{ntt+{HUHps)8eh?Q_Gj0AFQ5v{j_-MgQkyt(dcgm>fdLe?qbkQ zj*7l=Gz=wu6-zoVNu32#4LC5(iW^g11Tfi86cb{kf5m1heUBk=IX&>(i8*q{_>wnYlg#Sy%vEVt6qhaWL zIGlVIi9nl~2((%ZdP`F=jLc7*?=8vs|3@nmmT9tJr4i@%O6#Q`DqKWfmiWs)&W~2V zmzipGGd17pN@9h>#n=Xyv(arHrz3j3PlOLMj)qS99}d|bcrfHp(Ei{H!Fz%q1@8{~ z#Mm8$9y_Dac{&Ciw#K0CVvs@hAd<{aCB2nT)>209MztFAuR4A9PxThOuj=SRk5>4~ z+$js!xLS~CbRj$2YBsIJ@py8z>*0hZuLH52zBAGN{=1{r1?`BK3Ym`B8@4t4RM_V5 zyWyLn-UV)o{pB+mkM0xk=)6829TtQBWNr+ZpFz5}m~{6F8PeY>Omj^-tZ!OOmpo~) zTXtuqm-N-@5cP9qaYiQ!(yb5Ym)8 zqK`(7Mqi5>iG3A1lK9!hgItVsLVuF3Me z(}?qarw#x0Rqj&f8Uoc%tcW%|Sek6Lr!a@UJ-5VtDy!OOGQG)vJhd};G`T-)C~;lH zK*HAOzW4(%z3~@fdJ>;Tu1TE>>P6?lQ-N*AQd`5HX0|ql&L;BKt z!h2GOqqEhLX9-r1uKv+nel1izwx5 zmo()?pAzl~`Hia2%tBbSTSe53uzAVpuxVY4(zn~_dC$BlA zGp8%OEo&gUC38b;W5&+-hKv*O^%?i#R_1&RYs~u*urd$58}iV7F&IvIKaKQW@ltXQ z0;KtbC?9*pDNlxEskhguGF==t&};qP@4l>ba9(ax?j<~}m$Ai8^vm-3dbAieR{D2w67B!|AbOxLdJ z0`Jz!a{s3Cx{&(P)`;rj-sp;=(YVsWtqH}2hZ2hluP2t2yp1d?`xaDI`ioIkie8Js zXmSs-NOxC~?r!FTA3aOqW&H!09gO&BiOKWZnkeZWI;vNu3?v@^oIzcsDv9{E|wz?*`s;VWttYUR^QTcFOe%a=P+_D3S*=2tu=2gCqDyaGvTu}AP zudoum7K5?m9^{hlUO}{S!>2xOc)Fe&ZfxO!b6e!7M>pzo?HRWfo*HpiSija!d!RSW zbahvpU29vaOJhrpS8Y?VUuDCJ;F7w=@PgW|sGRD-*vu6h6Vg`9B&M#okeFWkB08&X zE+o75r(bprdM^eO$X%H4-r6Pbxq}Pt46(!Y4IJ>t^b$BVEkix9MVDjyM(gF1VzTs>_ zV&k*ul;*jR)TW>QsVmWYF_=v5LNO<~3movEhXt;WvcaWI>~MA`Cmh)&N!hbQn|*4l z<+8C&&NBTIJ{p~4!A4C(QC77BiS&xT4ELhme4pIzvVe@vx{#EP)`*1mzUY{?@z|)= zU2zd@vvE=FPoiQwzlOxO|MZV?qz8Nvf z^d3#tiJj*BgWKp*-BVtwEt7%zwc`;M73<>di$>C1a)xrf(g#WyN&Pi}aeXbJQEPf5 z!g|+7h4k)-4(dG>9lYjIM0nqq;D|N9{33hMdoh?r_Fx4w-0h%{_GNj=XirGM=vbKF==N~N=*e)#*u&6(vCjcPqv#tvjGl|Zd{%hd0C1i3|JgAb9NEkS zdw0=b`Y;o0JRtz1CzP1_jv8{e9kvy2IN&N*F~iU(+!JDuwJX{@bw`qI{Ps+G)V4y` zu&tGzL0cMq{kE+3^O+hA@SK_s^q4wHJPh!f`t0j7g`U2f&}}hT3UHV7|An=r|0k%h zcPkaP&QM|EI5P~NP!yk5}R zG-JOr`R3kdDy%$a8*N=@SKB+yjyXEcZl^n(IZZq!zy4zHcp7c#r_g3Gcbdr=^aC6i z2iQjXd;JVR|8W|0Tx5lnx4EF^t~jOat{QXR9YfCaJGT4@x7|dd{$fal-U?L+xD~77 zdoxwT^Jboo+sz7n=bMd&jyG2u+us~BwY{~&%;vAtW;VATncCd^Xkv5Ymx=A4XuOz9 z-2g|(9!zf{AOB7=pY(6r85-1GXN8Jqd{FpIikkIIjXC+50Y}U;OP;W2bb-KUUc!v0 zL1JFdqNLoPCCj=z%aNx)D^+xOR4Vc{!x!D=#x38?mp1ykQ^s)aw2Z;r z-!cYYKgbw-`LU?o>j5@Qk@xh8H{u7SIS)bX^C8r~<~ zENbIMfB|v_tw#W=&H?1!07!fY5Q*#%jC|mW!W4Iup*o=|lO5_XTcHVy8CtU%qa&LE zy0hz|FNZb;b827|ml`H>DP!&uMXcbK$7XIhT*D)a>v?5xJFhezAucUyaGIR|LGtmR zA@i>T#6JKCeg|YW3%DaU&{2S5gJM*3l%pD>Dor1Cn6%M|NdqmIRneAN37uHv(St=6 z{aB?jlvM&_*~BoNO&E*Vmt!6KGVEj*#6b=LoFuj{s$(BHe{u(MuaNoo0Ro-^xPJ#S z8^9Vlz!Z5Y1}I3;Mlp&y*$-t@qROK>RR(ovl4wK|Lvxx4+R&CGok)>ik4b5v?J)cOz33Hf^-`;ba3ND`(SRgP2@xC ze15d55k$+jWoXeSgcf5$XueSx&9{r7`3!MP1kKKgqS-Ct3GtTrDvIX#JM!mHcu`hl z4b~bobR?X$nb6gc1zoJz(Ak9(>47}x5YLBpxdLcgwG3@m388hbFj|j@pw$LZwAv<$ zmV3m|@-Q(gj+WPnN5mWAiv(K!BCq%lD-`=>g`$i3?;32?Xy~N&&$Ad0eHQezU_*B& zE_C(dLFbsINY4^P$8sTbXcR{KZc(%w6hpglakQP1K--;?Xmfx#DTOwdi3ieX^NRRH z{FMG_gVNt^QRbM(27lbZVDCdY>dZj!L8BMj3RNmPLmd;+Pz%TY0pdzBT6p@ZIr10eJ16pKtqNS69#B9V~{Z$2HA0;zXvZeLIlt!NeI32MbTr0 zB)YdqquXj(bRCpOmvIGjo>D~TUCO_l4yycgnpOEmzoGht{zUB~{k_^d`ggTAPN?$A z8I@i-qv8t}lz-v+Z)i)_@ZV<;vNQ~mr(u{HGe#J&VuUp(hPm=$u)iP%#tEZ;mIN}& zWPbTH$p7%_Q2OTCr!wa;s`kZwQscARwB|?G8Lbbl$93MjT-JT<@=))&^IN?qF5h$? zxuMoWcT|7ifvWdCQF$@wAW!yyw08h$yl~R~F)B7;@&~_W^|!v=TCcqabYFR`(|_T)+3=bBPU9!;hfE*4oiqE}^`7}%x7TKW zdCVE#@Iw9T-l%ic2eq#FqWTrazoD}%*#ikGhLG-zAq}3W$b>0cESPG-fhl%8Ka)HJ zzs84%eTYtwc@vSN^dhuO<7rU6?j!#;!@n85Cii@XEbe$uSpDU-&H9GtKAY>Fr){rz z{$+R3^QG-M@2{3;8E87|kA|lMQ14VA>YNNj?S;^deEj~RRE!WN^XLB?1acl(>dcs9 z$o4ban)`F6i@@8o0I}yuF>;S$(^T(87V7>LR%P^ONTb=6piaw60sS@?{73E1GB!EP zGIlzi@;&Ty!uOKXQJ=?7hy6a;9}GmR1HovvKLm~Ug`)nCZf@9A_lG2$D$cwx)3tR z+(EBW@3a*f)eymkvdS0*3dcV$!`+AkD@cGgJxs&-(>W8zF_4lRcnC(s} zvEH6o?XV@j$!Sw;r|X93evkE0>%7JyxA=@i>}L!`oM#L~JoX)k`QkPhkB)}`^mwg}8}{jo-N@*P+2h|Gb2^|i=6*m|!bi{U zWOQDgLO#Q$qBUW)5C)R&jw7v=MVhyiba%}%_}nB)dEO>Nx!b8qyV7RDIoss8{BWI* z%-*UHwdvAW{mq4`W)r!&Hlx|4jzbyMF8ygu?!75p-d)K9zU_$<{;i2S0$UP}1vVx8 z71W&a-e*-By0&JZa>6fFP z?loXP)M+cYYn6x8)XD(W@!Ck;;i?4F{_+g#)g}239ff5stMY3-8go~9*JtEm1ph`Db2hTQl9aWYe1C0g)oxbg>=%KrJV4o zo`ZBJ8~oYF0ar%2V0KiJa%f10byvR?|K`;$66-pAl?GOYYWFn87`N9aTQ=8Z+1IZq za;~nZbgw91>0MIV!6+zM8<1PPAvmjOPe^9bnUJiKrvbTTb6)us=t?*e4hvxnxd&P7 zq`leTQ4=%#+06=<2iW1lIu1C#UYs&BrpdBx$bxU8-${I^$49ZZGgzymHOi>DInkni zWrp2~`U0o2+H$v|>Uyudsy0SeWnVyg#duIk`Oc8!iqj#ZEj@4r^j;Ex^_I5*4+rzhCp&;}9MIib$HY0QjwY{*fxf325%XK$cp zOLv4peMh``Rco4UX-gixu&LBFXJw6NM*S+^l)7I3#M*U%akblnV{1+WRvK_KJie1v$R(K?>YW9w6S_lliuAZu=(rH3u)(hqfIBMzE_GAk^dJ))9w+@jMf!hQ04BF7(T2Ae za`kSqUEVg~Cf%@(p;9#(qEj*yZJa-lWRcaMX_vaDke<+6=^C@T(KDjE%O|vZgb~!W z)jzQ7h<`xW9lzl251yf`(KUQEI!1J(!$O!rgBO)#4@m!?SwkW1NrSzURM<96fyv!` zFuGfg+P71Wqhs1iVC5EPi4~iD6iYS+Y2-~r>Sv56m?p1Fw~8Olw~HDnr-uzUxCRY% zdiW0xdHD`b`S=VT_VFIP?adhc;O;+!&VfVd5IBhT3t=w6y;^{a9RSA%DKIlmfo-Jy zHtYfzKClG(4oFct_iM8@&Y1JA*i9EH+36{hyFEZ9eL7q#X=|K8?3Ps1h|Rf{A)Cr< z12)z=i0c{DJh2E2M_)inS>0Z+R^ZiZQ zZv$zsp?y?XeViTIPl!U}aW$qDM@_hjkJt(39C8;=JK!gmus>8KdS8rI_)Lmk(B2$l zzda>pKD+BIJ$AR-xb7OXbKbStfxhdo1AX^xd#7FRZJl?bwaZSlaM^+83q4o?aK4@N zKk4rs;{cOe$oxI?-vg&X(-~H%Jud*2=M|_$=k(dK&sy`OoN-dRI3I5}c04|4YJYsn%9$%3& ze)L+-`0sDB#t%?#F^2{KwyXyjCHHVOIfIo)0m{w+WM8L3;v;s5c_RSfZ>1=KZ&hi& zZ}piy-deD_ymR1ieCN((_s*Z&=3O|i<@@-h=I=8EOx_m@8hxl+X7Hg?NdM!Au*3peg0X8xsR z2B7=|nSU7|ip=+YL}tGLu>1vJi~xFMFEq(IRLMFNQG_Ck(iBOQr--2nMHn?H%TSLh zfF@Kvw4(B&1C<-ysa)tsWyc5_E2hwxuz*IxS{fDGXcSya4F3xns8i8cgNha!G_=wo zjF`~Engz{V+0Z121C0{6&>)W+^;htq-YQtqV4Ro|K!cscegV`!A&B~yhbocbHr^SG=4^W5JHphLO)D!`8Q(D1ebmNhu}hJtV%`e`Jag)oRw+lqRE7= z#w_S!&xUj_PIL(4M!OU~v?=6A>l#6{TD2UldW6t&h!__}izyMb*hL%^MT^s-XntMn zm-%C{?-uXGzFK?}`(%M)A1qMhy(J32`-jj%Xs$#>dpYWV``caqpJy@N1}x}h&4wOs zT<99agU<0wk)9)njup%Qc^=d$igx{CXgenU%XXv0Pn&7UA2u^m-)xRc&DmU%{%rj~ z`n}C-nKw3bGOuh<>V+*zKDR~jXLcy|)DA@#LMwSH(xs{BLHgT=y!w;92-Ic901Gzs zbK*j81}}O=3!q2(@?UPnBHvwV#pj$?Nq%wak^W2{l=9q~T?%g<4k^B| zKdbc8{*Llf`Fp$aq% z*J8qO6IKkh=fogS-k$+sf?pX)!k>Kd#NT^WNWbw|Dfh~)L*a$%8s%p$BdSlFH>f>w z+NSZ4zEAT3{gn1S`VH;B=+CwPbo#7u)df}ma7E=yZm4k49px{$qwGTHC`mz25eoVX zk^UyV8%@q6j+{pvIgc1?j&D(}JRidY1>c0kioOWUkb2@*EdS8ATKT?Lv-%y+F0H>j z*6Q4FU#ENBZL|Irx7`MpU5^@GbiHhJ&h@d;tlLNZQy!>&!V5Kyd!yL~{$quG00ua`iv_ z>$NU2T6NF)_86S;88SNMJ#KQsYpdxo&wXY`JZH@hdEPbO@AcMn#^;COUIyy!@khE`)CLdqA2qf;3;k{P(`aN&m`Izh`UE-e()JKFhRS@*vGq;8tRY*p=8gxeHMl zDzo85nkPf5bdLqEG&mgCZhRnMjp;tW5sN*Hjh4F@JFR#49<`bFy=t?S@!WdKf6i780`#eHk%IVve**5)_QZ$dfSbGTkJLj?zbNgIOi}H z@W^2-__Nh$7@CfTqv2=->W)UD_Cn}G&LEV`pKtFB(*F6&;CqP}<#o9nrLIyuM2h!a0?VUr`QoIyCRW668)e>;0 zPLXoC+K}~hxdY$fVlUCXdBL(fvSL-Yq^D|6rsNuoCzY6tCRAGt#Wh*4jp?*o6TQ}P zb=0_1SLC!yN8}OLw#YwS+oIn%w#WXoZjVQ^jzl!-NJ9OE(4Ta7H0ixG(%$*=-}B{x zw>5n5cf&Hc-Y82sTd&V@wAz+;rouyHdvT!b=KLs?iJTQ2Ylyw<-Vp!Nd1c~v+s0(HXi7zsrZn=m&H@-nKK5AB zdznNLC%miTf~O5j;C2f)TwEnZIoYhka-hMQXJ@sW@KlAL%y>z-%1A-H*4o^3gWl{s zldjBC%l7mdo0ilThsKm{r~0HJmztzaZYvUJJSr2f ztJPDKqTi99ZL%u2*rF-B%BDW6(V-@z)2S+bz_mPWgL_HpZja*BSi>oeED$^WCVWz{M6OINikp$JVgGzW!yf zy(q%8u*XAzX+2XIz(ipDZP#>pTU7KoDQJrI6TvcqHUr}wJQ{GI^C|&K6 zS~BXMRI=40q2!2Xe93Lkq_PiAsTF9OR*9DBm1wpQ#*n*^1#rI{;7S99+yNRK>tTWe z15B`Mh##hg6shah8nCZjW6R&Y+D&X#2Scu*EmXC-B}TivDcP`SWtM4PeW6uWZIxYG zO`~JdiZ18)s$sX7swt1CszV-;RX06is^2@s)u3%cEm|hkqS-flvZJTqJC~`hDpY% ze2bLka+`#v28Y;{9Zr!AgDznWo7_Sh4!DOjTz3mw`Ia8h_{%n`5iO&e&}<=00(e{m zaEO{Osvh!^DjNt?Ea;C=&t4O+ zlirhNnADwX7S~m38P!>58{XdL5Zu1jDX?v$vwzz@7r(YEF8=Lr9D~|_+JtnVMQ8__ zE`(_S_sYl~koG;^1u(M~VB09^f6_j~Q=HJZMV!((rNPv+$&{;R(m}9n!d zSg13XBCKENoHe~7sO%xgWjju5AS>IyrxxUZJZQTZImvu8XF6%GbxU73+ z>9+2Nnfn+TdyJvsLJ!F~TxvaAiySa1|yqDf0F)d*++%?1507W0eMQveqENl zeU?koXPg9*_IQcJ?hcfU*cBlcvNK*eU`M)|@Ad*MukBU3Zqv;M&eLm*=-Vbt9H#f0 z*iT_5TeTOU`Y;WOPcDIi zlM;}9QiGOy!h|jUxIK5&F?asZV}3$`N5jM!N8+Ttj-<)CAI?{DIb5kqKh&gde`t-S z?V$;6>q9fz)`$Plwm$e;%lg1iP3!%rL8vcuVI{z!9&!hU0M<_c^lb%b-2+f_2%zW` z6Qo~chvdtG5Pw;L5`9^ZDeRIJTi_*UF2+S4UayP60`3>1g4cKtKI zkTh`m1ty5O&JJOB_#pU>6!_m!r~2GAVe-6d$Kra|o!#lKKbOPZa30&c34GRfGx;s< zmI#{NZCGw{uUpvY-Z~M(d%Hyp?w=PixcgE>|IVC<-fa}s`|IEKk~5eb0~pu{(7uz* zKlso5)QhBnuhSslJ{vHe^Mlt5DR6tCN^yFjPqlw(!DRE&k=gR42dnw30CtmC5gbOZ zlDG_B=Pc2EUBRvMx`jvU&01cKH=Fs?-ySCJ@Tt9i$EWu47oXY-@S8=fYsz|Z?szo)OGol*JS<&>rIWp;f^I+Ec z?$508J)A}LM-5ehzWS{@ThR^XoXLG~VNs{`sCm>c@|N86oe( zE^-I!_Wi%}!*2k1-vyvQ1+YanutZ)kMPV>RY0yJuiWX{7)X|Wtf)-Row4=(S3rz-n zXi^wL6UR6vQOsfz#tP=;xQclh4zdX178U_KOk8K-$7lbtdJ91P47qvbf5~L8RB?OwhIet2C$-992=_Su%mJ%2P!plqS9(&kXX-! zikpcY#6IFUae)h!?vUSmMtmT?6Uc$ezfoF*7MX3JLPcZ3RD+5pdNedLV?qNb7S#1) zMeS&I)Xd~S^)gOWU&)1Pokafyj#2UZ^??ppm4zio}8w`@@4h7Ah+X@kobLMurM(n;sK z3sL_2GXQ?FR16^J;ZM$kVZ(~vZk%(TLEN9*;+MX2&06-_xm4%{y;k&@<0|nd4yz>} z*$+tlZMRj))l3Mcn7Oo#R})STsWkQ2vSe+JKUMil>J?^K}&p7~;T-76*k za$PBN!=+vBn)4ckD^9~omz_2!U!+f~oTu+sJxiZeJ59fSn%&#JC*&l~{ao-CG6}TCY zAad0&OX8AmvCKK|YK1eNO-iRcI#o`%_o*FoAJsVGwn_7l>n^PWu1B@^xn9xP0k}7pPC{ON4K$+4(zgpFOj24Z(KHXZoya#l4c(2!;_S&ky)oZ`O zl;>H)O`d-nPI`aT-QbHF6Mm>V;g3p${6gr)59mjFFPyY@Jn7#Qe)ygt3~w@JC=WB$ zsJAjqm@lW$xn>i51&+mriyn+hke&(8RM-_-sIon{QhjSsgVt0)o9;&cUi}Sz!-nI2 z8;#a6cA1PaPM8ieZkrDJy)_&R_@y%#gc<|Es5%gWN(-SU*@HmRd(lKPSw{vhe9Ga6 zr+Ff9J71o1InRLUbe0|0ku*<%eaXS1yW(S{x5cI^ZjQ=Tos1~a91pM784GRF8wu$& z91LD-yf$dP>6*Z8<~@OjELI0zvFHkVY1$R~UB5dFwY$Sny*mO`7D8`w1|g*P;@APx zIN);*7rZIphWo`!;cAH#oGI32I+AbAIg{hYzat|+bSfoMdP7p8;`;bZ)sff&&B2%o z-TtV0gWkwiqwert)6TFF^R}?fma9VdSv7~Aw{8l1YS|n)XVe^px-BuNMX0sJ{x4+A zp9AUcL>Bm%#R3lsSm0I(JKQMeg7cN)aJ*cLwy(sJV@H9@(#^RHk%`PO>Cv<}g~60G z)xM-$&7Oo(-LCj*gZ9`a<5e+TW=+w977bC8R&|lPZE7NCZK|UlTGzyUF|Cb5{knM6 zu1i3Tx2Q=|rKo z@JL>;)Y|N5h2D&0)vmNG&9>A+-InA^gT}-Lllp{qvzqvR%c{6>>x#G?wq`LP9 z+m;v{m+1Kn-a^6^_<^3{A&qssI0@NY2e}~~z_>ux}Cm-Na zC26jD3LI{x!QM6+On30X#tvD^Xqzree~ZAzOUg5} z3(E5Kb4n_VGK(9`(uz7PlM4rI5(+lj#TD$ck14opA6NL=DxvtNNm4NyB$uGhLKq3~ zoZN*Qq&v@50~{m$y|0Y|JGv;aX*D;jTP;l)=+UfZje0ruJS_j>c|>r8S)% z!sTuLl0~b+m)W58^qOD8%NcyG7qm=V;NF2VI5Sn+a|E)oJ~;8 zbIXw0?xXf-=3)z(^jY(v8u{2q@~#;u({XVzj?i-Z}ToI zpXRexzRl0f{hGfS`!}P0U<>LH+P{01O3s12A5N1!I6(S)2kGBQGJkj&VD)+?Xd4%V zrg24T&3b*7@-eF=g(J=a*+bqUX@h~1iEAU|V*BHjBKy+S!q((#1@%@L9du z*sFV;sYmw?GxzRU;;D&8_nd)OH|lzKqt-%?$vIrA_-7CHbOUTA{W(hJ_mT!~*-ZLp ziVs#y$xuo+Ycu6hNQ1Wf zaJQbz@R)(q@D2m|@M%N(&=Y;9p*bDrLDX^?L=8gycee`xW@`cVx0C)~L+-#3KtGw^ zwu$uTG(hRDB~Z9a9CCN5QPX!Cvn1`X<&53#$`>*1yDVf|ut>nxXbHxaWNEK0+4AmF zrAjWF>s9ERyVUJBk80R$-mYo8`Lw3ZrYD-V8|T#RHlnKCBq}d-ne4%lX43!U3^ojs z{$5A=m&~u9pHCVr^B@bP9TJ43Lkg6*L%OucgO;qJ2kD%F2fTO~2Lk!M_D3vt-=84j zvM*DdzOPu)ex^>wW~NilYGy>iVrIL7`OInJse<{QIeGKlC}+M4WfwYCPwpXkA8eYx z17iT)8v$05`Q>{7vJX)p;UqIeoZ*JBGvW|@MvdZs#)#&7#+KRhj4PYlEQ8Z|Hk8|O zHjdA3HeJAaws4u{=^7!k(;Xrvr$ z2QW4Y&@&0pMCMnJ`8kIH5>5exo@WN1D;(hQpQYgTrwq9KsRd4dno%A8bfDSY@L;mO z5x`=3Ba+SRMly%VjXW;H8&%x;H(Po1ZVvJ4+}y^eed`pT_RS}JT7Q0Cs&yUtHLw2L z_W3(N?%r+ghSWt|g zI8qItc+&Kq1~Tb9jbhe%n#!W_tdLdhSsk0|^KN$K=i?ko&u2IkUtH%5EMBvN*?T@P{vZklALK#rqXuYy zG^A*JvZSbea-=AK_Mj?$_NU5!iKNMXNuf!9En<@V+Q1|+w}x44ZX>hkx5LaL-|jGr z%)Mt8`SO!l_%r^Gf%*5q7JwCGelD3Ge-90Gqo2MvnmWzq0~KM$o`zpo)^9 zOqyRF)j<~ZKnhJM5@<^iMHh-N`cRf(C{+NHs7tYc%7^t-UR*6y( zrU0tR{m+}9e~!$*2H^S^faQHM`!Rs}M*tP1f&y}qnS5mCau7#x5Jp*8hRPs-ny?i0 zffvnz8|^7v=uY9l017L{QkXG^LcXX1C16Gkppvx!Sqq>e;Z1}Q zjO=zg<$b?G1 z%%~8_jB@ELC{x0UGIc~7D@ykg!)z!$PD~LyiT%V$^3N|556GW;MSLNUY;#J#*uE$s+h^j_{|D5WpH2GTM4E!8vV<}fP4%c~Y{i5IZp^3` z#Ddy!tf-aEh8pGUsL{ZI8tojY-ph&V!^Ai-MeO84^@Ci$)MvTAtKZ=Is{WMoqsB+h zcN)Jq-)JD`YvL90QUf^_LVYsdRDyz*;*|eB2e45f$az?q(a?g&3J!!!;w zDC9)_YObGp%}ajhbuIa(*UvqtJIeh;A#>TK5spbG`RG zPxOBBJkmp+hkD5UK>xp%++P5V=jV%1(3bSK19^2Kd*MXRgHF!F-i{eNI! zBIj50oF$|bxIdWI^Sm={<$Yt)!}rQ$aOq3q_59C`r}&>4?-F=od_>@}@dd#L#(xXm zF@7g_%jAc^pC-tE%@mhjA^tE$K7#jmXf8_TF9W0t0J<)xpvU~rWRN@Jp-V+KOQ!G6 z&McoC{n_6+#BjZ`OXq%OTgdmsW(EI4>qdbGRvpXkS@tczYdIox+hS7qmc@3FKP?W3 zT(>wQ`iI3`(F+!DM9*4&7n!v}p;K14{G>Gsp0GxN;|riQX?;i1{H~d*@}(^1{QL{jpmZ*L{~n-rG(&{5R;O%dR=p3jJZm<(DZk9Z4yG!b%?J?;SwpXN&*glg!X!k{Ozdef2IH2fWM-<-Uh(g5j-=Q6u>q6#x zk?!=Le-1(RBvbxftiKcj@;ZL~Bzj#8uCi7=sE4WqN35B6PhDj=Nym|x=Z zL%vy}`@M@K_Ig!G@A6zJyThYRe%ifPajV;i(v;gql})a@R3}}Jt4+AxQd{r#MrF+7 zr^1*g%8q)W)TlQ~jCiB?@6egFzc*?BAkzL3q&;J~;Zr;xJWUXS+wpSnN1Q(OOpG1t zu}IG)2f~8+_lCp>?F>p4+ZK>3HRWF_yNOXPzrnXjY22q%Wu5n0wNdZ&>cd{!GzYy7 zYOVFUtkviBTyu@jHZ>Ze$M_r1wIZ;d=}#yh&t-XUSY}KZO^r zq)NbSiZ=CVk`?Q|c-JL6WBmEIMn(v43QrWD2+fpU7g8WM5>%l$6j-OSHlS6l&%Z~b z*Kb6to3Tl!ld)H~gKP)&h%Z?PMB~yvM{2Ss!g~wuI#fPI(rPoI0$gc@6QR)d> zq1qMNsNNpjsnr@hpwk>Qq1PC=Q-5XPNrU>p`v&zPAGPX3QMDlql^ViPo{;?=dXX~- z0{BFF>mKRO|76nOQVt88&t-?>dCOsco(g40jtTQrrUTb_n%B~iI7hPGm-c7) z3-zRii+3i+OSdMa$u}qDDy@t!RjrGy(Ws7T(XNbMtydm3Vo(yb#i%IipmAZ;HRHnQ zH+n^}zch>EP_-l;l?a93A%jNlBEa8C0M|(GoGYNfiDDWYE@g(jWlLdOnLK5(RG(?I z$eLqqzANAA9LDnYtWdF*j2NkvX~}YRDOpO@$wjJ_NmUwUiH+LD@m+ca@k0iAahr^C z;`SS7$6Yqbj(=s4llW6BHwo49lF8qG$*A}{^auDH4RDuysc|`%G#}}{Bjr@sS3!dv zmAtU2N|v&&Qio}v%#yvQ*qOJz&}Uh5Ua)9GPLxzlR-#;GW`<%}dcJCLTDe9+YQ1)D zO1oZm@_=DR(xh=((q5C)qzfjg$uA7kQ-5e@q@j9d8meTbqtfp%5a2~DIfo3=y#)Zr zNq_IJqQI_d3QW~-!+5O}4Ap4S)>N6ZbyWO6jGYHmR973WzcYPcW|*N4y@M1*!9r0$ zDbjlf>Am+}MVbgAD4+s@A{K1euwgH;#%T19#@JhoCAQez_rvms}Pw%I7u~^dCN7F1S`!eid3&GNYF0LOV=;T%`?o;DVva!T{|f=t7URpX4kaj zjI|bt8N-$d8K*51GJl_zl=a>;C7X;-%^`-!xUrBhoD1mQmvYegum%UwzjvYg4Waw2 zYv9Am`Kr*>FoCwD&WgRT#zD|9*Hd<0WuRh3dAM3hX`EJJNvd9MQI26&VafRPf_W2D z@|(>P^OjAG%N;O}$=zWQm3z`MD))hTO#VC5xO_4pzJM4d6cB^4kO-U$cs`s*|36lN zHK;-No{!#z4!o*a0=k=(prhG{*0R8yHGjSxZ(g07bVZH7xOiTeYX009&78_)-HeJX zgVgdO)(R_ z`oAXn))QmDdSc*TPsWYqehQ8Q&c(x{HNg6B#Qat5=zi#c%{>5hD}+$JLIcWIn9vHl zt=KtT4!rc`?xLin{_=61VM2xM$(o@{vULL&myYvmt2Od&ZJprJ+B?y$b@L?G z*29xr7TuiWw&?YE_eI3eqlJt^^u}@>&xey`SOXk`t(d>21IGXzxNQYMEqZwQ01t`> zlp$}xkjfmG#z?V}SU$8bN-?N6QPponriOP6NeY%qCx3E&)XCQibqc##G2Ib6Vi8Sxnzut{ksnUrG1jP=U+N7~$-lDKhpu z^5kdjs1n=kXjYoBqf5nV#|9P49S2n{cHB_0*!D`rVk=Rx7$V9RTmH!*ycTS4!!f|| z@525sLIQAPqeM9TfB70uU52nM>K=!O7 z5nS6NiIOvpWb>_#luMZ(SsO3&HfM7h)KbFQhX~FBG#UUa03xxX{TRe{mhx_~L#ES z`GaDSzy85Ood1=WpFNs?67zooaQX$n>NkLiw=w%Zfcl>RDg;20a6z63K$gg0o+3yQ zHQ*B+kR(RHC8oe4RzN5AfD3g5Z-xXffTRBy5Wz`DRv|di2o{-K{s(h+jP3yf#E#}; z-)H{{V0jZ@!aV@(-vN}K0LXm;kj6F$2@U(m#Y{eMh!7aq7K(`Rebf*g#0W9_wh!Wr z1i+WSpdol6CU_$xc=D6A$k0C^x<(WkXFw4HWSlWYv`s0ZWn-t97WC{H;_MQMEWn}GeZ8~jOH7mYa1g*qwO%Eh?Y5x zXxP(;st=tgN6?8ll};3j7(`(n(u}k-hr%4$hxO2RKiS zPILY+y1{v1{FHOo_&w*gG2z}st{W51D8Ky+GDQi9CA#(u^luvlAT!kwoENr}DKZ1c z!_uAp(L99tc4{2!)s!su^T{QgXJ+%bPt2OQf0!qyqa=_#ChR{7l9Ruz&rE$ex|S+wwfwdfFBG4GMOY(60T z*?g1eg88uMy!jF7bLJPNPnkcIK4I}j`ltmF9kwLGLzYD9pd}F;_!ndb=FUR*cI1EE zhw#8Qd8)%F4+H9z+hppo(@fg^*&d9W4xy}H?c=$ZXJzs(%q$Z8XggPU)^@(=l+7ZU zlQv6bPgwWL9kX65f5du7;gIz{g@e|o#Us|Y#e1w@C=A;W`5m@IcDpT+**24i5aC#e zE#^A%FdzNj8{0AZJcgebUixXl?>^(HTV7VwRZnO71$Te;8P`b3ADoi~$DDFRhi8|_ z9B{0b8*yk<*z3?H-fh23aoBF9(hj>phBy zFh)Y$IKx4KylnxIqRoCuvKxG}6xMkcDy{LVRO$DuQ(Nh|P@~tQQ?tjtPrJ)~P-mI@ zF5RVWKj^i)-PT*;@mg!KCsAMQMN}4h6D34E7UDcw1Aq@f0QbTHev78VO_C8|JUK``ZTNM>7S`iT?w|q{bxHBwMc}YltT3c|1 zW=l|=c5~oD-35V5^&0|K8Po-AHmvbKU^Fk_l5ut5GlS}&&pOq?L}OkEQA1S5LOduK zb?BaJj|NapFah zsmjd}xoQi-OEeqiRO{4+Ezp}6x@25cNUvc<$OhxGkiFweLw=l468hMvH0+~Z=^Ua} z7EaU=)v=6@!)tW!Tj>86F#lvauJto17|Eo=&P*X}%F=?hnWnV9bQ@Mzs*7Ytvahf; zF;uoWK3d!um!w=Dlc`n{U8p%Xs#2#ivO%vbqSc@zyxXWSeBJo`@Ldz~!q1rGhW|c3 zFY>*9eiYFzh$b3{+E_;as$+B3b43p9MxPogh08e@4jIu}OA z0q4Q~VyppXZ$$s>uR-^&p~K=DS!k}+r5fg$(W|Si+2vJEl0_9>!o2c8*{rf~ae7Id za!PTkT4GVIR$O73ZgfH2xQP5V!?64n#vyr|CIsgloDh`v+l1i!mxiJFL@%s>Xd@b9 zc@zn73CH0W)?g31=Md(vtw--d4_}PS(5Cq!sBhGS>iH9C?^Akpyl?3X1OHN@ z8&FEL0!xX;SnkCF{D^b$5Y}L4HP!&LS1myIZN_|b@!A#vR4r14vKC{iaG^OPr+F49 zy~&lAyueqOFh4{#rXflpvOZCHPF<#2NNtg3KuxudU(G^2?|EJ0Jm;-9bf32m`H!J{ z^>cmCYNF#+O|%g8v0TS-IEm-NJ{*Is*#EUn0NsnwJ<)?}+5yTtB%!E75%N05QCS^R z=&9{Cti&Zw60wWD_)%?vqB*VMav_W2#eps9%6;>q-6bEv>|E5L@KVwiV@Z0z@F3XE)mk@#}8Z{Ch}VrBkR2^MZsffuA*yag^E*Wqnbm< zQVqL~wVJa!_Gr!QxTrO={h7wBC7;!1Eg`CQi;2ou&WzTe3g-dVe*p8BccA~HiqxP7 z7oi#@ql?F_5kSmZ6^LAGM9o<{l@`3lmJzVVndLj+&Gi}x=DDwq6u7KT63y<0}hN-9YVah2pn0$H$ zn4O*tlTLe66HkXy6VAlZjL&4z49`^14bHSM^w0D$^v-T)=$<{t&^`T>p>y&hOZx}H z);{r1*5Ul?!TeUtuNed=#J;EO0*JtDpTn4snmpqaz~mnpVDvK=^sY#O?iEGQy{Zd3 zS0{q@uU3cyXkGIH&EG;nm#zw3ke z(L|7cWC3!2*n#Y050HKw0-`4gAbeVY%m=}<9uWMw4fuba1>UpAzY?EIAbbkX-y#*kCOau8hk|6s=1fsVJAbhI^f_J*We>WZ^ z-%kPV2OD62Z~?~0K%jq$2ioTXfKQDGo@5_!a6kTpJV8DppZ-fD=9i7`fsFt}V&8qv z0@z;wn1*gh zMi}_JT!fDZ5m`hD(L@Z8$%rlD@$FdJFOnh>X*9wuLgpdO6ydfb-N-6r9kPWYoMB`?@&j@ixsN!M$dqK)lPHKvGo3Pt2*VOzYgEpuo@kc{LbmB@Ug6IL##hS2_${l6iG==#Pg z2>P~>Dh?;sV{|`A*9ynS3CG8eMpUC{L>b3JsQ{@$uog;K3#FyBPf9CjAC(4ZACxxG z-YIRTy;T~a{iXB+?WNMMv}a0>XpfcO(0*4Yw1>)s{y>G$?<4m{QT`h;9;yd#(C0k^+O{%3AB&e+4OhXrSvyiHT2h7P4t&qOXx4Omec># zT1kJVwT}KoYl!|>Yd8Io)-n1+txNQ~+P~9pYX8N!u1y%f>JY{iW$mKDRNtioX z8pu@i?P)SVEJpWabn)v+6fv7YeVXJ#y`2z1do@0q{-<#o{fSWl{gF{6lm|N@1I9uog26;hohq>V>&I^?0f`?ZK2V`kl!M^qXecjNi;km{(1! zS(i;4SwEY$u`f(o#yLN!k8^I)I_{ZCTe+tv?UOh;>6FBA(_4~kL_^8dN?S;8+&bdI@1L1+f1i!TDwqJX9UtNPLF2%XqC!3 zW0}W3X<5cSVNoM-%wmD$5%a~oL*~o*2hCUU_nU7J>@(jfwa5I3)Nb?t2zQtOXh4_0 zKNfDa_#m~#k_a|i68G!v*I}iW@Sk1n^_>a$F_pM%cfSa)23Ot-Fk^=t97^Z7V80-&DL9F zH(HO#4qBg;TW5V=ZouY^OusFjLAFG=(w0aef|WD>hS-euA1_xf0B<~K@Yst5k31#e zj++oJyQ#rh_la=a-G(~o=Em6T8ps-Uj^b{2O5zR8&Jt{LED~;TtQ4(xsFzu5-y%C; z-znd3*Qc=3ZcyB7H>|kA?u25u-A$$C_AeEdIuN-|Md_!+@IKPzgdj}v3a+lRf;D@cm>hz0hi}N$(g)X1P3tfqPvn!Epb|cbb z`Eq-41^6BFuLl8K3hsJea>QEK0N>G*PA@BtyP7IA1(3s9b4oV4X@uV2gTLz;ex!fHhi0 z0Xwt{0#4}U2i(=k4}7Cu5JZ#MpUxq5G6#6D17JB=v+kizKF|>6PP=K?zuA! z*V=eolOhSdsfw^X)sR|}GL6=fWXEhwbmP{=`|+ydLWPwv(K2PxNpi(enc~8zLZ!UO zD%G5bM)l0_cCGaAl{%^6TXa*x59uX^U)M{Hc%_*VNmNs!h;nKaQAEVwdF>5w8{PXy ztih2KbpH(WohP8&(Y-qH(VKMRq7UfBMqky7jd`IJ7faOQV~KJ?EKy8| zBjWG;IeI>hjsw=<0Os$^0oa7guK}bxhY9UDval#u2O4usX|>tbjH=ApoU#m0$)dDC zL4InuC?_RWHZwU@AuTyaDJ7{?B{8v9Jw9QPR!l;VPE`B`-N^V6y@-U%$aAg8M4}dz zNK~Q|i4vmtoyT}STp1k)tie89a&5z9==vgnKBS|7f|f!NG!|+?ZJ`NORba&^&2wNE z=DJJdX8Q}Wvcg2^nK7~{8OidA=~;^L>BTBBY4g+~Qx|H6r*>(FrL5NtN!hCxoO)3& zB=wngXev<;OCu_C(ufkG_??F#02ktM9Iytv@^K!Z{|=O64Uk3Xf%8kHpr%X>s>;Sw zrKJ}1f?_*XPLV4&v(T59S`Z>k%8!zX&r6h#$;}W)}xm-3G)uH{4tQFJRO;_qBaz;VDD?8Lfn!2Ffy z;GL)?O-%r$NM17oG8RfhT8kzmwM?Mm7Fy7vn`be?n_bzVO+FGq3xat8jZsp*jfv7; z^Rr~#8%h*h8tN3C>X#@x)~`~vuivg}SAR;?uI`bFeeDM&`&uG)s3i&xHGgw9?dyKv z5Y~SUsz_He)&M=cwhi5H3A!KpaD0aVVmg%}s?z|%JEu?~9oF=~j@eBAc2BlXdjQvS zNjT4KalF7~afWbqTak=?TaDbT);0y()|F!G)@_P2T2Cs@SoFJiM$3Bz>xD!fksHe~ ztidpj!3OMqA3AtDW;db-S1bj{K^KihJqqjPLU6Av1omlxf1e5X^jT0|eReeWURQ=o zuP@W7H-zo5B8F?XB3071CtqOQQ!TXWStPRP?v*z0-YPS#=LeZ--4CUwE`KjQbs3SK zx|E2fjbT5Y2SYgSt1*B1Vt|%ToCla)(2M@vkN&v^{SVd1eNX_dgG%5ss1HtqX5ctD zgR&oVq-G6z&};_-=+=V~Osl~}mc{xU&b0NF+{x<~N}8@;!JD*x3vc536TFG*9`H=o zyyu$?5WdOkf3g$jz!&YnV1X8>S9>QIm&5DAVCs+Qi`u`h?+9hVgJC({Q+pX)wHrHE!22=D6Ye zO#L12*m~OtTW>4jjAiraJ{abApb9qjjy?wjkcA!`w*?>=UDSOTVAfs$^ZgW<9OlCK zBhp}eL=B9N7=YnXGcY(h1I8Vj4f@BtLGM@?=pIi5?c@2B*6~_O<9H{feteKpJ8_6o zJARi^J^GfWa+uIn4t;^~oz;uKJqy(bP=$5R*#wY)*&(Q-9_Yfe4r2Zh026d#z0(X( zJ1+ssKZ!u;f)XfR&;{{D6T}h}ezphspS?g17a_8jQb6W%DMk{5V0et{?c3q0vx;6#795y3Zpbr1Oq`S4%rFuw@r zT=E_~2M=TZNdQ~SHoFKg?iT>H->~nu0Hp2$NIV2!z679uq5wW}06y>$5h9OYt08*G zM1W7z0X{n;cr*Gu`Z*MA2f=m_oa6*MN$`!y-TzX8`KdVP<{Sm^Jd63*Z__I{_SXTF zZ)4xFe7r}P{RFVh2pP-wy$}H+jflVPgN!~8G7WJ=g1$YIQi^ z=AFoXpF9VtTQB8^BZMI@FYE3j^>kwFA&A+Z-eNgRg{5(TT3CTsU7Q$NUldzfkC|p9l z7cQsX3Hzuw!nM?2!p+nx;V`@u9){<_^YBD?4<3qMzaH}Q?jX0nacd030A1fu z28e+)5Pdw3!+PlBywEno_SgVXb;CImM153@rQRy0Q-6sIsh8p^>bbaqdM0k6o{BrD z$KoF9k+`4wUA%#MAl^>h7aySRiqBFv74J~jl%7++D1D~=tW0PZke`tA|ALIi>i5N5q_HNL!C97L!C5BpdB~Mq#rdc zWE?WBWE?Q9W9~Oy$l7Px&e}7nhrMgk0DE}S7S0aSeVlEkXShSA_qZF)UULV{2zR|1 z;jA?y>`~T?flOn6-QKkZct4YZ=QCOG+=dVLr%S`Hmg;ccY7(59ZVN}JyHf|J2hsLf zMbUR#B{O$gX0x_i7PGfnRB^Ug)N?mmv`B0;@01uc?~`0-zMi+%d?$av{20IA{JNme z;yHhXCE@j063K2$BGF|@xMLw!v@iK@?D6)24t~Rlf~$@!xMC{_XJ;wGF?%D}Z*K*= z?VYF{cE0qXSz(M#v*K8TGgH~?Y;(B-wj~n%Hr0}=Z07U(tlI=Dth=PTtyc?|TMvnr zSsxH}TK_EFZu3O6*yf{Dn=KKv+7e#tOgyv4@a6G3JM><>ykGY~??nGR>p_Q8&Kx-G zEDL*G^k9eURM_llM;mnUps#TbWcE8nvioKyaC;mxB)S~)dCMHi1f32wQtkH5!o~I- z(yexVGA(u+WEa})k!!L$E7xfMP;S1%d+7#8B18oBj)Xs!(XH(l*#A42{WE&sX@7vD zegFr(7_i$@1Y5ndV1u_Qtns#?t@LuC_jvj;mwSY9I^AO=mbfMJ+FY~vi(HDNnq4YI z3!EFI=R3E`);o2{)jF+}uW{O;Q0;U=T;+6ET;=jcuF{1_SGp1*B83RPGg^bkuIQYY ze-3XiNAXrSg6s;UV8~AZ>jTtab-)Bz5nx3v_jjas_<1qge1kYGJ`oa4-toLfuQWlu zXRff;vs8MXM~%!}k7l___oWKu?)~CY_pOS>?nji0+;1oqdc0C7^dz!~bfFg!B2wS^ zgtxW_ScA*xoj>3${{Z^$FfxR%*9Y^UKST+7LJeVQs5!Mb#E#w)?8aOWo0W6C4=QJQ|EiMZ^FlGpm&j%L z5t(d1B0_}UdFh1XfHgQDiZzHF-G4#vMK(kM^oMhyJ3;|EBlMvyVhYt9ZcCp($AwuN z=EJTI4VI`3iR6_9CkRS{(uIXVdD8iT<+8Z}^$OVmZQ_i86-w#;8==0(kBR7HBS%OV1}#o==#3+BY~^TJYuIbk`{nV}`J>7g|WsUaGUAgsDuT!%GSLx4`a6%j@qECsKZ-Tjjk#OUf7fK9 zZ{Tq;E`OSmg;1BG2GuFXP@ZB=D^8w8&rfn;iLvRT_}Bv3 z*qAE$sF(%fi0DqGIne_uq0u{4L!!?hk5ocqK8nL)h&&=YCx*y;=RTf`KSq4r3)_jg z8?td8@={EH2G$&?ysuw#YHBcfcC7c(Z94ClP zN)<&V<;g@OR>+4X&KHLyv?~QA^s59UY*+P9IE6e^4oLVQ4oo2Ofr&&mD1pd)=N6ui zr*RIBV4t^Q{^St5@((U99Mvx=PtQb(@M;>JKWOsSoh=d$D&ak@HC< zvWU!guHiVGNcg%Jwi)wRqkndle%*tai)|?`Vnbe$EMymJLwd0Zl~QC$ODwXZ#}>LW zqY8XD5e2~#Vfm4~;Jiesz}!rcUv9CCPfo48XHJ{gJ-biQEqh4GCHpvXPsug=oq}67 zkwawMvx)R~e#Z0hFxFrP)_)N5SE7S=Q~@kNip$ZvDrk^iA%c`jHAt*9hPcXURCJ{+ zJ)**i5mxTS3N8=i1eS$M`jy7>y-U-jJWC2iZY9;SF2#%For+f|I2LafI}{%k+ZW#z zI~2W@cPt{Zj)g>eb|Ddc=WHB~1J1#rBAko3{O&>rZmk8VMGBA&Nn{4dr;$#7MZ#OXWGw%a?Mjt`gZ-FO->8-7RZ7caxk= z^dxwqwPs@}-hR1s<0N+Lpp-#Lyo7{)Q!FuD&_gEeTt8Z_cOKo`zIACFsz?y-;y zAuX~H)S?Lii^hX*i#g@pGLz=f;!JmI@nX0v3}Vh+7|C{MPU6mL&XKfjs^D8UHAzix z>JnNuZ4g;B9TJ&0-4dEN{v|Y@Poyjwz99I{0i1_h%diI6->&&M4=}fO5spI}KpHAZ zL9b(Z1E*KC76!Zzq79D@~qGrAA88uOQ7-&@+z zztO|663n&#GDX_}i~(ls^_y2eJrP~Y%3>l?p4i-diz z>%uX>?6frik(leh8NeBR+L5AFongBL+=|8tPrM<}_ygp%DuXy55;9sN8S!2BM7 zvVMS!^#IYB9e}wmm}`wbZZ?AXsLPt@#fm4GAahz0L}#QCWe}dx1*x+pAUJD@I0FBy z5Ae@L0`FWVNS><(iE|ymJ+}ck=Z+%}fphi)a8Hwe(24m?m|w9PAPdzz7L_<~H|Arm zHRhTg0T_22K>ZYe0(!aVC-m^kOyFGM0qcr1Fs~{D9#Gs4fFR6vISer47{H{H0D5Nt zRL=v*{tO_v0>J$ZfPM?T{|+1B1KdUDzo&=`Vl7+@q4WPf72uE2#o6e?q1cWmc;Y`@ zfb;=8!@@qpPCWYq;LpGQ%RC(WJgj{J{y6vmfGhTSI`-KFo2+vIK1){cn*hu^ znEe3x;~P(y_}-HEK0<)!asV&Y0AA_iBHaw&9WGSg<4ySk-i$tuK9hnMoKLF&KJP@Z zbL7T@!rF%%0&v6Z=|2KYz&>kT#oAv75Z=bV-^aY)k;llN$Y0-hgS{Zbkcp!c&3fdKk0%tSnp zFeDMlMaq#nWFgXybRjE|wa6x92Qq@3KrSN>;4{2LK7ZNk_=tS?9}p!CY`Pk@1rg$F z30)wJiTINlh$|9=#3GqUF;a~*e%p)bM0${ZWIZy3S-bIlkHC94k0rW;rFxDf`v|Y_ zr=z_59}rb^eHBG)2O_JCwZMAtjDc`1fG{0_(0uVvMIb3i-nUxRBF)HR?BQ}u=)=r4 zn7IjFV=Z370ZcxP!*&Cn;(w3f9ZsLoT^WQT@cX|Y8tD4!ve*t8APRC=4^<#C3a3B=yk)n*U#xa`$?AsZtX1%gwH}_Zw!$OUUU|N@IbH>?hAV1u3!z^7Ho!_f?aT3a15>q zuEJ&EW4IuC4?jv1I4e!4GstNfLY*2#`YS|V3Wz@Xzb+Su9v_cb4{aPDjdAcnWeU7j zng!3qp72N^1n$en!5#T@xG7%%*X1kVntUBxk#B~}@=M@n`7XGiunNvA48l3_4mcw| z1gFIp;Dpjc>WK1N>Yy^A_Nx$TM1|1yjiUTF#0c|^mV9xZBLaTXNQ845S#UVVc} zYD8-iIHXxnrMeF)k7jZI@9CakZgvgzo@+-UI5lml-}1n`HEJlxXP zf?xDa;k?02IBnG0dU%8Wz)b8_uQeGHjsjG;E=5H|(TuGwh=e z8Lp>qHrm11WOS6V!RS}UTH|Mo0priieq+K|HJ&h5j$-^bU$gPDW{#I3yxiYLu1{gZ z^$C3V$wV1WPBMlgW>zp_<^;PZ`%*j2!l-R#akMRFX|zpdx%3UDCG1Jwd&FL5_JQ3wnXo%16IT0InBV#GPaR?YBfO;D zm<4bN`O$_BXU#cq%v=seEcIa6YAS4vDdr<4G0%>ckBI&Cw6X>ffGZ=lA`OFm- zWvp(C8uoIFCiYVEc21{xFSp%%P-3z9E{QgaQ<94;?ny4Rd?V3hNw^EF2nS)0Wi#dIpYHe-`=GnaBSKAUvL}IQj z;m(~&INu@DzuxAqVfGokv>)+8??eY3cBWv+Q2^_mRG{D47CxTRc0E z-a0#+xzI6=)#RAUZgj}uHaL_>)Y(@{*4Q`ks_i=jRdy?-D(p53%k2&dOYN_UO6;FY z6*~}qu_KX0BoOX*USkdJJAK^)I^l=we00B^c-(?*S?4ARE8WG=?J*8IJ*L89kC{}9 zyDP29-Ip=nEreO;8pWz{P2^O&WN<583M9*&D|n^O4T55)HmO3V6~Y3i4bpi|`=oQ7 zFUaILKNV%W5GjO@NPa_NlovSuH{Afv`C|Ri`*ww3K6?1N09@<)uwl869JKrDz#?B$ zX!5nD8hmEcYQ4P})!u>3O0RHMxn~@w#50v!g|pf1pgst&NHRRp-xOa1+r#eSiz0>5ZZo^K*I$2U_l%cqc^;WJk%&AUmI;=NQl z$$LOH!F#7%y!UCjIG^8T<9t4d;(dt}!bf=Dd4%)u64u}t_J0rh_ZGa>uSHhi>vsI! z!Vn?M4^@MjP-CbHHK)o#XVQv8T<8VC-i+L!AXZjT1Un-zo|_h!CYchD&rb@dkV^2M zFN*W;kcsi{myPn@E*I(lgM5Vl1G&h6_tKF8L@Fwf2oOHP8|49x!%tZEL)iD7xa8Rw zk2OG+$KqNazt<2hfO!$hP#IwWr4du8!U!8$Zuo3^)*MepMpytdH7tys92&z-3{8=Y z56R)jhLlM~ht!KAf)~q#2d|V33*IUh8hl(nB>0|OXvjP1&=4XF3n2o8|DDl2!LvC2 z`=bE1VfMNtbpK>@zC`pLtVeY;56WZ2P#mKN`7x%D6EmI4h<2c*M!7MPqx_f&ks<83 z$S6)sM3O{QL>4b1yhJc3yjBzv-XAAP2b#+K`oK0_h1BR7%1uT4KBlJucpd z850-8ij0fkgvTaGgvDm?LSl*pK{4}${?Uu1eWO>%_(X4#^Nv0&=M{YmkAF#fM-!n> zG!Y>D?_3G^x*s=;{oa7ttFpfC!7RjM1^RGd3KOzZq#-?39a2(_Au)9t6`yKLi%D^! zN2Yi(!jl77VaapY!AWu4z@#)u|D*!GZ{l1juf&BSkA!X+_k<0yu89Yc>$0v1uch4* zh!i4lPayp7TnPEPAGa+P#{vDfH~;G%%zQi+VLP&rlq@Mo%u<2)>~Rp2JsBdiXHenU z4z$oLcY1J^A2TpBl;xKh!|};Tk?_jM<+-O<3S85hgwE;9MYGcer5)4v%Q&Q8lXgsd zC2~w7QnS;DV0J3uf9DL&|9v$Gk$!$M3}z@F1#C0U`=@U{29Q z2r06pf{JF*0t#JdzJ=Zl?}8wvXF(*}EkBXtlAkT%lvl=c$eS;)%UdcnD{r09Hg6wt zMQEG*Qpz@$2xjKs3N455zBBr4+Axm6AohDDW_MJ4-Giw@vMVtkzn)XUf#3=m2&~iq z|4Jk9t(pqnmDZGJr6bL~(u3w&;ZJw2n8S3eh-cZCXL4qhmvC*$>m_HDb?~N_t>Igi z?Gad(U*=nuKIdDO5FR3FS^PH#u?Aan0oGuCH|Dm^L-(x(D5(QTMjMy z1nv!b;My<|oEt2`sbLo7*x*9hH~7$IHH6S@>th%*>eHB3^@S{px?0Y(x+UBxbpsNU z>vl_+)m@Y@tNoK}RztXE^N{Ml*`0~kgyOHy0(I1leijOAuwe8#7<8Y7=sqm~p6KPX zTP480RR-+Z)L~|uA=tJ}2Aj4SFr&=@tlHcu%eDZ@ye)z@wJnK0xh;=w+FH$+*xJUN z(Av)$-#W}PZvBa6yyzLrXdz)4H6u-g{he(%=4&v&3)OTHX4kd+y$2K3fi+l){=Xc+ zri%iLZUIc|R)DEJS}?iC7|eR6fN764OzN2p6IXb_gcTt$enl*0v?7Z#=&7LT_q5RT zdirQOJv(UHJ?CiJ-B0P-%Rke#mJx>5(!be&_3y>}CD`xARy-fuaULwgd4Q@MJh}&i zia4tuU>bVygtbgCSSJPJ)`>xXy%y-LHwNAHQ$T0E4QQ`-0Rd0jlpD48!Q6V z!A4LX>;|R5Ay6DV1&Zq*Q;KUpQQ|d(CLZ{k)eQhkvE~aG<27;V=x3pD3|0b!VW!tQ z0Q(I97O00N=%sq7?`k_(pg1fA;$a0)7}f;&VMCA`o(!_PtU+d%Gf4091L@t-AljV; z!rj#%wYviZyEg!T_fg>QdH{l*A3(5!fMEOIbYbmVvF^24@1oJ?a4-Y>{9(P6pfqpz5XvYhH zI^GCy9N+jD`u1@Y`D4$Jj|llMOR)A0U0MZ`7chw1tBiXF5%7iGA>3g<4Je9bo74=j;uir zAUBbh$Y+FnVF8YN`RE=H_B{&w?YA5AvA-6WJ05ejFjw(3fan|m54*vlK& z2!9lVHTT~)`Z*}fKMr7w{nfx+dCZl%jC~)?y)nA~g53MI7xIw81vwiRqshP=Ou-1tK7=pGObRRGr939~J* z&qn6~)PDw$#XrWs@ooR*`##9%^B_2+DAt&TydK>TpuhQ z$3O7^fAcm8MA95SaU9?+%Nt%X!r&<*9v(3=;6A+o?lLOiHlr49G8VvfMjQOb zTn4`~d*K)6TDZg}OZ(c}TqK>t^v15uR# zqKs`4u4%KMAhzv)~fH2rlxg;3s}P{K#JjX9ewW zTF?!r1gqf(!6rB^wHuBKe}Kcn8?ayW0`^K1*eyd~ScXtL{{_)yecetRMF-oVDFL5U zMetln86L{(!!6k#& z>{aZA-HPjASaCb-P&y3Tl`g{;w8tl-@g>71;Fr-yYZPA)fZPIF` zHfS%W2DSUCb=sS$HQM{A0iAQyDxHV4Ufp-J9$iA~M!JyYV<5)ZhVgjmF~v*mWPqz? zc-fyohYPwAa8g$R4(aQ|UW2Ky)6fpK8hOBGqd?eT6bb8%5~#IC8PtGLKGknjMy)cM zN9!|cqOCAmLhCVFLF+PFPhV!VlfKmW1ii!fHhuB<*NoQjguV!AnShM{o6(ONzQEkO zc!|F}1N|RwIVUUtj!a_0$OIAWn5YR`Oeeyi*$h}?<_!I2KG0_tLai{1rn=0MXv@qp zX-mxtXdR{%^d+Ws^fuELMyu&EMvLicX0z!Kv&rl*tI_Nlt6}mBR^4R6to;h3W(*%O z{}0T+HWPiz9B8kuz#OIS4)z3gg>jqJG=`#4n=7daJ{PdR0lpV_5WgoQB2 z@@g91f^6~Dip2jZtlr$E>m`V^vt!vCFI%aZ0SaxW(4%xP{icBnoWKO61u*lE}6F z$jP-OY=o6FhUZpzJ4F9KgYJ6(-E*fGz$QGd!S?jpvtgNoEG%)Y#uweFdXmE6( zY8^eOYDa%sl|vZ4+#!ZhYM;y~w$EY~*%z@2?B{aw?3%bac1tC)>;@z=?RN0e?N9R3 z>>u#b9NtT$IuH)R9?N4JfM2lRCop@jAHa}5_8*UZ`1Mj38nil#pvgrY8eEN`#?2h& zy3V31TwSPA7av-YOAx)lC4!OX9M8;gPGe;`=d&}MDmZCQ^SP-`?UKn(t9Xe{Tloo2 z$N2HicagV}@y>)B??O0uWPj%&*8GAyz+rUXVO;ub#AQc69=otDZ64@59s;QIRED{p z22kNO1xmbZs6x-#RKBMtEyu&3p5+n7$Z(Hgrnx7xQrxrIN$#bb1h+bgIJY**7`I-2 zwA*Gul>1>pr28%8FJ7bvkwCZz=R0?B9-PHK?+--h34c9^P3JizV=k6uNy7R$CsAk6HHI?iDV>rC$i$aGubiTMVu(_c@mLci+JH) zJ^V1Qje=0`gMtw6>rx@!uX!OpL?YCOa6`Qb=Q}t44_jXW9@VvdzwS)jh>(y#NJ1Q9 z#NFLpi5n5(#L*CfB#@xNg1e`b0>#?WQg?an>#M$&SEo*e_WswMnY6t3|9$;d?_`oW zYoC2=ugy7U*zV7g>#CH8qV_ymLA^z6Ed|!nt`&JY=*u@nSH3Me3f$3}ABd*>NTDG= zQC63iA*;>HmsjVNs#WIJsF&w9X_n@8YZd1X=oIB{)GN&0qo1F9${;WI#7=3*B#7W<)Y zLAX$}AYQ0ikS41r%9WQD6|0pLRjDs1YSbt!?9|FHT%nU&IHH?VxJy5)@T5Uz;WdMd z!ncX<^)m}aT|$S@CbT5Hk;%S5A3V&upRDCrsH5g%I6SftSXxfKQ6@)AnIRg>EKyhP zjM{Qx3ohmyL6d$X32Wp^pc%=sU^qt zQ%WB-NG^SY_)agSRMbr=5p@V{LQBHS90ND#gGtu?SOeRE;pbLj-6Eie@3l~u*H;^$ zrrH9P)eb1HnUB(%AQaa`2}LzYvV!VNSzdL4Jg2%$EvtH=dPY^7W?EIhc1qP+ousO9 z-Gr*6dhu14_2a5uCGP6QRf;vl^djnC){Ch7MmMrf)QMauY7<&fDm=w8@Ce)BB zYqv&Z>!4lUrhmP6XXtrvBITVK=(YWYe#xcN`5;AT-PxJlHU!cF>MlJz}G{)t}d zzJ6+NN~3DzNb)2HWoO`q;BHGR7N(DdmPHGMlp4d2B|T#?S@ zNoUf?zhfEagcZO5Wl`4v+kwvoL?)52LI<%cO%T1(3Q+@d5jo(6h=E{)4MZb!AQ`~} z*+SqzvEV;YEAt&_lY0*=mwT?+fP8gETBC#FTvL8^B=dK5miOBUb1P>b^aCim+Mr`3f;tIbJU-*oK!h0kR zUK`TkxuF0a8!832k!HbVq+ggfGAwf**&}ltIVW=%xh-=T{!Heu{&%^-1UT-{tWq9Xo~DJ5CFhJ8lV<{bj-<uGl&B}#iGE^$SVxSJ zXFGZJDE49ej^pGwhhK0RKjRjD#A|fXf2jO_R^&SFs&XE8Rrp2)(Rezd)K8y_L3w?;1)7U1aeAniId{8_&v&mP=`qYu9mEP^amu!>I zv6?(1xP#5)*+GtdEc+OqJz^k|0`eW4D~ zKo_E(5pAI_1V{SUhxLpkXDay$$W=+62HM`v;n9nCv4RXkS?5z+)V+rb`XVNY^AZe1oKrz@)$lAOe&f*o$xIzT(~d6=95(6@HL9ZoGDa#;V%LLKiK>fse53p`^o7f+b_ z%<_mGwycwr0I&sQk2~JoH;`q!F9G$rphiC4^p;^aqVAjLf zXZaNNT7H0CvwskFSc$?ovE5n}wmksRQMtwKjvJ>z4^HKLKF6P*w${SqmL_=A$`%h> zd*Yl;C{E2uz;W9w9JMXNA-hT(u&c*@yB6%V>&70tW!P;ugq`-I!nplTVY~eyVXOUl zVY9y!{A{5F@<-hALaE_p8o08jdJdGlhd?IOcP2LqgS znvLUgU2u3_0QS#|#)L}>cDdwYhf6WGyHsJTOM|f4rA-)f?GZ*@R|*?k*9*h0TV?BA z_sQ0}o{|l@J}O)7_L6*+`xo++?)T*@+(p@P6_%;+Bd60($opC-^%gbwRpQ|g;2f8~ z6CS!aU~VU#QUOJpZBwBy*_u;x_y6D>+%)lo&SSxz3Bt;KS%w2BNn(A#~7Ed zkMh0!ej3>6XM(K(b1)X@j*-AXtP70Bn!pqc24)KbfkncKzzShmV4ZA9V2i9Tuv^v} zxI*3?IIPwgxLs{=;34()z)AJCz$Z0Yf@HEp)Wj7=m{?oy27eui^Cda z?O`4A*03e=masKyO<`Nq8^iW%G=!bis1JWkb7A=V#7`Qv5u!Swra-t7pR&F$v+g%j z*aqp;It)Dyrc3z`#+bBYeWX4Hqb#r@+7U}*ywDdDg6^0YbjG9z?J?OxYjmN|5?wB9 zie4ydjBb(FNB64LMXyq?jULsgj-Jr0iaw=T5q({&JmwwZ2hH*rQKKwIR43HRRrrug z{Bz{HO78PqVvpqld->c(JBI0xRq?u58gGi;cw2NOxT7N>0Bs48Xii8J7A0f|4GDQd zT|$YhHojU`6Te7a72l;+5x+vcJbr^lY5XqD;`kF<3lgqs6(zhue5YBIC~6SuMF|S1 zNqCoay-odpnY?H68Rr*Lb5etDq81)vShzG<3*E`a=t!|fYl;h+Qhd>v5{9~zIMk-3 z3e_puLS;&ktRkgSR+iErFHPxCD^6afUX;9Eqab;QW`4>st-O>g+PNvOYUiZf)yhc~ zHF8rFP@lq^><3RU+;O@Cy6jP1gCLBDO;*^%ld>t;9NN;U%=IoxfX@ZGgHQ3)JM;qcX<>R{8hK7mvszY8uX;w#kVab0R?XC$!&=EX7l{|NlXAY~ z^H0s>98rT%pTZ0D_f>M8mG%Nr|L&@0I}k&B-A%tVv0Z8l^iWw~hOz=%loYyRL7^WC z3&W6K7>B&VR3WD@N60E%Aj>SQlBX9glBX7St0fl2bR1dA%s}WLlUL&~r zHgQKIxav3c;7U<}kP1;v!VUW1JSD&p^6ze8J5Z7g5&doK2ehTUk-C$9Nw3pKYW)l( z*Uv#>g9{QGd=TFdirB^ATLsxe21Y%CVS8){^s4Xv`^hNberh7mRYhCOP24QJJT z8=fRSRrjs`Rn50vRP(L-8&~M>)8shN%691Fc%U2^Ai9bA#nfFL)E%@Zp;ZU5t;UFM zn~kV8Cq%T*M|gVx!rCJc+Ma;m_6!8I7YYIGRf1o8lgy{RPv+gePVU*hOYYHrTJGNd zIPq_}d)qH^_f}Ev-tsr3JyFM4|A{VOOCPY7Qe@du_64Gvuk-tM+b*9S`TB3^)xH!EvY-_Cp=88(M`qL)&08bWE@sx< zZy-iQLBgS>$~$p3l6#Px-Q=m?1e8!3W>B)njst-^0Qa5br#_#(TL!ZUJ(y0IVEV)? zm`vEic)|@vd;N(>817BMw7mr|*t-z=d%K~xcRh3`_CjakA!tv$0PQ_rL1*`$(A_0M zcc&84d8|#W_gdDoU&_Hy4wjQIXAk?~KDNPrVEzHXk=l6n5o+*bfZ+*s=$_Jt)=3j+ zo}2}ZllD+Q=?=A%0g#=HfgmluCpod4Y$jF`tjq}t>l2T25};5%{xdtF_!qX(=Obf( z=U}S#0(l34q@zG6rKu-B>UfI$XMpMF0R!rD?TZ3rk5Jz}GL0|=F3lz!2nM8=8IW9N zFmRcZ{N-xpMM#%Pa*36>M4fx-b$;e9ai0(s7-iiD={hA3fj^)l-+!LC z!`DA5(95=Nq|b|4?=*5pu&$n}JuntevF)Fs@1^|9%c}g#JJLQB;yqPfLXi(qXJAa9 z+@ViCGXuV$VENjGqJ{pD4(oo$zVSULyC2vlKhW7f(6K)}OMIk26WvqFx@TMgB5wj- zPm-U!GstW33Vr`z{^jEb_Je$(%7uKR%7uI{-4~(({HzE3N}t@fRNap%9pq0{orjUW zA7<)%YNR_s9#=rrw4lD7K{YxBIsk_oFmJxfet_i?W&=!}tT6$T3ci36^~b_i&2kU!Y#UL5>#`nTNZ4CFMH4hVqt@ zFICT}*P=ePzP2G>O(UeIl#j6`JfJ+2Bjtl~$yH9Cdh)c9qn8}ZS@IA$M#!<596MO% zK9+fuO?4Lkp)WqA>i;(z@*}c;Kuh0eN$>q15T{Y=>*+$2Yx5^PRW3%_k205^@+W5u zenJMDyNEnhF2RZu4v4R{!>lcT4FiQQ?$H-_F`xAc#b-#wC+rs=qJ%s(jq9}V8a;NEt#?J$TONcW_rd8-aqTa=w5X|# zUj#$)0FXd$zs_VGoyqBkx7jaVLn^uQ$y3HsYw6`C+`?i`SADpNmE>7Vj!|-q;}YBC zBKzkB{x?ZW&as5EvafMk{yR>oi#Vwv;=}_G&6L;d+#|j+;?U!C^Qndw-jf^S4Y>_o zRCB{KYC*WA9*3Li8MvlVfGZm1xTLud7d4x4L9-K+TKzbuHGs3)>v39pGfryn#&Mk^ zII43VM|5xEklq_Op#L@Y8T^R}1FliiIFcTKbk*@aPH$gWampdyg`c?0eCn#)c6i$xxW?xrobJza89Y5( z4@a%calpnAd**myr)?;<*~VjwT{K$6b@uI8Yu|?<`&Afp*nm|I zJA{=EhlLf64++a0pAwcjeJu1l-4lA9MWN?^aF^5id*ptOOU#X6#`&CD&-ejHxeOn0 z*2Hcn6Kr?3!KS%x*f=i$!!A)+>ym^amn;mr6kx!$3@cn~vD~!@OILJQnln|O#_>A>_oxHcgxwKP*pCyilF}@3+ z?(`I}$=whm9+p@;-x-6R-dO1sisfE$Sn8FEey<$#dM!Y=R|Pt~>V?H#twOt3uh8l} zD71Kw$(p<;WQ)8{$r^mF$?ARHl-K!wCtK(%Do{HGA5r!(>-+-wuTy_N#3lcDytMy= z@g3hAqi@#w=wp@d3@rDv#}a=J^!f*)J0J>+0}|05kb$;j^(f?0J16R1zpXD-pIE7j# z3D_LV7?*ae4AMq_&~$VM+hB2s3)(|`(GnVlrqDPvhNhxEG#hoHMW_v}5UNA#g{shY zp(1pttUPp`tTc4Hyd><1d_mYFYDHl$s1=2OrB)dJr@Sy+lps?eOq9Jvo?EQ@#S~=@ zWU@m#uy7MjI~EitUD@W{ZSDcjMIZk0ScZj(GS?tofG{G?iX{L^Y_@&6%yCq%h~bQNA;_<5E3{~Wmw z=c{rsd=ByFe!kyIJL(hkQIlYX%EUP+OLRd=q7N1%hM+Jp8u^Jy$V<#ZZc?F;lT;yO zB{c|{Nu9Fvq?Pitq)~ZF@;zCf^}`BSd-919*o0;BqGC0`eZ9{@qc` zb|6+20$ub+Bkib8)j?T`35rv#P?YM7f>clBr3N7kH8TIwahYG~3Au0Sb-7R3dvc%BpX9zJqD+BeB`&j`Co4E6$+?{xe1uY9 zCDFy#3u#MnEwwl0QbMIRVk(UgRXGchRrUz4azj{^FG8zB5mFtC;ObNaR_7w1x(t5R z^@4A8m*8E!TJWsdCYxV#Oy*H@RpwsvPnmo5k23cvQRX3`Qi%(t%6obCG*NrEDeq%h zO0>7LFSb&5(VkS=6V)I`NWB4q8q5&bV1s}LXZSUG!nZLHK8=y^UX%#0MOpA%R1A+r zwQyh50oO$X!n{RWgt?232+oVH2u@9J2~LgQ3r-E90?zfKOu|{#@enz7N_Wyw8V*td z^!8Hw@>$*uWb?g*PHI2?-lts$o*hP*-!T&&9d>Z zwdZoS15rez^5d@Z~ZgSTlWR@*W8D}8b;4UO6=>W4_49#l%y-j(LqUAvw`Dr6iA^g zi=;01A?6WtworpoJ{xb>fWf!{^v6x1H$IzigzmTpbjAarJstzC@eF8;mqLBK8S?Eb zAZ+J{wo%k>qmbSDAwjLXMTD?fi5&yV9L#D}4yJ)zCEKV!cK|WF*ao`+SITAE3G(kH z|9(LKpbVOabRis~#yvEHuqGG;9%3+ZID|+b@(4~ehuEnOv0{h#!GqMg2VNs6Q1|~% zhzdwKm~~S*m~plNIkU+XM?D@$Y3gO$;Sno8TewO<790kca3W9SC#?PA* z)Y_8_N+-QI=`jd;h!gNboO~Z*hkr==A|e(($q%2uO?<}B-6KQ={woKwkMj{ZMkj;6)0hmnfKCq2_DkQNcvCG_fz>7DfjZ))IJndKIGl0dE1FUn{HO>L# zwIT0x)>H2V`d-@q@`j3UDi89hDi`wE1N%Z0xeyufy*BU@eew(Y>U}%qL4L*EsM2{D zPQ>Cm)tw-dsykY5Q*oNA@($Bgd620yAkrR;7$OtOGa$7@3zU07l=%ncnV3z)I57d` znV3_M_JaIL75WDq_dAXKb?Q#i2k@;b|M0n_dF95cyn_TIl^xQ46fYti$}>6nP@ad8 zaxv0gkY1L*0{5x=f1~dI6`RSigG~GI6OQ6XoW=K4zu!`Ue?#Ye%~xO2sxMTW5~On} z(w+>(9t=%M>+2J`s{DhLkFh3Pq1=NJ$4_UmKE>pzA;%*8K)wAP_4Zxr?Qf|2zoPE{ z0$W)2E|z_OH9x`fFW@8k;sdoVUH*kzo$U|(A$8d?Cx~SMC^E;uuO;^IC3X0r^1{8Kk*WUa{ zJO0DA`4Hx;n*&~Fzjz5@aO;WREzA z)AYqj{>5=T&t7r|N5~-c+Cxy@Y%>MvE0=!fu)b@+;YNEt(3aAX8f--)PC>I-w|Q(; zf7U6A^+_gA4tW;f94g6B$5GJC*6$=wKY3P>W0>V`#eVu?uW%fDWEZhpej7X0KgJG? zAF*9a#5QdaTOYuEBjt5N|K_yv7V!dKKP{!8HFa=ZJ{_0T=HMX>cbwG($Ey#L{H^A@MIXB;@?+fsXSx_x-MfJuD=oHVe&k!emiVCanrqcH3; zipLJ)bZj%u!xrOWY%;FGm`Oc0nzUlXqzA($E3t0+FxE`pjv>>77&JYPRc4Q4<&5{R z-26u@wGgpHg?<(8&f!!$ms7DDmmLpk4Ohn5Ty~DzNXxPo_L`Ys=ZrbnYT<@WGXt=3 zW+aAZC1TyI46K=zkJXl?7__X$fMp|ASax9f>?K$_dk9OcHlfdIFM6y`q1*Zzx@_LS z;yK@9Z#YxB8;`2v^xfirv_VHmL2g__GwhRs%n*kCgY>*hFN$kq$1 z>_V{8E(Xi&lCi`-3;p(m=(R6Hw|y8(O-`4w$mu1a z!TD>Uey%9gO~F}-kKDQJ`Edyj=JFoO7@OD^NbSvOew4mh>!gQOPG(r{Y>Opx-OxMF zAKml9(K#<39WH5TbIC!g%K|jJRAP}!0~%f1QSZ7Gb*}4B>$Y8}aXTzjyFV;cxj!dV zcziCDd;CF&f5TlA{^`TzI7FF)In5>RAhDB6|5%We|6qLQu7y4~V|2S)p~GV?+U9$s zWqvT4=0~H^GYR#cnONwVk6O=CRD0H<%BuwxUcD&yS}l}$Z5B$r4+zEHlfnX@+d`4g z9ihyH}0a8&ulq0%oE<$gIR^IL!t|0)#wH)4T*mr&?GAQS|Q3V8v0h1`I1vYfzMvh2W5 zWZ6N#3fY08kVRyx@FIP1EruagqA~}wi`bM5tf3uCX-5a`SQMa-y1*Hz3A9C3kPFI# zd{7z`f|8(UEC@3Q2-zXag{+VbLPqEwAwBf8EG_JDS!&ov z#4m&>C=jZ|v*fwVx}Q!}o&y@sWQ@xYY>;;J(l^cgeQl^NDnqBEEYu3cVa_ND^F%>d z0P@2kkQ*L{obXg+hvy71AP>2q}^4h2+RxvZTmUvc#wxvV^GjiJu8k zf{+lY#8dRaMe>~>|6c0fZNxCcuNC~cGl_9F{ZSF6h2lsf6h_TLev|`pquh}l<%`Uy zP^3piBRx79Y0+6ojVVHMOcj!1nuWyJJ|RAKtq>QxLlzr%LKYKuT^1epFXAUclpsXM zD)D$c!(P_=D7p9KQ~MXNFA~dg8Rzo-TG~+@r;hx%X~>B)M`oNY(&Jo^7UzwW_#h<5 zM`EgQAs=UQv_rt=_4)46e-EpNJ@4_V)A^%CkG%d zB^;b_)d$Zu1eOU0xz9e|(yefESf5+FN;FI+?9%1<> z7;f&B_To^34>Js3L3y;eitRuE!z+0vI~M!*$Z$g`&w`+6$PgfQE-+}EDC2> z&x5T04)ShnW;?WSOcKq_%6%v~v@3BT5Keo1tF+-&WrX=v7VxN^1NZ8=aI5x&Yjq%8 zYN9Z&CJD|pIdG~egJW$Y>}&gAS33;b+6mayPQtqOS>j9B)cgsXY7sV7qA-UzQK{OC z(@O2#!FK56nCw*TLum)nDG6d|QxI*M-z3M}Mfz}BG#!qMEaA{(5Bnxp*fsgUwkZ^I zn&V*8oB^xm1(@Bu5SGndnAyAr7A?DA-f|XZEw^FT{5fVc-G})i5$26b9IjWLhw9>Z z=w&G#VA*YkS>0Bc+3g66Zg-e>`(s8=1WbF9 zFuf-aCOuU!?rDcn&ng)9jAL5QDH!zJfVG1Gh#>+9cfy{qB&H8&!)TQu3|E;ERxnuQM9hc&sz4$JdaE*^yQ&1*s}@0P z)iP+T+6481BajbVh1$w@iSMDlLWIV0C3dl%W6S7+Ra_rd11)PfC#cQ>B~mJfjsTv7 zBQbjeHRwiQ+Nc~lV|vgSGlJTvIpm`@5JnjYjZ$BZaq%DH;xo!YJ<3irN(Ya!u#MDr z8z1K2e;F8|FdX@v6&DrQx`GdK50G~;d1^ZVH*aAds1AMjv&V&{9x#gbqPFPSB2% zwBsc0I7K^7GblREh3GUV+SAg-m|%eXC?1(jN%p}r42WN*9j`DLdzFjwtDJCO?Fo5Bl@EDiDjy;P z-qix$r%yg&+k7$`_-r1*An9{1e4le7{DOn;OIG?z_KPoBiLc%yK1D5kUck2!$sJ5y z7xK=23@~E-w55E{|L#MPaxNdL_Mkj?KgnPFLfB8f(*=HF+x$YI@;m+UM;P!Y`^KM~ z3`Gt=akuJT)EmTes=WqNxd#)4<`${Bm3uIxdr_q`Akv+rl~CRXD(wZ4?gf#)BStzC zvw_$`?1b`6%rX2)C3v4Y^EW!~R~jqb#3AK9q`e2w zon`N3D;#I}7w{B)@dW?sF!EsZkDXmT=MziUG|H& zsQX`~?tc-*tXUPFp&hqr$1S$Y<7}6kwBrWtxP~$IgdModHo1t?wBiaTY1KJ;>MUDM zIz1(2%}%Qzy;gkX5tLW|exvH*A3%?sru3IB`P^BbAacd9E~(_mWvRuuL_03hjtjJ7 zl6IV<9cO6ADXhl{Y-Z2ggCjVKL;Q;a{PaG&Pw#xM$lmQyVYdp>KA4}Sqi!5dA8_h@ zQ%y>RsiH} z2iZf;a@1VMCJyc~dU%w5Q#xI?LHHZLa!UDvL-}8(oPMOOcT(z^Q{JO89rkQvmS9EB zdF1nDiQyc5378Nvuv?agow8z#%d4m(XMM6}pT?bP|hA{>Eok$`to4POF!Rv(D82cEEm4al1|A*gnk=V}`RZV&sH% z#$FgQ3C5sFGzO+8W5x7LESsK>CDTjMZ(4(1(?#euU5qZXWms&s9_=%>qix1vw3t7P zX7gv!WbqjqXWmD{Eb+hap`$VfBke&s?@fL__qkGQ@cl7s#+Wnou-e=VD=loXY^E#v zXZfLbRv5Z1W6^1uf)2}Uw9PI=>+Etg&t8Zot5!5x^`XIPHR`N4W1;na)YzOy^_-_r zHRlsl+Wv+LTk*f}5Axme;S$WH_GBQn4xc+1hKzYo^U)_O=4hec#u(jmW@E9f6WVM& z(P9^fCc8*9+9jagE)8||xu~^YfExQMR5>)F(xDR-4l7aSxDlm}6DV;yg9Xly6Ca{z z?mZOF75|1a=PQO^Hv*M8n4{qgb%-ro>ee$1Svj9^{yaI_9jBq$$pVeecBprDMeST) z)XWV*)!b-Q%u7P~yiAnN%SXw)G8DVip~$5jg|16c;5v*vw_V6}JBb|k>&SNh7qUEl zB1B}l|BdI!^(gtzL{Vo*dr*kcNMJSX==TTO**1-?dRXXYifT7&RJc2%%-s_u?tv)w zh(M7?911*Ak?)a%y!pk*onMV?&t_zK_94@AEi$~uk>+(AsoqzS>hm^Ie10HACA^im z%`oE;@}Ho_-^);R8!^oAXC>e3rfp5MquNUwK@IKmmUdk4yjj z70Y&@{@#;H?N6*_=(CJ=bkL4^+EM1Ofg(RcOpE>JcB*iP+#(hzZ_;=#axgRLCPjWaulzw}dD}hWrKGh*IW(4lxYg znZb6*WIOQLpTanwzM+IeQK$?#!3M|-Hbr`{HBy6}kR0rR#1KEkhlCO_hzm_dY-kQ* z!io_cwh&R_9f$~DiSY1E2#Yv~(1?pdNaRbzH-spJL?{s&PVG-0oF?A^a*yXQ{LiK4 z;=I;_IctfLKOUCL?J*zw1`WIsyq<6w=x7CF64ORvx^d? zj_;SyzU%~QzF2L<#TX$b#sX0>wup?Ki||-agvACRG&UR|aq$R_OGi+A0RrPI5s=Uf zzl0_5P1pdR#J%uNoP<~6v+zv(lFvWkl^`nMO*~AFV^SW7+?y#$)|Rj@5FJHq2imnD zi<*z^6qlrqh(rT~C7K~L(F(yyjtEL}M_`gK0+K`FpBw|fYbbUXNDxWGHZ3tkyP@XUz9{LCb{XJ*4Ks|2oD^>E4R!Q8C1 zaL(QZr|dIu%zlda4{;w(St6V=l{lTNJd?GZ+#70@XMuY7Y@$>wr!BdZ21&FfoVNJp zX~8qs5cBh9z&+0zZh1~{&GUduz8~i0hhc7hJe>10;8;)uhk}K$FX)6_;SlB&?to3< zDOeXiL3|49g5O|MAi^e}kt=bWKA#}}7ILp|RGtOuBpUd-q>j3aw!~4c1(#F%mdY`& zL?6y2CU7j71&2~Q*q6?OU8xsrOM@_{G#WN#DX=cfhgDe>EX&(4t9$?!<=bFhegZSf zAA?!>$Cy#}E6ht7!AmF+ahPTAB-a?F=};@Mq+PiWrM6AE4~5N&NZR9954h1zyIL(+ z*G|LiT2olo&c>`-2h6N>gT+E$m@f>&jD-m>TbK>gx-yv5HN&`WIgIKy!?5lsrqx}C zLEVQiTzC(LwNw)|O6-&N;XY1;s;wgb>;djuM-uR*i*F0@)0#WyRV zI1kkctm)-=pcGrYj6NU=mnrw5L@Z@LAm;IRa|m<7Xo(v1mgqrei4nAySU_vZ9B3|? z3ymdSP+JlT`H}<(OW4ttuo0KA5=+*wqe~ZUQo!~-&xP%k87kGr_u3Evj zRA+%oSF;}s0kQmOAmK*X5i<#6LVv9QjdeN@)=dM}P3M4~MKJJL$3S2m7r}L$)Yhgc z2m0D3f|`2`b>skiqiFMi!d&ApX^ zcFPCEPn?iM1%_GQRqHtx$h&ZiZ9tBcagN2EfY&a-k@9pF-DpgGuD1_R+fV+3#36xT zP=1JZNPAKa(~iRo0FO8*H{%}V;(wHr{ZS6=qwL&A=-?wP>@dakA&T}xcUjJTLc|cc zdsxo~)~%SlY2=C|kM}|4IiOib*#5@=ofCjSS2DQgB1fE`f;s~r3WJB(E*ID?53^k^ z(jS)?09}$c>2eah#KC`wzPQ9nKEi??q3(a=6N0|D_@^=lvxDn1xiiQcbrkS9p*#mP zlYEBc)0T2C4-=P&M^(9y>%hl-*e2Ms+_*s#IsW<>+kvoRGeyp1lIcM_E7?MNts*2}vRnA4qNj$H@)VZ9g ze8`(};B5+}ciA@Yn=9{W{WpWtPq^rP%E|Z+2l*X3{tlgchZVW=I)&YTP{nSNdy?}2 zxdX`Se1-h{^|Z$T^(R$(U!GUxL8P3^+xY*_<4om3K2zmFzGi>@&Oo}r0Qkj0`GpR@ zGC2B;WA%3q!uxFa`y{>33jXoDD*s@h!qgcMJ1Fl(mCk@9LU|sh6w19IQ)f|@;O{#* zr0;#rZYW?pN%% zU$EnR#s<5?|9`?yP2I&IU&XT5vFtIb>v7g^pW-aaTkOcMvlG3-cVAMR&QWqo87S%eiFAYP z4TTN=oqzZpx~!WC>tw_FxRNUX|3NhCkV=j`mS4j1t67gmcEdK7-^KEmu>4gldmYQ( zM9sdF%!k;G&)_DN`*n7vtN0RE=*3H9k?;tVx42CHj}6KkggQB=v8!3IB^}7+Nv;s` z#E~PNT{NHNm$Lk7mfyhgTUmY=%U^=awBr%1#|5hWN$g>39HSK%*gKx0S3crTKPhgJ zIRfPlqA5t+oUIhs-F&7>`@KP5yg*+(4Qu*K+JoWCmJKII0()8pOU>u>REo2-<23un zDYPi|VH~3!M=(eajNkzK#y!L}r+2U>HUp0C^%=k0f$rvh;j%l#ru}qoJNWE#&DU^HOpQVKe*27=N>o zmW?R9^Q`A_NnA7e)bv^d3>EyJ=CfQtUkb7fTEd*=TV=$zV zj6sb|3~1(KrDh41YgS>YRs;IA+R>-A1U=eA=+fSd#X9@Zp>qyxx{sq(?*p{x|BPk> z5ls(3y88NgF8$XW$xj^T^t#`Q@g1kyErv2|)HT3b-5D6vv&Bk%S1i-_#S(*1^clpW z#~>Nq2ASxbR)CIarD!v(L91ainhm?L$Z!CShNGxAnn0b=8Ppm-h8p7!P;K%vs-}wy zRH`8DgOPGD7rE@8U(F)(P3_Y77KGMnrVyrSuR*O%NsS8!Kk*3 zMCI%Rl+R8>+3Z}D%q~W;RW%k^HKWkF7X{X9kY}?Uxi&|UGv_k0=e&k2+wYKNCn{m9 z#52+nTymcZq7N8$Y!9Z+;1aWn%WfZi($4m2u+c-UjR~se%tpl=N0ixmpv2Y>3v5GC zWEX=1yCme>Wg^$E06F#*$hL1lrb8Dp99ALSaSPI%4k5+qB2t`RLbCHWNS-V5`8T9I z&;{}ylX5VT^g#rD5JsKBaIDjt@g?o3a?(PnqY;W7El}uWi+m>+aKs+%8D+(MA#7L7!= zBqX?JA>O?RaURu(^=L)({AGxmzX6e+dlBI^iEyuH5bpg2@h4x4f8lC~@;;aY)cD(} z!AGQfNEmYT#4x_19aXfWh<0Sn*F*Yz6QsyE(`+O}T$WMt&^!-UG55(|uE5nTS z49Qnei+9qF2HI9mJMw5ps;@Q@eT)$AYk^qbIf(XkMx?I?B7FT2?iY$MzgUF&ry|5Z z7r_DL2nuLKU|=r-0@uMmXg7R=&cHYLN%#ccA%5p;k?$$-aJ2GH-aX{roJlD_t-p+6 zXb0_~Y(p{qk;S%32+}}I;50-Anjt*U3Sohc2nlpUaF7pzf`Snk9EE`3B>0D9!!M)+ zzM=K-3GIe=*cy0-?Zo`>Q}76Xg7}2^jXyI=3R7Z|ZE%=;JIOuD&~qq{vPjy8!k??@ zk3zOhI{Qd$gdE{v`UnX#K~UH%1cuqcKWrZS!ad;|9sr;42zW;%z$+pXo{N{UkAY?3Mul&8FpWfgUJFVUROSeJI>(?6+f zr)b(56s-flXe0PUo5MTW23|2v@Qm@m{1`uY#D>BxHV&?_>2QfF#Jsp_%#Ck{bNnhe z#&3f|!g1Iq+<;xehkV|HL%gVfBXKgF>w=UABJXf1=cO{Bo6kmu!DR)EcloKOM94En!(;hgk(Km|5Tri-HiC7sSG>FaxHA3oyN~9wtS7FfQ5vqoM;a zEV=}PqBmh!_yZxrs6Ywn`=Pega$acU`b3G`LuuID0#x#KE~QZd?F!@Xy=miI`p2e1 zfO)wtOv?>1y?h2t%B^5r?nt=9sKOtH6%m+Lkqm>10_a!NLa(w5x|QpoQ!xSUiie<8 z@jUS*w9Eg1PMHW@VmHg*EXngWwnK+}EUk0j>R<8;Lx=P9#Em0Z+ykmcO9yIQ)VW>M+g%Jo zx)=m>x)NLfJGt<5azJ$!E0bHD(jgxT+r`H@@le2ZP?)vfBWOdLh|R3`x<2Jupsp3F zJ81`~zllh~mojxOpVoZej9_R29YVH>0q6jOtpNsr12YH)J_B522RxLU9tSv>2iTEU zvJqGID8Kl41x598ist1MipzckmWm2&p!^$LsXPnRES&{f%dxPYbJ8#nI0Cp5bBGy) zA&b%8Nd8dD>5ski$3EJzZ!Uuo21Wb15bVz(q%VhO1Mg+QdnxWG*e52a`}h1xh*&kO{9dAk zn>iNAmrR~enmd0lV7HI_`vC*GP?P!`Q~OX(K7dmc2dCIBrx~E1VSs*?TKgQ^Ws-JG zGBB9rqBF@sJ;{ze$;wW$!1HX6b8L@u-xGf*b1>vC-o?3qoZ*Mq2gzl3jQl6ae@b-* z=)rv`msF6>=3JS|i_j<6>6065o5!XzNTnT5xhOa5-e&*2T}iOx-QG%YeB6G9zx$N< z0gG7gQr0=0^^9a4y-srso@4);1oR&UyL{VN^$%d`0V{D-be_dj?BM7k41x|1{m%KJd2y&%$A6zO|Wrq09+QbDfAA5?bt z6?by%rJ6g2d(>7xQ!)OexRdlN>e)a4`VN*ms{F@m#ES~etEtL6$W*xqDHkK%(JI{u zBHc+Uorg(c2|4(ky6#u%+Q>UE1+A)!$cCW?xVpenzEuhdT2U zI`LyV=tF*L>Mjmx|A&-|kj{iW{{Q741eIURSSMTZxw9^TlZ2siThlOvMl zC*dZtI7A9LRLWS78kXO{@>^McmqJ~i!)lzt2DZdF%Rj)LaTZ5t(Lt8DpDni!%5N5$ z!XA|k(ixa9RbBfn#Zc3x&y2`7i*<1%k0&0c?w_RYKZ|6RpT+VESbiy|t!jF`o*b>@ z=wi9cSnd#Zv5)Rxn{4M_ZKW?ZvnFF~$-nks5F@Im^tIEUOIy4+#k?RWhyQi<&qwHs z^Drf!4NI9v9v{{!gd8#CNG3-XISR;8f^De67TU3ic8s!JHedyN#(J#dZ`SZrtLdFp z?0qZg;T7!7(rv>J;u{?faZYW|87il^iyYSHXwM0bmqQ#QdtuI=ZbvRx^7yhYVXQ|i z>yS*AOsr);9iknpX~!zI%S!f-<>+Ip45FVF_0r;QPU@ZX=wiIVUi_`%lv%rKgiDZ) z_`S%b=B5R8rUjL81_l}RVxZZdl^}5oodhfmWE?Hf&tzxTK zwq;xHz4vb8UceY^gKfIO^b$e|EtG_kgr1P{3n7ruLV!>LgaBdhcXn6Ukojf?F`9Sl1|D*YScFl8%nS*&UNxDCkp$EB+_orgXt?2SE z406*xAB%Q+hH0yJf;RbNX}xce*7{aywci-6^lQ@!|1K@_@6%HM$yyvRqJ;qqv>;%m z<^^unoWT8>9e6@BEjMVya=&I+UeL6l4>c{=u3_src|Muph9UnhhL;UeOCQpAE+=KWWD`$O*dk3mIm1 zXG)vVZ#8yW5*nZdp`n@^7N=QZ=^6>o*Yxl*O$)Epa744FM09F$M6V`APSRlH4E0AY zP+!z)O^Di|-smIhiMd8yF+bAy*k_RUG%oHxi2XZx0=&E7)n_ZQ0mJ=KUib5P8!6dZ zY_b&p%#HKWjA*NdW1=)AHd#Zl*&2*3(m-6L`r_&}F|Jj;@#EDK->2^QsT!X!N8=Kf zYi#0HbtE2Ed(xF^OTJUB$xo^!G&ZGCohcpaNa;~~>X2GfXR0M_iJH?k zsVV({#$=pQL&j~Y&wK)TQ}tP2A$Hz7#mocU3hvbm@yDCt{>V;J!S!Yj4ByR0k16Oe zF+D)t={Ai|kJi}qWOZa@sV$>Wtr-<+$*5OzW~-Vq$7@X1fEu!?>ay3XHfNuz zb1zp_?k%d!dklF4`4X`^qzbu@I^P8Tm2mt^+Fko_c)x~g3(;c)JqC%9u3R5=WCyD) zCqgYb32Mqo*O;6r_qNL{;YxtEynWDhk%9yl}V53QwrC=q8mE z{Zz%pe@6bLl43ib8JUs0vHuNVo+9nL7!JM{*#h5R3E!WG9>eI-haR29o@y?zXiPz< z>I-63Tacpa!faI)7OJwaLKQ^~DlckRS#hsQi>IihWUh)!R;j4;0u`1WQ$g8{$}4{u zc@_Cw`Q>)ym)W^)cbtoJ2K>vrhy~KV-N+_V^5y6<8$BkYM-Q>mMy%GC2B^B!rpnSN zRg@;GtTaQVrTHo;D^qbPRS)poAgm5tm6&NXHp$efAW=QU7#ADjdQ8Y0){bupi(bG;w?jKfZi_^YDPONI3o<=2NQw?0NW4av%G z$Wm5Ap)wmPl`&?F(#CWuwXshrjnkFfv{*?^o0ZUXk>Z=LRb2CZifw)w`Gog&#W&gc z&aSiA{WN$-CrkT=iAU1T)x0j?^DwFKL~PQDf9ml~DfBI;B|sT1R;9N@D6J(ysjcZs zY0Xn|YnhVT>XgvdruepA#kEgWZ2Lk*w{KKb$00>_T&;+Xdlc6Bg2FpK;=Nsw?M^uZ z#^vB$1SQ)ulfKccL*aGa4B8~rq?hkn(WQE#RERDa)Z~t@}z@yYE&|&vOdy{s-^vvUNG-YHWXe zy7Sr0hMsOP>rjw6bBP7?8HX-ouuD0*{00XN0;`75H&s_?!Dh4sZNv@cB|eR;C= zl_3qX_IE0{e?UR~vt=1rt-ygj3K%#kzkxgCJMa{*@5;abYX$V#9dgBV=efKG7D9!g zAZwxOOOTPpw8;gu2fnL8zangtfj;rvA3p3Q>(oF6O|>CWvJ59Fa5z%|!$tBRu94qx zn|y{R%6oW*JcpObV|b_BhT&JkW@A4@Y3g5*FXT3rY<`MemxFNx>^;lr7gjpgp)6R1 zA9&xzwMO(Q=lh&R@NaaA!bZ0FZVH^|FQ0kA@|+hYkGZjOpKAt|JcLeuZliNzaW2lB zyU4k*W-h$O{84$%!!&xh=4`nCY%rl8>4J|4_Qqe7j z`$7;4;=Rh3z=6}PgiEa?30lEmzaqmq$gH4aTR{M?7;rvtX$1u>KSbg1-DUUF@X1=2 zz;~C}9dcw1eIvNrP<72VVsShD5;7iXKuVAduE%YaLJ$wBz-K{&r-O$vG(B-uEWg5Z-w4917rot@4> zg6$y6A2{w>j{;%d`*-AP$66F~9?Lc`S5W?}!}LiP5r?>r?p3)+;-%mtmSd79MUdRm zn30pN*UPcT<=EpS3GqqvIE5ak(Bm|T(P=u@Q)VK1hVu}dlK`B&p8Fxxml2nj!75JJ zwUc_SzR(#mlfdZ&qvn*9huIRZ0RKuU@M_5ex=xx-!i${!f!qi=xQY09$T zXL5QQ1MY22u6;QK^ldvy6e#%Cdytp74}aY9wbp^Xfcj0LUgN;411tZGlmu2N)`ysRk^9Y@h^O=*HhGxD{HG+NkCB)@Mmu?&_Gh z=zPcv*yLqmsyh@P&2}A#h!vDk%{`97%Q}14|8*ilz+(kb~ z{ldWXA3cNR{QWr3y5?G5cFA{papXLk#GDuMhMdo=d6#&7pBVWFzkEz0_9@BPKL@4H zmLUY+XH@z#jQ5#g<9@Dr2Qv?0)?=7GF=h{lITK`bKa4q#!#tnX>_su>k}h>HrEg(2 z-@tahhEsh7yEA8U{0mn01?=-PSoJ?)-JhWN$1v%CaM$R0q;3e>@9PrAiLnGyn(>w6oH{tzn zXeMT#uRo#3AJOCY=M<%Po?acls%uamr&DHl)Zs^Z6}2G zQMV)d2_49NjvXLBa-0WxCz{{xI62n&L}PQ3tvL_l+Vgby{Cjf{f#8MeSJ>idWm7^a z81S3+5(QQYICoEZPG^1zKDn4XFQSCQSnMF4Jb<;&Uw>ibpRQ>|)6|}lb1L+HM|Tu} zy+Xi?11p1i6oOGn9mY^{J1w9Kj6N_XgE1Y9IiM~EV-@9YqNVKCF23D?cH7Z@D^}dB z-#TXUHp)4(I4bY@fX}e=bGq3Fc)iotIVF8YUi>%vbOP(#pyhO^OY!a!TF_#m-pq22${*=gpAG{*0^Vts zABH%$hF*qlN9j8b$x5_G=>jEFpB!*XsAVaxD6@z#GMc8#~$9j}j(e*MVI!4xvY7dp=X*+(k0jUjJs0%;dEnP>CS zNRU<2f+IE6nyAUvOii*DXuw*oerv7zY|WZr>r}68f_iL2>I#{u@gYkzHe{nZL-(sa z^m4U@-J;g8N7WMkx>_Q>MC{+mL%Ggj{#w$n6AZJ5dA)$o8*`oM;e32FBicxi7Vb#XIs@k|OR2OIePVOTGy%}D8CBy3_q@w$4hynQRniBXPHkrlHI|biNjP+Aj zv{mC`BGnm_sP>o)wZ-PECAL(}u{COnYf@ueryAlWs6Kv*>JsLvHer>j6L+eLWUMmj z22~_Ipz`G3A)l!{#m=i;708dN_YL5lYQPT+uX~X#@a&bOgA34OI(iHcCtWFCYEKMO zOJbOs5@R(cF+~kY*{V+}Qf*R&YLe?!o!q9Xlx|g~45=b@w#rhMt2Ax9O42S?arzk* zrr)o^j9(+4B6bzI`ob1z7qXG`YdNXl9KM@ciVa8&JG0!>m=>t|RGVtk zq5#%FDZf;mmZ++<3{|A%sXV<@W$864&1hCh#yAyc4yY(|M1@&PRgkqsdD#~!H|JXA z}Fz?R>U#-LBiI^EKcfCj~x4%C!?&-$pEQZ5DbAp+^sTw4z5{wx24q ztSZk6S7}z9O0rT_l$EW*>>?HBRH`6njPi3km6zM6+`Q?^$y=SqG6OvZ&|^HY(uB{d3cXd5Z&6Wx zs0#9{~Wrn7kXmWq42t}%bZ05-{SkR=sAXXt*CHUK}n!;OKi$6 ziBwief-*|dlwO*vw9*o#menYwtVPM?-AaNaCsxc;Ld818Rqj`8(#>7)`%P1bM_%Vbk0x`y2b;8UPYt>jVUx^8FC{ft6yIP|TtlQ{8xj=L zkgn*4d_|2ZSHzeGg^%e}SYy9J8)qt{X{BsUyJT&;T)|DZE2#NN!!^6Cjdoo{ zeUBMB21VWpuU`)(S~}gi7iZECZ4%v@(4_+En1?Q@ol72X=Au(nu*wxuYf zEnBv>Vx(5q_BI8#Pf$?D3|TssDX?RQ0y>V#uj3~9c07u_!TT@d-%jR;oCf14c>8BM z&!k;5hj^Ur+>6tXJ{{;*hb|@Dm(>UNLg&aHPuaQx72IW0P*)_9AWL_;0=o+o&|NA2 z?q>OQcgv?|s=Rv^$+KsR+!?zbRuq=X8Ey5Oy8WDnM5e8hu4;Mo47eZ*-Y2VT*Mg&dJVo7;~-J>~kpr2dP{QNnQ0GfL|ka$9XI}w(+wasCfZ>0_t`lV|L?% zJyJTaF^CQE-)+{QfX{UjJYGFWcFRI|4o;vj*i7)NK;D9bi?1lLJmXW!os*cXZz6CYe8a z3PR7Vx#;+Lwe?tfS3Ju^DZ1LOM5PtB=Up0IcF$i`&^(+K45lkDHKKGr6`KSwHbUny( zI&bZX&Yjiz2iIJPSr_7Xh75YVk3BvhLH>|L<50m~oca5GyYUUx#UXY);<{B{_e*8al_>X+`FZkU*6{C;fx*x(Z|E5~XZ_^v_?LTRddJOA#=&n_Q9eC_mJjJ`$J&pdxaL31`iryY>F}*<4&noR^R_J1 zC0u{R7O%iDUs5^cH=ut9rS)LLLCPMc>{*mOpR$)y_G;?2QTM@u?}6*yP3LhZ4f%H6 z3YJ+B@>|_V%|_1xHBa<0XJDLk=|GR^c-+w2uCRK6xOhf3uwuYTql5xu#A8_WQfg~X)iqBTGV3qQ zDZBr6&A*r}UoX0v)+5B{eXcbaw=01*^=+Q3FB~7#*~T zE^R=M^%~Mz^jM7^D`_t)xUv+j7E{6^EVqD~%_BMhNorI{yTn-yQ?^(DIZ$LP*} zOjmLfuU9eboIsz8>FN&3hf;#DS2)&9pwx75@~KN17&Tf>d@NNvI9=fMfisy19RX(n z<*%YA*@~AAY8sXtCUU0WkIDGM%yOC&h=yG9bOiP{M_@6;T*I(?BAVQeA!jeC$#(3r z!Ofq#S;310D^UxTNqq{yDFde#oJLUFu|OAC{Y2?h%AZZyOKCkDxUv`Rj%$M3S@pU- zpdR;MtK0Kqb$i*rlgG>)ObSC-I=mOTnD=|Rwk?X(1G_A@xNCuTpyqhkG~ynu=^n`% z_RP{0&q57(m1~k$tp>cC)bHJ)iQYY$;4`QmpBd`*U7+#4Yc$sH0(JUbst*6_)#iV{ zS_58EYv4y}vDh8biabbHerq;Eavnpy`ST0I?M_mV4WwnuNsH!VlaXLAO$o4Q&_7iD z0kN7GkfPqeY;^|~sw=QU<1KX>YiU-eWvtpQ6V(E*#kogvWT>77B-oJzb4vz)fH^jIBSGD zt?_ENrm4-Es}@_anr)S8vNfpD)~1G#ZqpP_9Rsn13}FX#F^Y%&cy4Uh(OMR}?{%%bM75H*HH zYfM;@>ccZt7oM-$@G@0L)Tk<=S(OpvR1w*)^2iw~jasad=uIk$KBU5!t5gtkxAJ3u zg?ym=IJ*jBopQTbiv#v?IPIZ2{D7>7XD>mI*@ezEAQOm_jzp<3#$R>OR@FpDs46;M z6)~wQkI7b9Op!`sDpeBOpyJpL6~;|aLHw}t;}<9|VZCw^4k$bE3S}kUsm!Ejl#%pz zUcXgVlHDPHp!gU8#sk_fCUF1VKVuAMyxHg^d`q6P5G15f5R%LjoI5kiODK_P$L?|aE zUfC(B%1X^qW@@oA(yEo7-lVkj@k-5@q?C*~O3qxZ#LV4F$hutdS+^-R`{&3zip&05 z@!58+Glo&;lVDy171#~W-)z>Q@P0nJOhu20_^5+eX~1XY#A;rapRzK8m6;i)^voEg zWhN^%D^n?11xn7YP*V07CFYD(Le7BVb7v|Rf)tZ?fui$HC^G*RMdUw$yv6&k6qRpR zG;$sGKLO@pIQ6b>;?b-_F@LH?m&vW>EE1``o?MTZDJ4d73cZzQu1%E*&TAV zN&mq=2o>20$6pV(UIw?GP3kuZJ-SInTd`9uHYvt8nH3&NED2CtiB+*B;fgMaRa8le zB1^LsQCh6+}Up) zYJ))HJ0X*ukhM;TLkGm51K!<12G?QNrPTQ#m^%xW3 zy+E5s*P$R&S78G_k6BK8s*Jj+^j=E`gq@lR6z}M zktDv4z@!$*i+Tfkig<_s_n62Pc zoT5Lb%xKCCzDn}?;Tn{iU2`F$;@Fepnj10amE7q@g6iiwqlBdNUSi{3d~zQH(Y@H> zUL1H26}gAL>Ym>sA8Rgk9lV^b0^BO_vI&`(8>s({lIP8?^6zlXwcP6>K@aE$dvWCa z1M%p5h*`7oln=xSJ$^;f{wxFkbHwNK3&f{p2SqtLai!uyLnyoKk8ehOVK8N*u z1_SyO7WoNm>?3&9hp^E1ao~Fx@Lde_Hca|0IQQr|951=nU_9cQgZS?`5HlC!T#xb} z_{_iIn4hbj^4lr9m$E0po~P*@^mq$B-b9bTz$9OX^}U83e}rTH0cQP*V=u~$nCD(t z<}dmGJ;&UKS^e^aYYxIZ$@jMZp~IK*qE12j2fXUM=<# zpvQCQ@hf=UFW{F?qsNoz@iQ3d<1o}m;Z~2p(jO#P@8{FKlyHw@r;v00!>qwD&mp<` zJRQs&0Ik)rwdr*Q=ywVMD-N6tFp4O@hO(Qn>^MD)9uJ_${rKfR&7$o2l)aR)SHo;K zgSv|*b0OUQBu(ioP3m4j?ic>Bq9zI zP3A-yBWC@DdFt|KaxQ0j#TDwNdEF;B#~O@Vu*F%&IT)#6wE6`&ZdMv>&i-?Z}T%G4w8FGNgy<9ULJBS|Ebp45F{=)GT zs9~4ia)PmClPCGbV z;Pj!v6mVuy_F~?x(-5T$V#xu=DxUi^5r0e|`pxdUQF$!P`8c#2%(6#Pp^Hh&_M^`Z zblHGiR>_yT1%Vfaw__Lju|i1>E;igtRtb~$$gJ`l^W!*G8!L+!B?=N_1y=(B;eXa#mz$S^p|(;rMLcoAU5 zgOUnP4md@$j&iVS!D<4l6Rci!xDBb@ZI)Wym#W2mlbSpZs?p=L8a(e%z2}pv^Lkr# zK3^hshx{1avkYygNCS@`dw9PkmHN}gFTy^vLdfkb9_sfERIis!U0#tI=bfNV?=*FI z=cvu6NUc5w(z9&o$L0)M8`z_(Ot z`8Q%$8FB}h*D|b~Al*1zXr2Ru4dDCBNRj7apJ~`+0DpA_d#gRrqL#oAH3dd#OkkoK z0@GDz$yKeTL^YNwRawTUGN?lpK@(IKG*zWR^Hm(YRz<;kRbV}-eCut>v;JJUwzrjM z`wFouAGsC$tKij_l4|US>u=+AEuR;Yip@m7$)w7?_^X3BX|(yN)*7s8YnUpnv8u2p ztIV3IQd_=CY-K98)vCzWqJofa<%bL@FJz8#LRTp}beA&2PADVn7Nv(juC(wsl^*ex zG9v8C2#5QFcN%_wF=@tLQsFJUuHy58;`7&lNG;HZ+DI>zhgnn-YEyAoqzc30RS=e@ zys#YQh8HU*yh_;-jmnA`r_9I!Wkk+YTGR@qM(tEGNm)|#O-hV@R0%O}C^6xIZ)Ih3P?_8oi557Olkl%+MW6=XDr>X=u6-E0iFDh6$QDMrCicw}%k}{$* zl^&h1w3u?G#xy7;wnNFWeM*X(p~U#5ijUu}xcEyHlWOReib(HPc={BDWh_)^#wLYiTqIlO8Cf$QP*CRYWX<}F&vu7gNu4i&*Y7tp zV4Q0m3S56Cx(uR67yfC%S2e^)F}}&dH%Zxkip>mCbY_U6GNTlcnW*rrbcOL{XjX+n zvKx`{vgHiPnloQPxf_tfvgBQ(z`XkukoO|5AMu&2EthfJoDB@-UZ~;L9_Km~^JnTA zaQ%L$+Bm*%M$c;eRftW}u}OT9mm=~56_#gJXnwdt^5bO7Pn9)4N5KW93M#0VrLYqj zRAA8@`4_E~U(o^i7GEjv;=7S&k@w|O^o@Lr?7E!#Uqsry8*aZDKD`Q_zo3sc0WIl6 zud&#r5u20~C%M=p1)IcFx+$d0Pr;=@3Mvhir8F8zQeat@0?LZzUtTNU@^<-@_sOeb zraUWF$-QEalQ>i`GFOl#RKP7N{w=q1yYpNcvmc4Hd*fu<1XN_6*^4vi+>6tJUFy)K z7+o{5Ndo?ffI3<0d=yY)kzb8XzO|9^u1%0vZH7E+3*=r~CAT`bf1UX;M7<93Tz3IN zE?ox^sfBmfzKg&&YssbhoX;lO0iRz#oi@Qw=I}a|&pljk#x9lEC?Ef%;-47&7J^+Y zt={r!36w_*gGvj7OA8%Y3k|r1z-^(kYr%mnRIp_jS>k-KYzrAdGo+}QY^8~;v55?_ z$*v=2KN7gxW;xfPEP)Em=5>hAW6`C4D%_KMGOf^!~(dR7dY3U zELu!F@;YHYYID63UGlgm8GWLtk`-V1qm#!F$04wepg zfCe{!;sX@azrne&q7M=`5mGh*?mqz?dhI#@_Kqd4btq8MdB_m&$1TMMTrWbO^o97q z?8Bj`0Bqzrn*?VzymA%^#!PH66I+agoLiGJ16$0XbDM!bW?-}#RATySgv@9fq;43J zIQ4Zp!GAFz*&Ta<%$c<2Jd`EtxsBJ}wYY2zZ2`&RyLj{pg(e1auP35WS?Z4XIM<{s zL60Tqv6w_?af)-{<6;`oBK)xkhc2R03wP7#$Q0+_M`i!O!2G#mEsEI-bpAS&fvxn- zNHvm&ByufmGckyGB066-8NnVKvByUA*oYn*iH(g6_!}AgHxd^cnw%Q|&4k-}3S4)B zj*#}b<^^f>CysMbwr}I|PSm66Ox}eLP_>SxT(FlIK*A9V;$haF>_hg;nQR_#z5h-; z5#nP%dK^HH191q0%mF&K{d6+>&4alxtT_O6FLAkt_PP55lGbmv(HtK`+0!Vq`;auo zJd@`L?eJpy0mMQmyN|9vIfjhRhx|}39~FFak~lqu9;az1r}LeE7&whBP7_$CsN|_@ zxCb(Sx!IHRrIvv^f@%}YbCJO)rMxuCiZ}^A-J09zIVhuZAvd_@LPlR5`*Gx4Co(!e za;vBFjFLOi<4%&GJBiOb>Gg4RzR~$iWXtH>%Ma&4M)%@8=^|!Noi``)s~^mTm_0IPO~@PA<1h4I zZ_J}1-v3}*8w zjOt^U&qpw>4`D;^!|mRKahkvGzXQ8|3+Mcm3cQYTe}Z$H^&dveS)gVg$bGJPfd8HY zF>^7&`UZaYB|PFYxZTI9qWosc9tS_2NV${s273G%J^lpa`ae30-#Jb-*aCOmg((h$ zdIGHLFwtGEXQI3bm;V~EwC0OqmBZ^%q*`RWCD)i1HdQ*gT{l&eSJQxB?M_ruQaL65u9<1Sd&oiM)JVSu;7 zb8kV98`0wi*zp-UlWXzG)ikIpx$6`GbUB>c>^(8(e_rZZgK-EkXOWsUAa8ze4#ERG z3s|Ax#DS4c`2{qS3SCcZT#G%f#xGY9A6LLKPiZRUk5K-6`1(@HU#FwmjwKG^mCK2c z8|lU#&|W;Y2hMFy*1f>B{=%HJ`=M+86To zkBiho`C}=+hc2_9T2G<;5z3#Zo!DbLY<(-AHgoqzN-Zkxl7E=wCr?>$C*Ey$D9X5avA}J?3JMIhsk?i_pfb47q@aIm%UYlIy)h z&`WslQ^&41a|*I~eS$9J#|$$!21{4)dMRDoK`%4^0q>JLxB*~VsZ#_v@!+I_kpo5% zNEMm^@1Kqy!)hlgy0An)IKz}b7mbz^xm(nWCA*27F2~6(PZLRh$BW-OPGdImAVdDG z5zZs9j`MnmF8%`2qD|u1*GSJO*t*cEs zf?a0&GN!uuV#grxLcxj#C6PL%Q=eR-p$M!Bu6DfNt81uNgS~d8in&_%> zw5*4aS83^=A$Et{p2Uy{k361%50D+^h&HY*jdlKsY8o~f2y|1Ax4*`@2ZI*|Rt#uK z)F~aTTs62AtIn-bweAh7c5hRaN4F|GCaK(WmP$#yioLe0$m^&Iy{=cj_XEoFenojc zA1lw-?vR@q(yqvnj^+`A4E0+WT2^P0c9D*a!1ssnQ7<;>4DwWye}Ec%tg7`6SG7;9 zs(g}F;hUjy-#nH2mZ-$9TE%`%D)bwx0{?#H`Oi>pz*1!gY*kj^#mWdgqx8U^C@t_e zO0|5fG>cv7$PM71ETkQjIL~6;R7`Gb)_`O?*MRh!bRB=S5GQq3ZrWJCeMRxM zPZ7Hkkn6xdQR;ji&Q7@gdR~|DdCqxjKsxcw7*fP4d{boeRh~6SIo1$mS)-I`O;EZu zO=;E~rP@lAVyjWItwl*8JxU0fs`$`_iVfYUn9#$D3cFU3VfQH_>}5rSf1=26JJ;a; z;2i_|fY}RFOS*|HAqAWTw;e){9(>bAoYa#Jl@YJ`kzUFO4OD8VRVkt2N(zlpVra4w z!ZH;fR;ak}O2vjZDJEjPq9cYB897f8k?R!}bx@&ES1Tmy9@(N_Kt57Pv|XXdl@-qY zNc-TkTS@!YjB!1WhO}o8%GOncABdG2Vx)u^$w_ciO0=I6B7+nc8KRiTNJU2_AZdz< z&QoM`nId8u6b>m2jU7}->>SzR*2)^UU%~NLDk%PLS>m5XKHxoB0&=RxxgTjyvvVEF zDyZs0-p@d%e!d%rj!nc#HSt}#0M%e&Z_XZaD~OkA}I=u&sIo6iEN2= zvL?36n$)kLq*<~guTmgMdO*r4`KR0|zm#W?cX|J{0+Q{Hb7{pa#$b$BB z=dq5(MveHU3f~lBlT2)qkm;d_RDXpe2g#NkDr-tKlBD32Oa-MD%92*Cz_eBcq)(84 z`V9GHtdLK}E_r8MCeMu9<&p6uuWuv&;u>RlvvWVv1yF#E=D9q`Joxo6x=cWi4pP7| z=vj#_`Pd|lb`y(DLUVi+oMn+E(VsF=$LolCZm`vuM=muPqHN7_NkyBX==J zAFxRzHnA0ZDX=h5eg#(f6okvWFjiiLsq!eym3t9^RD=JVAXnvOC2Pn?$1)~=Z<-pL#VlH8u17{Upb35G0VAi zWWemjL6;i7FT^hC=n{**A=o7leZ0ppsE&nScEamA7*smKAj@=Q?KI$a0=Jz`ryXV6 zac=ue3<}q5I|!MA`?r#6w=#S|LP6#Oxz)A_)o$rL&SxgUbqO@c5ELdFI@bLF5>1JvNH)TMVv|MJ~Z+T42_spvQdln2#Rw@X0(n^?BH0E)8fd{+LUE z&z$6USPVZBV}rW*rJ)JAzC^T9As3_yCFHI~(ETzYe@nS?_vX z>ykAjqHEy%YtUmgv9X%LZ8dFVHF2?;Mzo4Hx(WlX;^vh{=!77(%OR>uKXjanvIW&v zZ%0jJkZz=7C;c)e%O#;q;57vCM`Xk#nY+)ET|X3)h|*Se1-s6RO+`wan?lV5s4@D^ zeFPwx`*zyrws#1GZ?t}wbDC%h;WB03p)Y+ z=={q0XTqAfkZbkd`*9r4%+a~IksI;N&E}zv#Kz6U=Ph)!w_uA~2(nwK*v$;C&G0Wiev6&bPdWquChnxSRU88`H=7J z!_m3DGNb3G{t-Q1rOm#^p#Nv$^L5(D8#K1paqw%5U$6ae9f%QgE{Hjk)I1Z#?1w3Y z7uV?DWbL2B9R3M&`2^PV5go*b@R;{$r0>D(-ld_u10#D2M)+5P=M9|r8V>p+4Dz?I z_h0L8-#rV~%)C6{T7z-^Ih^OjU0=g#{-tp662Z!b6_rtbJ!QA)&oGNuVH$sc>AZp- zzlL?agdQ)zsh&fRU%^Cw0jGHye)lti=y6aU#W4@-|KRffa$w)PstPw!|s5>UaQG z9>b;A5lVLxQokTvKXl-pam|06IByNcH!f^52VwT1JnwiOYYb;rp~J?9Cj+O^#-1 z&cU#N6^cb;!APZ6xiIJwtXxI;4V2$X`D5uqd$fZX*+#5xL61%NWrJ2x{#LC)8*@s? z3dc;*V{qtq9A{rFa>)Y3;G3yNGu3&Ut2?;D)#Y7?E%rOsU_^is4@MgL=TgHGtX;)W zQ4gbS2CWl}ZZP__6g?K>mxcU0pF7O%m|56j1WV2!Vy4kbhKWtH_F}3_%rxiybg#F# zJG(&BHJWXbW*U4aw%Dvd>SF^Z3Qs3ck973UMgL+jD#56uWi)})0ZunK{oo8!_FN)% zInlC316Z$*noXpGn?P*#5`8^j8!=DCewZQVc2c2hkrRQ=C5XGxXRB*yTrOWQgJAKY zM1M3miL``tP;#kpF*p_A)DjU*pm%`N1I{4-&LCXZR$E?C82Re)9Rm@*Ri#q2DMrg8Y*B#q@`;>WA~=WElts(VWB|(0FR|j^ zmG1U6LZ3yNaaoph7@mItvLWl-8jxY^(}zvQn?GR&x~tyDPt_hls&ETYsavFq-QrZ_ zmZC!UOy#@hE6<}$IUcpj_H0p>XSXuECM(@*o>INnD#d%BlDtnV(dSMj_&lw6pLZ4S z`=#Rj?79ZbV+`*Hpak2^S*!)lH6XJxTx&q^PY3=Q69VT9@>FqvzY2VVllL+&ec9!M@R(+NrAesQ!Boy!#8F4Cg19<3`>C00)v$j7^>vJ zXe9q*(Hcgkvg8u=UYHJ{=B z;2nV;?jhaUTG_W82#$l&s;-s21q!-=2%%;$GqOnOxmZvOf{_;x=l6Pu|yi%j(nU*B?v@E%$6J+W9D4jwxAj}zX ztPIFf203Jgd6?vb$p7&@I;4NABjE1=b4#~#9m-;4CR~3AZrx20t$bgHF2&d+6Fm}$ zpKxpvT;L)9Jb!uR2FWdl4n8NsOqiKPJ1C2yxkhPzoJS6uM=qVm=#vMD$b}5#l27OU zj(b0K%)^-HBkclnbDwh^%EAHX(GioN>|I=ML6^!7+9Xsd6`RCRy%6Fgu);&$rEr-N z2A2{#v0?_DVmh^A0;ZUTT|!Wo@S~Cm$V>zxTf%5ud^JL*Q1lA&sbe0-u^-7ipLxi+ z4rM+v0~zG=SafON`w}Qp7B)$sT7a8Cx{bu{Y77HQ|pYv$+iiHt~Zd0Gb$u8!vD^ z;B*YxTEj~O8amY3wFj)NGo9;DmJ&L1U3+oH&*HWj*kG9O!7g#ov=HnSh(4b9iNTwo zh4*)3i!N+2p22NAwiw62JB~qc9R3(bOpG%NocQtBg~)d20hb++w05|E8{EIut_#54 zMAKQl*m)-G%q7@h5nrK8CA#DgPKoFkjy@J_<&91xNhpe7Ck=TLJm@hg(77hXEOZ>e z76Wu91NdVA=k=p_KZW(tKKsZLCz3TzfROcmL_O@=LG%bSeJqxv(RG}KADLgGa2M&(y5Nnp^Om3BQ&}hRARSEUxvkqlFHlX=V=d~AUq8XJU8T=%A4KctyKIo?($_ke_)~1jEE=P}L z*kc)Obs2-pGU8$>jd>}Z%@T~ZWSMiZ#UjY`!bcgH{zk>W)h6>?9+JmdNdGo`fK=eN zEF_lqR>a3~7OYD~_vCCp@7mV$g*e@c9$Sfxt@vasaj_L!Y$brUV7x8cU1!8XqBp*d z6TZ@#otTwyowS>9*+UaT&0N=cur|bJblu75nXvzJKhAmL_zvG333Mi?7vqy7bZSSi z#SwET55~RdDEC6@55GW}|I|V-r-Cv5FfqXI^Dm|!;1=5@;Ge(#m9XXXrn#$0ye_7+;SquBUyR0rU)g_L;}I?{At0Za0`?z$&8IB!d%z zseDG~UFcdJb1Y_lW%SuNx9NZE!_m33Lq^w%{DeN_L9>XQ*m#I!mO^W-rQbFyxCE>v&9K`ki zV-Cd31AGCeG0#N#ko^5UvhcUa)L$oy|09|GZ{aX6qsNQr@jM;Xv+${3(osAE8+(d| z`g7Rs<20N{3E+nbqz6E`AIIFw-9Of+-#rJ#U|;!zH5lifhho-Yc*BH(^lNy;3vjAm z!26$sKRgbj_$hikgdWZ_LHj9tGG$Mv?Ae6GBFbNZ3pWxvyL2PW^#%g>I&5(bzrG62 zZRS2s%ee>Th-(eT==_VpHgga!INa%mivz&2ffEBp3gzcgb{S>Y>MVL(k6*5X>0JW@ zyBa2TB~14;dYp2sG+2oRHpAWb!SIgJT+iq*%>E$W*$?M7b02%;JO{(9!C>Ta%)glB zL{GUw?QTcN`+yY$P8b+*l%G!7`RHFp*)^2i=y)c{MXy;^~A_pVs#DnSm`*8a~-_dJSF8)taH8QbgT16fa zSqx4EICZp?X4gKD3H&?Ru|uX6TQuV}6Fp;y&3gP%PcKqOuVYRkGIG1wYRM3H964zA zz?jF?q0e%3G3mlg+Q=07QZoy9Hn1YVi3KMaoD6VsiOgcPphq($HuA24JL=KUtWv2a zJ}dEL1yNf@>nSDTOK5#1^aRD=8@Z7ovO}C(Q$^lxVF1s~N2Elt1W*oOD`A8WCnrx=E&oPSO*|TSWN39Zw6piuCgmhSq)X z>#d}KtKo5rM%RFls`rorv}2Po#7vc!54eF~TEPniH43bF>Xm{PS>P3bRiRXDkwUa3 z5tWI=W;`t@jwp+vjYcyVM$y|w(kn!|eXdA%`b}_;z}@yRv~EIH@_s)0OgHC%m^C2S zq=huKmbfXixGUe!PuX4;Wq4SX<`$|H_h==%Cn(81O$i=oT^^fK4)d~d01ATS7r76R8~L63@|S&be;#hfplkiv2%;~u;W=Uq~rLh z5&BexZ;FYN>>y922Kp({&!TuAt73h^73~|NDBmPS`eiD@uR!7cl?wH5Qb<6zYynec z4Opb0z%9s8Spv^0(DJYXEdPgm!h5@8Khh!i{f-LfIuw(F&M{l%xjq5?I?SJriIWO^ zQ-E(W@lBG|OVL683J(lYSfEXzfe{J`jFZihDyt<|!Im-w1&xsnq4dytnI8@D4x?x7WDVq3}8jJ~%Omu#+`>$v zL_Qn(GV%}PYaONT`@r7X;9Q5Y7@29#V>Qp@<-1mVQ-^QL@J${zNhe+tpw|&G?y`pa zDKIoh{-GiA3yYL*SfYHwGvpm!D9?x*c|^3!EfUfi2?>c>>)fy&MY0)X9^wbri-cc9 zeyt-l&SL?$G&|2jS%{4AeiGNZ(5(d<)k2p_u}K~_NrTSD60f0&?y|)C$uHU>?`WGm zqa)-V9WS>SzKkKbV=-oID^Hiw!TBf9P3_Kg zC<~DpW-ksuAK!=$*rXOcOVK5Vm`$SiNc6C#yDK2YPhLqDxh2wQ5@|e%1aA_CN+OVw zF=BEPLN1*Q$4Y^~rI^L*B+JPpr^zInN$8OHjShjo6WopCo$FBMlX6by{lHi_AG$R2 zeGR%4Vv}_Ah$DVNiC0UWyL_^J<(5guozW_M`qdt~a4eIX1~fk7VdlBynP; zivA^T@+hJMEu`}*K!$XK{#Cw#kuxM;@~?bxD?fv^pKw3V8NO(QtE6@XTp`!(zJRI{K$Sg;4Lq{UlniOOjdQ3x)Ve}ZLjSORpsSJKo3E-&& z(-f4SLgABXpF{MOlOTzMFpB?sQCoed~^8B4k`<&o&$NE{TJ%{}SK*VZXd_o)iz^AJE2;FAS0WE`-(NMA zFdYw89XR>mB!FY3e9zG{P)5 o>sFy7y-E^?UnpbZ$;$bUx%B;^Urh*V!a=Zuen} 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 WZyflCM)-Hjf(h6@?CG8TKKwr`X$#W; literal 0 HcmV?d00001 diff --git a/acrylic/LedMount-X5.cdr b/acrylic/LedMount-X5.cdr new file mode 100755 index 0000000000000000000000000000000000000000..07bd77c5ce2fe02b5d7f12bd69e2e3d0e9d0c2d0 GIT binary patch literal 20080 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 Y=>Tt5Hc;l`1j0$cliE%I4PamZ0JPl(?f?J) literal 0 HcmV?d00001 diff --git a/acrylic/LedMount-X7.cdr b/acrylic/LedMount-X7.cdr new file mode 100755 index 0000000000000000000000000000000000000000..4064982e10c322657b145b836c7b0483329904f8 GIT binary patch literal 22677 zcmZsD19W9g({9X(ZQHh!iJcQ$6Wg{mv6G20v7L!++qRvXdEfu8d%th}XPxeKR$53Kfxy z7MX?pbx1rR;mSaUe%SetWwDA~7`2?;&d_8-u~g<32y(GDBH{fQbT}*_JQp$jzNf9J z3x}Lbog7|M*#XY@#o1WK<+$goscB(W-L5DB7insnqb@UvI0RQ#&PysS?e~aH-?v-f zANNkC6Kk?g7vl$%7y~Eo$F^h{VdMAn{Xa9hO>l>|j#cMY5mN_I>40_9geV zDLAAU6dgkitt-2fiF7Wl!Q8@pkK91kx|clbFlB@ z!!&ZLfBkmz;seuy?<(5G!dc1u5*@B2nt-ij@?e^9Vf80PkI^SR`bF&8_e5~-j!#_9 zCu5`UoxEkvFTtBvOZ|WU6zm4KJlUod3S9U!oWAj``fh4;J&sN6@a*!8=E%@02wGdj z%j=vd1TNs$fTPEvo7|Y8l*;mn28k^0PtJ3rnL$4yD5`yzhCB|DKu%)5*UUvXjI`uh z&@35VnN4bh_jrwCh=0jh5WZ1dO!BpqZf^Xe#92@gPy(;;U<}5u^BqszE6HZ&RWrs+ zDV99#8Ls-t3EchD%N^jhiE>O>AK~6eH1Ch=I5tYqMgF}8yb_$sI@degCV$`(N629k zTN4Be>9w3_ru<41v~x!wYQ%Td?cq520mDmj0zOwBjR%eDXs zEdIham`f~Q@FT8pFEOtk58i80@CwU39WgV&##P8uaYU+i3e?d|E&ezomm0)Yd%?SM z=)1K6T%RGv`6{S}7u=)Zhp6k+LZFk*TPbk>-_m>q9i#5hkOi-R%y*PcG&>tSH=M$; zPH7`eE^-ucD;?UHI>^}mCsJl?<_sA18g?=WEdv$q8rS}g z%3)q5MGJLo{hWYob8o`EJyy1cqMdMyR%(`8&_oO5q_G@!M|{=I8;SR3UM0QCsJX_Z z(CYD|tQT}+_fOVSB@LGUL=|-a0A9v()uAvmCQP)3@ zOTV*Gx*}_7bPBKBL@S7#^F9Po6*xX^IMmF}E42FE#ji=v^dOV1N#ATt1|#Xu7!N4< zVrK)c0Uk=GV$k_M`$6}tVv}>wOS{And}9b?!_#bm9L&+DTikhRH^zP4LY`&6n&z}s zJa1(z()mM7>yqJIi?A00T}qv;?K;hpWU!CRKIBwMY7$HG%B?t`67PJX^f zU*5Du=DfRnhF)HJw_+%*L8E=7Z2I2JXVS_F&*3kc!tfSE9)pDv3h?G15a8s0K>jDM z{poF7Ir-wVRbU_>od4!EYXe6o69)x@A0~gv?e+2V)0Z3q0s`>^()g34I|r&j!(SaN z%-Js$G7Qg;6DUl?j}s&;!ymKY0-Oc37u*FR1k&T%w`iAd-^3g-F`408hVI6HU!Qg< z)=e%=SYixmBkJz~}AUJ}Uar;Zp#=eGnJ z=Iz&vTL!VrL>O9vbB^+Ptv2VVoOH@Ge;awS9itz>4FaWP$I}CD<;^YvEy6DX94CM^ zjix?hBlMsXq(a4OI*~#L`qkSa3)NxyJwzjxr3G91_t! z}U^MjaRtL(FXpB4>5a{7R z8k#ssYwxTJN%>%nKYdHwAqPGuM;XwgO~WSytRkBJ98T4 zVcR>G;-Mc=_>aWkePXzMk~bO;-yY|U6n*b^_pIkI0%4bL`xZ6|PP{I~Sn^-r%;)z> z7N7X$bVb=;oklTs3lmji!s2|04$w>zCnL)&Z-_-?`GcJWL_42E(XIDw9l+!!dU_41 zBhzS2Yq}o@swb`CEV&Jh@Q(lFQ4AnQVi5@FU5B4LofJvkmZ}ay(3VrvvRqroY$LqU zn4gsRYiJNhxARD)p*`$ z$JWr&FHpaSCplJ$@QYde9AG;JRIo|Hml2Gta z#8wpF;XH&c5d~i0mEdk@qF`ZR#Wc6E%vvzdv zCequ-pCGJKPqIX#INrDfJaZGt<{h*RO~aPk4&OnsD6sG{)CR~rJZ{aXFns&O(`O;{d0&_TgFGW~ZNmrg9fj{Y1n~H&TZf|xeOL!=) z8QhHe$CoX^nc+3RXKUVA_QoVW9{0Y9?sy0loV0FUZ?-+SwP&VPPMIdgMj8=UPaNLr zQRW-XkU)W)(#d?x1n-se=Y5xE-(kfGuWc5c(KWHeeT?D_ErcesP;p zUrvDPyUsKGG|t)CDxf~nz7DSzC2{nNzidu^wNlEN2Orn>Bp9J_Tkpxq*HbIm`xX>5 z+r1DFRQwj`ymX1J`&1AI^6*yXv+TId;xfvON(H{~?DbZRRB&ZifU2%HjQFUl&Le8Bjm1N}deq*M4sV&9&6_vXQaao{4byn9m zYcN(6)wPK4s)3uIhrSy>pAkti@<4`RJ#NrP`m!P<7r1ct%TG~d{eyPjF^)AK&NJ$V zifqd*Et(2+S)~9#$fLMyQv0R%2Xvtn&k(Q>A++cOW)uvr~`R`5StBVBl$jfb! zvHFEMDVhzODAR3`@(hQx@FdiD7EcUn;4wUK;eEqDzzPc(m#!vOdzmwAT=%=Jk75v zXbE4drN~s5PaPWY*mk~2G$pTfvgLHYr$Gs435G2L17Iu63sR_9FLe}0T$JmDmJ!9u zna=gSt{~78lA6hrAde4my&mRrKTkae@zyjUX|ywBHe-MxU87Q)%_3OC?JKV3TH~0D zZhEjc*QY$XrL3C(hQ)qtI0!hgtIx!u#xUF~?=x6`Rt&4Y;7GSM1fFOO zz`(yhSJSYCh2v2#mlRlwulL^BNf<`Zlw-Eod9Q~-70M7q$`L6SM5~ul_#2Sak>6FU zk1^MkWar0TT>vEw)E+{oI=K-lVpwx3LK)c?R*Cgg+=B`fp{l_yY*LyHhEb{E=qlzy zfadQiIu)uN+^e|EhJk+;H$GT@Qfl6$3+07P>hXz@mZjS;|D&TK+Aox{PB(+T;JwvR zYXLE|vVsrJ2VAkFxwOR*s+@d_lc8ouRDiM(dvYYTkx&wZiUF9p;-(_AAt1iBGw{tQ zO>bUBacb;b$$RjL<7h?0zF~fFT(-any|5&n+NUP{hO4Y-A-3pC1fQzf|Ae9_gUWik zUPWcPQiK5SJ$osVIw~Yo2Mx$Twmuk>7@e{{;i~h_uJO6Y!+8cc06(CT4SpevA7%tZjOS<3yE zXr|er;z|)|hjs5|R5?cEFJ>rGOep6UG#er?W%aoyrg`I;%YC~kQC~XuqZPlI<{|t( zeZ@W)Q*9#fF%2$m7c~!M_a`<(q1-F7ht_OJE8t$3!Vvuu4E>lESdWkb(|_37kivb4({ROCA9*WHHerOd<6(# z>dTtH}s`~(CH))NFBGe5fuZ@Fgi?7~X>y&@T(zk|+AzB$rYf%5#Q2PQh zTdOEU4gaM^beN}5%{P>*j$r_St)!z!5b2HkZ+XI1`O^ie0{saul*F#munoP^q5s6Ym8OT{lfkJ?_Oz(&?y z^f&07Q@*I@g}bMy$Rez;>Wdvll)(#gN3@!6JR25K%L=yWf~l##T>F*bTWrB)RNHK1 zX0sU9H8+$Gx9Jv%NxmciS*mx%2Ur!huW0y{4Z5LJa_HBDnv>rNs;gXbiTJN8F9h$l zS>x*WpI=U1V*bI`2QL@O2k#5utxe#vAm7lxCUc);et8Y_5^tL>_%Y_MP3@sUi>O~| z^%YKEs5#Gsm5C6|_gj>iCb0Qj5*^*L{VoR1giS;12!%|4YUvl^_As$^m^p_rwA4unD|3*PF#`iRLvm5=p+D0tF#K?IuC> zd@Os%=HLtUg^+;@Hnw#aHl?;4HC+J`<7i12Ym&la{@f1)|2c2HqviRD`!%H}{wkRN zHMRe4Ze=24?&$P)UN0?4E6FQwZ zTbwa1 zy%3K{e^woCPuL!p^2c@XyBgYinC#88%%jw@*LeXC5#2tsK|e3uy#SrvoiCVa+;?k$ zmi=WPXsw!35&@btK2=T~{`+Sdk;&2JTJRg?We3OS=aWVLlu4a)M{s6ut8>hWs13aw z_Pe#wN@%xUamqlpS#@b%6L``Q&DXXgJCCdY<*lH~5S(JHlELtgGC%+flnSFE&c+N5Q+MDS;_IL}c z7z^fr$=-RcGOV|C2RFVX_Ra}AQ7j!jl%n>igIdCGlVrATT`QL5d#8!^d_sp-`mPzh z-cW-&&1`lf-4yk|-pVQW5BQY<+Cy!yy%Bz0*4;|9+v!gXy z`Hzt|nu~l8quRz>58@bPD*zyl;N~IBs0&2PT#`7GFM#@ zzPJ4DeSek=eN~paqloFy$3M069q6BW*BCQNrr3TY4tA4Y9bTZ&&bmZxS(Mo^UQ4(e zZl=Hq%k~<(h@jZb=1rA)H1@DMN^VuRG7s-hjs{6Ks#&UKjcIHjG%==I+^OET!EJ0O z(VvzXOnzrE8%3ihv6M^?r%Pk0=_l6L;6c&CADB(Xg8rrT2E8NS}T@e2JMPtr7KaYq+shOI#G4G&pTjLQOwUXrq(;S8Hm^ z5;6;h)&?o}OB1C0Y$*6)BrV6@m^}{v%>DJ55MrFU$8m8_;cO+{3O-Ot41M>$_BWvX^ zI=(NHk(Hz9>LO}P3cIzV`j;FW>8z)dgKX@R^`)($8-F8L<5K=fR)Mvq+Gnm!jzqU= zvG|iL3@qIRuH|A?K=7RaN#i&|7RQYt%3sZDjzn7GL^e4}QB*W7* zw%Zibnf!%!IEHTVY^nBp_sviY-FSxiDA$)};m(HA@hDmm;I!lvjcXgiS_5suO;*kZ zk(!o-q#*`K7rM%nOWU?>8 zGslC;2|iXDg!(NfgXpg=E48tsLz*8;F?2|9OYvm-l2+Zxx6$?cz+V#D=Y!~y$*nXf z^-C>#k|oFMO{l(Fy%wVAiZg0Ve){cevNUqKOeeqpRoED#QM6Hi)DT!&3ARz&tdI`j zE0_xPIU22&qUn}F&_8Xg!p-yPzJI}RY|)#X&2Hr`((TXzrfVZ>RsUKo z#-N|pfuKcyQB3z&Zfz}|megvENw!~MC!SW3(^N9<*R@=0{&YXMt4(+f6a{+kob{zY zi|hC2C#LA`vzBfQC>lj!$M%gW8uxJX=;r?#?Fyyk!xKce3r35ivovF$+W6M}m5z=v z`lERyOU$a>hFk%3u`x5rK^IeWaO+Dm3(<6%z@x`DR!n%sbeE1_nH0Udbn|L&6^>jj zn%$ioNMSx2`z1Ku0YzBPJqlJhDnaHzH{u7?Pw&3^Ap_5aV8b#ifn){6bShgRifSv+ZKV zs&m_EwrBRCE4R{THaid)A~?&_bOsV#M9-^;$My23M+%1An;*X zb58R>xxCpobID-1dLCYo7tlZ{Ula8>`bT0hokuoG2E;xs2r z*OUm0(kFf2D%VaypEeG|D@!PBp5h-1TT=M5)1O{mEYcSoNM6`!Psv_tGfkf__n;1B;{7l`wa&T_=hD(T9SX6YO6k34>idzuKmR@>Bl-pf7+{&4%1ol&jMx{qCu4MzSi817s7FeCFQ(3t3_qf>@4FWM>xEjhG z3Jd;+eEh9N(MITAKc9nB87Ujv{mY97c&_}m>foP0ir1;G+jmf6!#zsd*FQs7UEHbW zBq2#|*UA4tg^f^2CZvU1?c>wb$*{McwQr3E2#<{3I$aUc(neP;Y&PS8a@kOGOZCC; zIHaeiTUgGnHlr_EmIA?ZZKN>RiC_2k93`gt84BpP98SvwZXUb2o0meZX%C&I>vS|f zQl6&RKu){G7I6x^GQ5xG?YtUM2O!)hNfAvPlQHrmB91K;_xt@5 zldZa^``4tcx=>k_xv}V_s(7<8_lo!yn8F_w#M~g9p`YXs)vq4LlqMqm-zh~~*!7QZ zvXORiz1bLb2<)a>m)B+=YI#!l@ynWYm@}-)}FYfxUu9%w(u1&u*ykFXfl8&vuW#s|(c`huQ=K7sqlG8L16& z?}?glbamheH*-f*?0GDuXnDPcSW8iVoL=fjvWeJZEvO6CQzm3Rgw-TaVm0clXNNRRk%f5pI zz3%yPJFeA1K&&aUGkhX@io4+D!GS4_`!+#m)-y^10m8XCY;FK<~X`QY}BArExk z{n6fOB(7#&kpup&7X1D`T7C-SJ5q+bxM$WJB&%7v<09DQMr{pq(H^JVem9SV2%4ni zPX-X1Ggtip4%>s$2pHQC0#t5<Pfp5uUyOB;hO0MfCaOLvUv4*a z23zSh{Y-Bex~&r#_*WC14R+H@14TZvYs*^P4?rG#rU-6ESi4+Q}JWI z(`QI3&G=)(WR$jWa&ozuk^DJ5Be-XdJ>8^eO%6>f|9MDU~~k1^1c0_#l9g+&Qu~}qp37HQFGeKU?av!8w+g~ zpAps&R&R9_lTcJd!VIc>rox4HJ>Nr&KOr%z!%HoR3RNErEG>lT7rg%j^Bz8Zq=V02 zg4mfnwWu^#x&kn}YWyoz8p&+A=y9yQS}XAD@Ish{1zV`{@ftIQeSOUFG+wVFf=l^2 zWND!o$mFOwhf;ZmJ{xqFv=tPpjWVNP3|Ec}zW%ox$cf~06rlujTes6Rp_5>=a$883 zd$S()p}LXSdFPquEez5~j)}%qZpCZz*XXs8y=7 zfo}wZO!DlK>K(f=ww`DY@S+{SR^4)Ej>@KY5qC-T16xlj)L2M7exTi_2c54E`>^g- z73zum`@#_ZP4Ig_QMdY8v>6EHr0#cV|b{bY)LMiEwj{Kn+9prd+=i0M*mo@nI_;*abc=JVm`Z z5v`mH?m~QOzqhtvu}I0nBB>92B>kamna|wnY(^DCpqQ^+pY^I-Q9Ec2`DH_2FH91) z6gn{=CpWN8&Vqf)?*2>_5-|Mm@SyJkbwv}IzdO3oA?=05?e^Yiuwqs^f4{l#dc@qD zcD+Efc=9uQ5;Uhjg?oqpoMf>UNE1BgB|jV#hzwD61-LETGF(>TMN@jg0wW$vUKlab0j5;+K)n%AK6FW$uoa(dJcx; zW$jah>@A^fE}HQwN*5HWtTW@le0pt;Lni4KSaob>QubYpnTts>vDPMh7*;GRbE#;QiA`w-*0PY&TZ zlwSKi_WJj930AF+c!%h$`JSqdNTv!EujT;wl9Q9OQ<^Bl_3wI*aT!sT!E_iV#;wmy z>c*|oo#A1eAVD=P_S-TSCQNy%Os`Ds+?gJXe(ADTo!&)H&nD3y#r;wg2Mqj1a}|IbaG}En(aV&+40c)~B;5z@h%IYp>E7T1%jL z)kw1>6ssbQEL7HH@%hXoj9%SNjyKW` z3&@^eK0P?mco~Eb8{G5EzGAaHl_#CAH2I-ir}ijB+nm3DcxatTJ=ZhC5Xl?!o2PYf zGU@Szw@-cycZdm#!8F{7_hAiV|HT)$$JP^h=W|!#^h78L*mmbL8N1Bgz5TN;!$(-_ z?ufd~z=L~d7hNKw2rgN6?B~CZfrK1#6{s;gMKXGxyx5#D{B-g2<3&nEsS3wcDM76Q!(((p?~nBfbw`OiWEr|<^K;o1DsaD^Prd6mK6CL>3(Hrd z@6(H$o157$%!d`-Jjs`%BQs@jt*xy~AXj(a4$KD~UF6d#g=VlSpDuB~2e2vo`210u znp)$az2ekvrE2fgJTsl6Y;)50?6^FT4-v$p?b>}ndy+)u$i2~=cHLgmYEOth+Q?0c zm|Vv^kjV;Ix%TSQR1^yiItQtGBH`c|yVRtpCnY*Wh6og@mVQ=GO)X%`$!+#WATPWW z@XFN#a)-)Ko%^Hx7G|${JZw&9rr!NV~-LzTh8 z+~e}F=*#t1wzM+`6mS|SH-NI~rUsDgm-K#BZm*B|zzvIvj!t@+d7Llv-;@y-dZ|{j zR%u->Tb4R>AGVv4lyH<_r@GAO^Bj+WfjNg`9TP3{75~#?Rx0w&n)u*-yG% zom~^;hAjpfJch}2cox54~*0ce{fs{z6e^6y+4AT&|m9X^4?OIsQZI`Ru zk^HD?m(35R6a5pK){}`))Y&;~O==ujh?!|)fmtFy@3vlVl5u_gSWV+TFwa8QIt-=h zNyHHb23KeqhAiLQb_@KJ#u;sU?*g@pz}jHLJ1+rg2$s=BN%q)hRcBfT56<>Ox+%#E zYC^BhhUoWE&01h&`l-8+V%ku~@X3khw5k*l&Y`5K$(Sftn^1Sc6#@V-KvjMViy+p* zU7pg0ztBth85iitn0RWg-=oV@mA5q)@i=&LauQobDijGXV^czEwfZM#z!6kgE#7vc zeR%^HXosjV=KJQ90*Jc|I0qWCRpZh?EL6{6mX1yhj#y;|YJ{^;`RkL)pP1f!sp3|w zTBq<({I2+CL~c1sw9^6<;{IPfo)WIE?v?eEJGowtU6v{B1Z``Fz=qb;tOjK0T#IUe~QY#GUN{82; z*QFxUO_fehTH;I3n@_$F7O zki;(E#8gw0tw;w4CtOiiR~J+ok+VBTpor#`RiTS)w06Uv^bpO(4O4;fP52k}G1?#@ z`jwxCF%9ckQ7)l(G|fFT{v@@#43&H`N_J9`vuK$j*Pn@C-(=Z&2mLGUWiC`&(VJ|= z(wHKcfDzkFi%ju$?Z&sASDy%WDvPa9xZl=D^v6T)kgA`Diy0BmA1eh~t;Xrh+g=C< zgh8Ezpl4#gt9Ku?fZW#STZ=WyY;NBK{%dz+3J6((<7->w0~rYD>-+y!g8n@t_|Gbk zJ7?nQ=ip_{A|e@;<+KB-v;k_mVxzI-@DQ?Oo=g!llL0fg#)ocCZlo zv!VAW3qj*uVBN{0TBAlku61Yi2-<8KN|Q3tR*2e=C>u;qO zHbPf7bC(-PZ>_J7WT|)G+GV_FWAI)r7S*F;(Mpl!_f*L6rjNc$)2Q^( zUeEn>=gKQ6J2@v2m-{*PJt}OoOh(3cvV-qt8HDt>&s1!oH@yEqo&91AvUv|jUC;+< zWV{ebZcZS3aImF;m;C|NJHB>?NgLr#FmTTO1*ho-RqV{*`lWn-!NbN^kYKc&2DbCj z%yU_9Q^HsuSDq_M>=G6Zo485)9^|o6&w6xhZ9iCEo%el6ZcZgr-4c&~bqg`z`)Uqb zrppb~!AELN*iz%{6xEH)6^^(k3TrFfdjjpAm2{uHuNSN3)tv&YP)%7KK>W(BD61H%GCb=qyw?DIXV!!&M^%7m*A%EGmX~%cAt!@F}Don}rKO*g~7_4#d5yr;rY#W8;*nrKaz)^$wq)oEP{T-fp+O%6OMQf9~N z`x=4?c{^qS;rTK$Qf!TpU9&Q?(fbf!?{2Z7>`N&>vN+lFN!feC>UF|h-UT5W92sm@DR3-a?nvD+Qk z4h0$BGQ75(mNI$E&TPvNT59g_8$~hDHREzRQt0(C3!bG}j=(_8nX{>f*y7aGGj@6C z5R=!|N(2Z+iFNL-kN3TOZ);#==j$)@d%VjfrXRVx+Lpgc^9zm+Fju*%b^0j}nnhn+ zr)*1x0sCSKf|UdgzQVopF(Ghoqt50;N-B6gC~sSm%!WZ{;?M0W9 zkz;ud-UvvGNL#vdn@S(^NjXo(8LYZu^U7Ha4eeJDBZ|p(4bjz}?mlwjc1#R>An)KH zO+#4yNEHj6wXbmtKj53i>2Z;i8rz@ zlEy1nbt4*KcR(67e&XG|Q`Gkgm5`;x2@+tWQ$;&zgiY*ahmcGImTk2Tl^Z z-LaFCIf>Nm@=+r@qpxFmurjmb@i+uL-+zy^H&jSWARtP4*vebcv%q>TBhURnpYwLt zO<=>wDicDS7bjlbsvBlbywe_w3VtR)M%y#4(M z&MPVP)Co??u0>v1|Bb>0Oo9VMX7#WNi(vC^m_43-P5v)=kQ6G zM(4e2e9>3RG>MdSe~;IJc!SpU2*$)hc&Cc;jt6LmKjh z(WS(ZTHb;u+CPSgUDBG3D0w$Wn(kNBj2UZmcq_VusZ0YbHMK5fV`=V#4%C#usRR0n ztfZ{9`E!2NCGq}!;NV9mr354k3yUZIN~PtPdseDld02fhuTLE>@vhlbW0#3ol4t)| zQx1YT{lMvW9_W1?B=Y<>6l4Sq@O$age7_FQnD!`?bwUS)0r*|^;3Oj-oX-U;<2tIF zEd%eDzGipwv?14N45m%BfZ2Db!Oyb9c+?Im|5i*4CB7#KyFoP2Ha;aMAuII`DqU}D zePUg_e&*V$Z)hdQOBMW!Mf5fSb@CY$8qnQy`r~~L?)sFEG$iLHET|P$pxb82A)fKK zoyv}y#b&ay11U`R#DJ^14P2AzqiYM}KJilhja{^YUT|deVsEd^tbIuiByw`V3rD^x z_^3@On%k_aSkD-Ttp@c72tNT!+>F$1_~noJeiZEOf%QtSqL-YX12uB3hD7vWE%NdEiPWFmb#jucJBLscr2JeuUqlD#ujI!wf1BCUl-rU!c1_3iP#MS zDN4|}E$M1TLaK!KeU&7#Z;qrl(^w-78xClv!VDnMwsm zA#B5`KZr@$Pt5WBIz^ACv;|*33kC{WCX#vE?~`_8qq{w*FQ;Y@C9DCKx5^pt*b9kN z%hlC*OWEAo{$wwb3Ub&ia#y8$@53cPkhi;OOrS}lWt8|Lo;zO{)=DKcl6kkt7JRIC zhi0dm49>16r|h}^IcRO~g>ZF$k2dzLw7e_^XW90F@sU_}VoeyeS~D~=E8-eY_{6&+ z@@ntyFxvmFW7Xg+Ev>cur4BA!+B>OIOcxJ>UZ=GWr3_=0dP@4Lr&neCV}U&W?q@>^ z=a0>rpWMPY8jH3x;;gHy` z2U0CGd!!xpL(*r=Qu?B$M=d z;5}9}-Z={`xZXVkL|T9Z1Pldo(5MDq;?rU&)`ok52khli#?koO{l+5U`7UGzM%zcm zmw|@F^}MJXk(RTSr3_zjb>#4P zSVKOsh{nvwioN(eR0{oi{<&uVZtY88{xQ7W?JGau$!e7Vb7jTGzm;%#j`6v?x|$HK0{8#4#(JJi zfwQ30{l2=K{fx-4iZ|QB=x3tmDNDCY6AxjMc2^v}8Zk-hZ1(;s`1YWr@X3v$X*SgV zy+1eP&Od@C%Vz-dKr2h7k5^O!p!lBVRC*TE2`A+g4Llb+VC?CzTvuo5Q#bwuKp`=? zl%kX19~c-Y@hb?>{Ma+jfa2S48u52+^9#YdQLo=i&`EAcl5U3vX!L#jP z$)|Om|2C;uS!*{z3pEgbyI>pxb90z=Mb`s8I6eg<|M4C_1?P?%6c1-LIvkTI#|&f( z|K?L_rxDi=7A|YkD^=G$cdU0+OQ(t-=8~=w`rFM(w%X~F{NB$s*l7v-K0$o*eUo^- z)zgU8*|J&NM=)19FrPo8L-I&bxwRazXPjUK9Fm7;8)_a#{)*gA6i+r*s2&D;BHspR zGo69#*8%$WADX8~WFI|w=`jnjJ!?m*=j`8z8DeF&g$f(XBehu0;omoZ;h~`Ho@S`L zbQyRa9}cIAqDQi+IY3=MtO1`-D}K+RC8cWf3gsr7$mB*=a6}uJA9v{|B{da zdcS1yp`a69!SZrH`n%!z=Hs04Ew+VE!el}@UGIR9O-Fh3rzTiZV;=X30A=!cVfR85iFH2$Iq^zEZ? zH^r+M^AbJRuTVsyWRF?6oIaw3WWwq+%im_8N2k5Ns}d#9u6Kxsjxw{qgOL0wnU|qr zSS8O+r@si`KQ*uC^W$d?3Sf-f;uHpz1A|yd3(^Mx!Jis|=i=nlPgSi-Cela@gvf6b z3LyY_wtMcBS~dt>wc&wD8~bB1v9k?F!lPtx^1F@wW&e7^ULq0l~!!o_=hHzYrdYjPkR_o{NPmlG%RqhJixdTHJu>@ zl~n&66e2iNj8iiUmM#lV-J~r&5`>FH>8dfASx*u7Nh%2WMgUw(PA?Zhl9S(J@##+7kJWR}|$I*1S?>7pO*pa}$Uk&(LUU>Z~2w%m>*2>m_;h&n`&DzQ&MhL!#@f+BsL^~Nlwbw8(Ct<-Gp{y*L z9m+6M*ayB62=$%uxkr7QKFbfG)Yx&!<6p9Pj`C41nU(tJ5S&tck}|#9ViaQHXKWkh zraKbUOn%SBngdOSmytNF%C5h1!6&m}{h!%rlurdT_a97?O@m!_ijjF|xoz$(cf#Y+xUYvxgF%3R(7x1_6;lzSla%|;;AG`&a2CrFFSLM%2ztW!8J_ zi4YE980j@;+bHaO1cf6c%Um*Rq=yG|BIDNaeqC0+cb^H#*BWO%wLO&RB+Wu6G^M7Y$R?OQO%+}eJO|HRMI z5A?(M3%4I%MFk25RwhnPCV%0ptEn0qSEQ7tqn;R>tOGF5u_)9w?e5o7 zNsLL-QAq+M7{+C40JYT;tgLL(ObcvM%q$CRl5+J^4U8;o(`;-~GIC6;vdm0UYzj(4 z(qpm>0Ec0D`f=HD8bv5S%wGivtO)lJt7vN#1xU{ohgkuEiql;O2lqlwbfvNJ{R4}}+bq9dxi zYwQkFD&*pOW7}~or1C!a-ynJ~<3uU@deuOk^Cr6WEHS+cZzo?I#9IK}M#rHSdPz*Hle1DcKOm(NCs z*v64`gN)${{C_$*@1Ul(u8q^1ln|tc5(NaLNs}%mG%28BqivlYrk%%XtuIS^<@YHSQHSmm+&*_C+T zsFV;Rv=C&2R{SIh=vQ5C+hbMmHf!IWxfkmP+D%0lwDRBG@$pnJ)ui= z+r|-2GxiL!vwU9?Zl7fc;0K zgjuG{ye~pX0~;jDrTt~ZEQh4(%9hPW`nAr&=!r3{k|pU> z-V>wbp)Nn#9CrCjhVyq|MyoDvD(vD9;b}1^4ckf5df~8!e%0hnX7Di5l-W;|IKeSO*-GfjotA~%idBNu zsiGnmxDfFqRJAUJobPe-^Oam_uN&mmj_qCsP!#hMBavJY5 z6)tAG7uDJJ)b?2=Di!06S?@*3qMTB=3q!5nR0D5I!^iIHfZxx99!S|}ev40iq2CM4 ztD~-L9rAKEj^Y=d5fGn zm{yx3%~lwT{OoY}oOs)mM(qx+Cq+0y!P>pcn?|xMI4Rk4_UOZh?Dl<*Zd|mxW;+xW zdNkFwU}ID9aTf7GRUiMIg+98UBGY>2D1@i`(9>Xi<(8_i{AinH8fOP;aM}#|>X?A4^rxFb{w&>6`NVuo^d!j>S{d*VcuQ6FyfO^ z=@m`tV-HFa>ZZkYn2T1QCgC;~BMfHNLo-Pthn?Pj_r2kdQ!vS(?{MR-EFASf z;s-|q`BK(%({N8DKS_(KAA%!ly!pdk%`k9UjnssP)F~o@PAcqqEPL*yFX@r&`C!M( zU^O0+k;C`#A;T&+)^5q!7P8g=shDc;6>^$rVCv}cLFqPlZ_Q51J3Zi%?X);w1lVzh_N%VdxZ+BL++KR3W;w3KmU+7a?XRbRV& z$w+K>N%Av?|2S0)tG=#?eJVY|12`gR(L|SD>7m2NrtEwAs2m<!`dJqxB*{yI0CneW<;BGaj_F{|2c6@6cMnEN~_jI&wM|`dMCNUU| zl=Sqf&~smdmDN8>rS%%f_1YPphp`62KD(3keQ=6gi4V5CTH-4lNn-l&GKcnS-NkLY z>hffX{o6dTDL=)SgW%4&acYodq$1Fj_2Dr$gGqs18OHzNY@Z|`afjoMe)>qQNQX#noKh_z)1DP;>LUDUJLD2o^BL#9UVy=cMfMM#^=NRO5)Hqx5ue z9#B}iBgB}~#;5K4Rc=GS!RiSVr{$W-ks(+mis>f@?N7S4L-M8!Za|l_||4d@KF9kpm_v@IEtlS;YoMZ zXz%CI5IUYTUE}xJMV;sgD)l*A4ZSaRp+t+HjAQCsdZD}%!C!nj{gn8+MPJ%^No)2i zX2Zag*RPjv3GVDSAb%_dHqAF5->y*t!NUOE=+gp1_S=^YPXq?N`;V=nf+xs{(C*@I z@8o!nPP?-<*8Mm=oxi)~!#y)O*K1`dE!#ZdZ~-DM7XkV*V{uY{D_<)$d(uW?DaR*? zFI)_I04+`IReG%z2UK|~zUu@Tro1Op*PLFFj!^!YnL*~u;G_3bT5fL2A3$1!*z%TY zVobvi>~Uon29kSoKME0iM^4>E&0wMlB(TikkZdJTPpWWFQB<(Xi$Cb6B8T+cu#L|I z^yh2$;|C@qG>1`*@J5q%{^JPC36H#|ZvhKW89NQuD(#`#8ddZFkn&GA(CYLMpFX(R zK;5gP&TESQ{&f>pbBRu=ky`f~-@&nxB!Rm^J4b;MsRWNkRlk)0=v4RtO=;G2`FqLM{u?KoFMYjo3I@oGP6Hrl-HOQBC9mJMhbd)% z<}Gjpl}Jm$J%fu5<-RmY?2bTv->e5%S5PtfZnZjEp6*>xwO1AyLBZ(`(a)pHKl#UI zwL#IX1?yaFkMkR(X=RUmn#BC);z9Gpdl4Ox$FwZ-JmK_>WhsRmueBcujF*CWFbl*} z!EcB8?zN(v4GS((Rok%oW-`#NVyv6r@o3dL4Doe?+Xu@$Rwx4@oJ@ zl4;)W;?XyMt|K4Xb@MI@v=Ibpcsq2yT=ab|?1_L9lP(AcMYny#z~hhPL6o-(Kfq8a z*>Y&Ka=2DmuZY6iK50uq91azv>lizeqJ(N@3CM7~QNKaGwP3B@xy12Cdz9iMe7=J9 zm-q|Mbe#h4GXyEQ4y_FV^w`)kY|=;1lf5+Hb|7ZGFK#fAZp9~L>M zLWBW;9tH#YP?9Q!-p#!N&M49y?To1lJ8w#AWX+cj+|g6bnMiHoO>Nah zIYc9Q78~0nT6S4b#XZZlz5KVj4M-?zsq>U+4zwdQqx3mxcJGC1`BKpMEGnr>Rx>42 zzFFeU4l6Wm8nN!d7x^IW8|3X5_~j7KH)T~fe|F(e@m*jx2(VRh<$-PzbnR^{SG-}! zXb!0i6wa!Nd`Do`chU73B6;twmGRvNhm??fR|E03t*Ecn40pp7G<*2Dx@n^8J#MK@ zK`gFm(>(==H=3*w(JUTrpHe@#LCwdLUmU8(aaF2ZF8tjDKXnvQTXr2NzZYW6;_YzL zn!6SJY2B2!XRO3J{v^R9p8IMnW%T|_tKtOkQ0k8SN{}!^XPY$A1x+&UhZ~P z1i6x-3-6rczzetzISZr@72GK<1_*5+YE((s>+ z?P$5}+^TTCAVcaPBuzWG!pw`{rfJ#e_rz)5<;T?;^FLS64}r!#NJ<;mJ=z<9<(XT{ z&AKcvUQ)*BetAif&=ZsSN?nOWT>di50q%c{9Z?Kqg}~D&UH>Dv>HaR zJ)PX~B27r+4JS+yX2iSmlFB>*%;6GZ(Wzj2bb?5+uNoXr8n(^8vcyZ!?B6dpDh`(@I@)it-CII~n!csCB=u z=L?)*^m0>o%4C%2ZMYRlyUYNojl3(q=)gUa+DI zJJ41Vj^Cw@_@hh@re@x%-o7pp+whi}Y-cN&K3`eId3|~M12|8=_^xD{e`dwzQrzX2 zu%Gy6mjR5&?vd9qn|(3N``1yDKcb1FowI|-|Fh-SQ5)14g7pq))a#Q`xQ*6o=~UG( zSNHY~^zRR7^cxP>FXNrt#Vh~7li@pZpiZS+{Dq6xwzlK5O`Ov?9U^;uFM7_K zY2y{W6ra3sbh0}vPFNqHOj|hlJId*W%A7%!!RJZMN0yJDR*47 zxm7=~#u=qD8s12oQM!xRjW8I)e-E&5y7OdGu9RYu4Sxd1U?sTtDS0Dh>}#1MXW`%$ z;*;XfJbv87^g4#LVvhZl2gek;YbT)7M=S&Nh~v+K*5+CoxOn`(gqpv$qU68~GWP4= z#*}0@?7zRp#Td0A8!kyrX2ZDW&7FV*_F_Qs$ot5L=x7FPO8cEjDIA z{@*;#YPi@Gp#sm}cjSCLpUhbm7Mo(JfN`Y$MU(w6l(TzMY)X?F){tTEP_Z%2ga0IR zKAunJY|X>Qv}s{s{!~D0Mys9I?*Tg>&oj;zJZuKHHWuU8|Nl? Date: Sat, 14 Mar 2015 18:10:48 -0700 Subject: [PATCH 319/332] Remove those files which aren't used for the LEDgames project --- BeagleBone-setup.md | 84 - README.md | 121 - Setup.md | 166 - brackets/flat-bracket.scad | 42 - brackets/flat-bracket.svg | 573 -- brackets/matrix-bracket.scad | 32 - brackets/octoscroller.scad | 134 - default.config | 65 - pcb/LEDscape pin assignments.csv | 33 - pcb/LEDscape.brd | 8462 ------------------------------ pcb/LEDscape.lbr | 1089 ---- pcb/LEDscape.sch | 7234 ------------------------- pcb/TODO | 14 - pcb/datasheets/10118074.pdf | Bin 196965 -> 0 bytes pcb/datasheets/MAX3040_.pdf | Bin 251328 -> 0 bytes pcb/flat-20mm.scad | 59 - pcb/octoscroller.brd | 2228 -------- pcb/octoscroller.sch | 3660 ------------- pcb/receiver-4x.brd | 1567 ------ pcb/receiver-4x.sch | 6471 ----------------------- pcb/receiver.brd | 6490 ----------------------- pcb/receiver.sch | 8072 ---------------------------- radials.config | 2 - strips.config | 2 - tall-cylinder.config | 65 - 25 files changed, 46665 deletions(-) delete mode 100644 BeagleBone-setup.md delete mode 100644 README.md delete mode 100644 Setup.md delete mode 100644 brackets/flat-bracket.scad delete mode 100644 brackets/flat-bracket.svg delete mode 100644 brackets/matrix-bracket.scad delete mode 100644 brackets/octoscroller.scad delete mode 100644 default.config delete mode 100644 pcb/LEDscape pin assignments.csv delete mode 100644 pcb/LEDscape.brd delete mode 100644 pcb/LEDscape.lbr delete mode 100644 pcb/LEDscape.sch delete mode 100644 pcb/TODO delete mode 100644 pcb/datasheets/10118074.pdf delete mode 100644 pcb/datasheets/MAX3040_.pdf delete mode 100644 pcb/flat-20mm.scad delete mode 100644 pcb/octoscroller.brd delete mode 100644 pcb/octoscroller.sch delete mode 100644 pcb/receiver-4x.brd delete mode 100644 pcb/receiver-4x.sch delete mode 100644 pcb/receiver.brd delete mode 100644 pcb/receiver.sch delete mode 100644 radials.config delete mode 100644 strips.config delete mode 100644 tall-cylinder.config diff --git a/BeagleBone-setup.md b/BeagleBone-setup.md deleted file mode 100644 index 5abe3fd5..00000000 --- a/BeagleBone-setup.md +++ /dev/null @@ -1,84 +0,0 @@ -Building --------- - -* SSL install is broken; [disable certs](http://derekmolloy.ie/fixing-git-and-curl-certificates-problem-on-beaglebone-blac/): - - git config --global http.sslVerify false - -* Checkout LEDscape and build both PRU and teensy LEDscape code. - - git clone https://osresearch@github.com/osresearch/LEDscape - cd LEDscape - make - - -Teensy config -------------- - -* Code is in [LEDscape/VideoDisplay](https://github.com/osresearch/LEDscape/VideoDisplay/) -* Update `LED_WIDTH` to have the maximum length of the strips -* Rebuild and flash to all teensys (do this on the laptop) - -* Find the teensy serial IDs with the `find-serial` tool in LEDscape: - - root@beaglebone:~/LEDscape# ./find-serial - /dev/ttyACM0: 8998 - /dev/ttyACM1: 14401 - /dev/ttyACM2: 14389 - /dev/ttyACM3: 8987 - -* Update `config.txt`. At the minimum it needs the first line with the -maximum strip length and the UDP port number, and four lines for the -teensy serial IDs and their X-offset in the image buffer. It is ok -to have teensys that are not in use with this BBB so that the same -config file can be used with all of them. - - 9999 # UDP port - 64,210 # Image width x height - 14401,0 - 14389,8 - 8987,16,1:9,0:8 - 8998,24 - -* If there are any bad pixels, they go on the line with that ID. In the -above example, there are two bad pixels, both on the same teensy. -Pixel #9 on strip #1 and pixel #8 on strip #0 are marked as "bad" and -will not be set to anything other than black. Bad pixels are -measured from the start of the strip, not the image. - -* Run `teensy-rx-udp` on the BeagleBone. It should report opening all -four serial ports and querying them to find out their configured pixel -lengths (which *must match the config file*): - - root@beaglebone:~/LEDscape# ./teensy-udp-rx config.txt - 8987: bad 1:9 - 8987: bad 0:8 - /dev/ttyACM0: ID 8998 width 10 - /dev/ttyACM1: ID 14401 width 10 - /dev/ttyACM2: ID 14389 width 10 - /dev/ttyACM3: ID 8987 width 10 - -* If a device is cleanly unplugged and replugged, it should report: - - teensy_open:286: /dev/ttyACM1: read failed: Resource temporarily unavailable - main:508: /dev/ttyACM1: write failed: No such device - /dev/ttyACM1: ID 14401 width 10 - -USB problems ------------- - -* USB devices don't show up when the teensy is not plugged in during startup. -* Clean disconnect from HUB is OK. -* Power kill to the teensys and reconnect is not: - - [ 243.372796] musb_stage0_irq 496: bogus host RESUME (b_peripheral) - -* power management seems to just hose the port. -* but.... `lsusb -v` seems to bring them back? -* Solution: - - while true; do - lsusb -v > /dev/null - sleep 5 - done - diff --git a/README.md b/README.md deleted file mode 100644 index fc88e6d8..00000000 --- a/README.md +++ /dev/null @@ -1,121 +0,0 @@ -![Octoscroller Interface board](http://farm6.staticflickr.com/5349/10218235983_c55d247088.jpg) - -DANGER! -======= - -This code works with the PRU units on the Beagle Bone and can easily -cause *hard crashes*. It is still being debugged and developed. -Be careful hot-plugging things into the headers -- it is possible to -damage the pin drivers and cause problems in the ARM, especially if -there are +5V signals involved. - - -Overview -======== - -The WS281x LED chips are built like shift registers and make for very -easy LED strip construction. The signals are duty-cycle modulated, -with a 0 measuring 250 ns long and a 1 being 600 ns long, and 1250 ns -between bits. Since this doesn't map to normal SPI hardware and requires -an 800 KHz bit clock, it is typically handled with a dedicated microcontroller -or DMA hardware on something like the Teensy 3. - -However, the TI AM335x ARM Cortex-A8 in the BeagleBone Black has two -programmable "microcontrollers" built into the CPU that can handle realtime -tasks and also access the ARM's memory. This allows things that -might have been delegated to external devices to be handled without -any additional hardware, and without the overhead of clocking data out -the USB port. - -The frames are stored in memory as a series of 4-byte pixels in the -order GRBA, packed in strip-major order. This means that it looks -like this in RAM: - - S0P0 S1P0 S2P0 ... S31P0 S0P1 S1P1 ... S31P1 S0P2 S1P2 ... S31P2 - -This way length of the strip can be variable, although the memory used -will depend on the length of the longest strip. 4 * 32 * longest strip -bytes are required per frame buffer. The maximum frame rate also depends -on the length of th elongest strip. - - -API -=== - - defines the API. The sample rgb-test program pulses -the first three LEDs in red, green and blue. The key components are: - - ledscape_t * ledscape_init(unsigned num_pixels) - ledscape_frame_t * ledscape_frame(ledscape_t*, unsigned frame_num); - ledscape_draw(ledscape_t*, unsigned frame_num); - unsigned ledscape_wait(ledscape_t*) - -You can double buffer like this: - - const int num_pixels = 256; - ledscape_t * const leds = ledscape_init(num_pixels); - - unsigned i = 0; - while (1) - { - // Alternate frame buffers on each draw command - const unsigned frame_num = i++ % 2; - ledscape_frame_t * const frame - = ledscape_frame(leds, frame_num); - - render(frame); - - // wait for the previous frame to finish; - ledscape_wait(leds); - ledscape_draw(leds, frame_num); - } - - ledscape_close(leds); - -The 24-bit RGB data to be displayed is laid out with BRGA format, -since that is how it will be translated during the clock out from the PRU. -The frame buffer is stored as a "strip-major" array of pixels. - - typedef struct { - uint8_t b; - uint8_t r; - uint8_t g; - uint8_t a; - } __attribute__((__packed__)) ledscape_pixel_t; - - typedef struct { - ledscape_pixel_t strip[32]; - } __attribute__((__packed__)) ledscape_frame_t; - - -Low level API -============= - -If you want to poke at the PRU directly, there is a command structure -shared in PRU DRAM that holds a pointer to the current frame buffer, -the length in pixels, a command byte and a response byte. -Once the PRU has cleared the command byte you are free to re-write the -dma address or number of pixels. - - typedef struct - { - // in the DDR shared with the PRU - const uintptr_t pixels_dma; - - // Length in pixels of the longest LED strip. - unsigned num_pixels; - - // write 1 to start, 0xFF to abort. will be cleared when started - volatile unsigned command; - - // will have a non-zero response written when done - volatile unsigned response; - } __attribute__((__packed__)) ws281x_command_t; - -LED Strips -========== - -![Testing LEDscape](http://farm4.staticflickr.com/3834/9378678019_b706c55635_z.jpg) - -* http://www.adafruit.com/products/1138 -* http://www.adafruit.com/datasheets/WS2811.pdf diff --git a/Setup.md b/Setup.md deleted file mode 100644 index ae054102..00000000 --- a/Setup.md +++ /dev/null @@ -1,166 +0,0 @@ -# Getting Started - -This is a quick introduction on how to set up LEDscape on a Debian-based image - -# Setting up the BBB environment - -To develop for LEDscape on a Debian environment, Start by copying the latest BBB image to an SD card. These instructions were made using version bone-debian-7.5-2014-05-14-2gb.img. The latest version can be found at: - - http://elinux.org/BeagleBoardDebian#Demo_Image - -First, we need to expand the image to use the whole SD card. By default, it is only 2GB. - - cd /opt/scripts/tools/ - sudo ./grow_partition.sh - sudo reboot - -Next, update the the Debian environment: - - sudo apt-get update - sudo apt-get install usbmount - sudo apt-get install git build-essential - -Disable the HDMI output: - -If you are using a Debian image from 2014.8.13 or newer, do this: - - sudo sed -i 's/#cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN/cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN'/g /boot/uEnv.txt - sudo reboot - -If you are using an older Debian image, do this: - - sudo sed -i 's/#cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN/cape_disable=capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN'/g /boot/uboot/uEnv.txt - sudo reboot - -Otherwise, modify the uEnv boot file to disable HDMI and HDMIN overlays, then reboot. - -# Next, set up LEDscape: - -Use git to download the repository: - - cd /opt - sudo git clone http://github.com/osresearch/LEDscape.git - cd LEDscape - sudo make - -Copy the device tree file into place, and add it to the slots: - - sudo cp dts/CAPE-BONE-OCTO-00A0.dtbo /lib/firmware - echo 'CAPE-BONE-OCTO' | sudo tee -a /sys/devices/bone_capemgr.*/slots - -Then run the identification program to test if all is well: - - sudo bin/identify - -# Make a configuration file for your screen - -The configuration file is what tells LEDscape how to draw it's virtual screen onto your matrix tiles or LED strips. There are two basic formats: - -## Matrix screen - -Let's look at a sample matrix configuration. Here's one for a small display consisting of 4 LED matricies, arranged in a square: - - matrix16 - 0,6 N 0,0 - 0,7 N 32,0 - 1,6 N 0,16 - 2,7 N 32,16 - -The first line of the configuration file describes the type of matrix. Here are the valid matrix types: - -| Type | Description | -| ------------- |:-------------:| -| matrix16 | 32x16 LED matrix, 1/8th scanning (three address pins) | - -Each following line consists of three sets of information: Controller position, Rotation, and LEDscape virtual screen offset. - -The controller position consists of two values. The first is the output channel. This corresponds to the physical output that the matrix is plugged into on the board. There are 8 outputs available on the OCTOscroller shield. The second is the position in the output chain. This one is a little more tricky, as it is backwards from you might expect. The *first* matrix panel in the chain, which is the one connected to the OCTOscroller shield, is called 7. The second one is called 6, and so on, until the eighth and final one. For example, a single matrix panel connected to output #3 has the following controller position: - - 3,7 - -The rotation is any one of the following values: N, U, L, R. 'N' and 'U' are used when the long side of the panel is parallel to the ground, and 'L' and 'R' are used when it is perpendicular. Try one, then the other, to figure out the correct orientation for your panels. - -The Virtual screen offset is the top-left position in the LEDscape virtual screen that will be drawn to this matrix panel. Normally you will want to map sections of the screen into contigouos regions, so the top-left panel in your display should have a virtual screen offset of 0,0, then the panel to the right of that one should be offset by the width of the first panel, either 16,0 or 32,0, and so on. - - -## WS2812 strips - -Let's look at a sample WS2812 strip configuration. Here's one that can control a single strip output: - - ws2812 - 64,48 - -The first line of the configuration file describes the type of matrix. Here are the valid matrix types: - -| Type | Description | -| ------------- |:-------------:| -| ws2812 | Strip of WS2812/WS2812B LEDs, aka NeoPixels | - -TODO: What do the next numbers here mean? - -## Testing your configuration - -For matricies, there is a handy identification program to draw some text that identifies each panel. Run it to test your new configuration: - - sudo bin/identify myconfig.config - - -# Set up the UDP listener to display incoming packets - -To run the matrix listener: - - sudo bin/matrix-udp-rx -W 256 -H 32 -c sign.config & - -Or for WS2812B strips: - - sudo bin/matrix-udp-rx -W 256 -H 32 -c strips.config & - -There are a bunch of command line arguments, and the whole thing seems to be in a bit of flux. Here's what exists now: - -| Argument | Description | Default | -| ------------- |:-------------:| -----:| -| -v | Verbose mode | | -| -n | Skip LEDscape initialization | | -| -c | Configuration file to use. Note: Use full pathname, for example: /home/debian/LEDscape/default.config | | -| -t | Number of seconds the display server will show the previous image before timing out | 60 | -| -W | LEDscape virtual screen width | 256 | -| -H | LEDscape virtual screen height | 128 | -| -m | Message to display at startup | | - - -# Run the UDP listener automatically at system boot - -There's a handy script for starting LEDscape at boot. It should listen on the ethernet interface on port 9999 automatically. - -## Ubuntu - -Ubuntu appears to use upstart. Do this: - - sudo cp ubuntu/ledscape.conf /etc/init - sudo start ledscape - -## Debian / Angstrom - -Debian and Angstrom appear to be able to use systemd. Do this: - - sudo cp bin/ledscape.service /etc/systemd/system - sudo systemctl enable ledscape.service - -Extra: for video playback - - sudo cp bin/videoplayer.service /etc/systemd/system - sudo systemctl enable videoplayer.service - - -Video playback -============== - -Playing a video is as simple as running the video player (after running the UDP listener): - - bin/video_player -s 256x32 -l ../Daft\ Punk\ -\ Around\ The\ World.avi - -Note: These packages used to be required, but now are included in the default Debian image. You might need to install them if you're using a different system. - - sudo apt-get install libavformat-dev x264 v4l-utils ffmpeg - sudo apt-get install libcv2.3 libcvaux2.3 libhighgui2.3 python-opencv opencv-doc libcv-dev libcvaux-dev libhighgui-dev - diff --git a/brackets/flat-bracket.scad b/brackets/flat-bracket.scad deleted file mode 100644 index d273806b..00000000 --- a/brackets/flat-bracket.scad +++ /dev/null @@ -1,42 +0,0 @@ -/** \file - * mounting bracket for 15mm extrusion. - */ - - -module bracket() -{ - translate([0,0,-3]) linear_extrude(height=3) - polygon([[0,0], [8,0], [8,3], [3,15], [0,15]]); - - cube([8,3,8]); - translate([0,0,-10]) cube([3,15,8]); - -} - -/* -translate([15/2,0,3/2]) render() difference() { - cube([15,10,3], center=true); - translate([7.5/2,1,-2]) cylinder(r=4/2, h=5, $fs=1); - translate([-7.5,1,3]) rotate([0,90,0]) cylinder(r=4,h=4); -} - -translate([0,0,10/2]) rotate([0,90,0]) render() difference() { - cube([10,10,3], center=true); - translate([1,1,-2]) cylinder(r=4/2, h=5, $fs=1); -} -*/ - - -module right() -{ -render() difference() -{ - bracket(); - translate([2.5,4,8/2]) rotate([90,0,0]) cylinder(r=3.8/2, h=5, $fs=1); - translate([-1,7.5,-10+4]) rotate([0,90,0]) cylinder(r=4/2, h=5, $fs=1); -} -} - -right(); - -translate([0,0,20]) scale([1,1,-1]) right(); diff --git a/brackets/flat-bracket.svg b/brackets/flat-bracket.svg deleted file mode 100644 index cd3a9139..00000000 --- a/brackets/flat-bracket.svg +++ /dev/null @@ -1,573 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - trmm.net - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - trmm.net - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - trmm.net - - - diff --git a/brackets/matrix-bracket.scad b/brackets/matrix-bracket.scad deleted file mode 100644 index 2306a779..00000000 --- a/brackets/matrix-bracket.scad +++ /dev/null @@ -1,32 +0,0 @@ -/** \file - * Bracket to hold a 16x2 LED panel in an Octoscroller configuration. - */ - -module bracket_half() -{ - render() difference() - { - cube([18,7,10]); - - translate([13,10,5]) - rotate([90,0,0]) - cylinder(r=2, h=20, $fs=1); - } -} - -module bracket() -{ - rotate([0,0,+45/2]) bracket_half(); - rotate([0,0,-45/2-180]) translate([0,-7,0]) bracket_half(); -} - -for (i = [0:1]) -{ - translate([i*35,0,0]) { - for (j = [0:7]) { - translate([0,10*j,0]) bracket(); - } - } -} - -%translate([0,0,-1]) cube([200,200,2], center=true); diff --git a/brackets/octoscroller.scad b/brackets/octoscroller.scad deleted file mode 100644 index 9d2ad124..00000000 --- a/brackets/octoscroller.scad +++ /dev/null @@ -1,134 +0,0 @@ -/** \file - * 3D printed brackets for N sided LED matrix displays. - * - * Horizontal or vertical connections are possible. - * The spacing between the holes differs for each. - */ -sides = 32; - -// horizontal has 13 mm from edge to center of hole. -module horizontal_bracket() -{ - rotate([0,0,-360/sides/2]) - render() difference() { - translate([-20,0,]) cube([20,6,10]); - translate([-13,15,5]) rotate([90,0,0]) cylinder(r=3,h=20); - } - - rotate([0,0,+360/sides/2]) - render() difference() { - translate([0,0,]) cube([20,6,10]); - translate([13,15,5]) rotate([90,0,0]) cylinder(r=3,h=20); - } -} - -// vertical has only 10mm -module vertical_bracket(depth) -{ - rotate([0,0,-360/sides/2]) - render() difference() { - translate([-16,0,]) cube([16,depth,10]); - translate([-10,1+depth,5]) rotate([90,0,0]) cylinder(r=3/2+0.4,h=depth+2, $fs=1); - } - - rotate([0,0,+360/sides/2]) - render() difference() { - translate([0,0,]) cube([16,depth,10]); - translate([10,1+depth,5]) rotate([90,0,0]) cylinder(r=3/2+0.4,h=depth+2, $fs=1); - } -} - -// combo bracket has only 10mm, with 13*2 mm spacing -module vertical_bracket2() -{ - rotate([0,0,-360/sides/2]) - render() difference() { - translate([-16,0,]) cube([16,8,26+5+5]); - translate([-10,15,5]) rotate([90,0,0]) cylinder(r=3.5/2,h=20, $fs=1); - translate([-10,15,26+5]) rotate([90,0,0]) cylinder(r=3.5/2,h=20, $fs=1); - } - - rotate([0,0,+360/sides/2]) - render() difference() { - translate([0,0,]) cube([16,8,26+5+5]); - translate([10,15,5]) rotate([90,0,0]) cylinder(r=3.5/2,h=20, $fs=1); - translate([10,15,26+5]) rotate([90,0,0]) cylinder(r=3.5/2,h=20, $fs=1); - } - - translate([-7,3.5,0]) cube([14,5,26+5+5]); -} - - -// bracket 3 has the normal vertical bracket, with an additional -// bit to secure the 15mm extrusion. -module vertical_bracket3() -{ - vertical_bracket(12); - - render() difference() { - union() { - rotate([0,0,+360/sides/2]) translate([0,0,9.9]) cube([16,12,13+5+15-10]); - rotate([0,0,-360/sides/2]) translate([-16,0,10]) cube([16,12,13+5+15-10]); - } - - // subtract the extrusion - translate([-15/2,-10,5+13]) cube([15,50,25]); - - // m3 screw holes to secure the extrusion to the bracket - translate([+18,7,13+15/2+5]) rotate([0,90,180]) union() { - cylinder(r=3/2+0.4, h=12, $fs=1); - cylinder(r=6/2+0.4, h=4, $fs=1); - } - translate([-18,7,13+15/2+5]) rotate([0,90,0]) union() { - cylinder(r=3/2+0.4, h=12, $fs=1); - cylinder(r=6/2+0.4, h=4, $fs=1); - } - } -} - - -// the T-bracket is for securing the center struts -module t_bracket() -{ - render() difference() - { - translate([0,0,5/2]) - union() { - intersection() { - rotate([0,0,45]) cube([50,50,5], center=true); - cube([50,50,5], center=true); - } - rotate([0,0,0]) translate([0,0,10]) cube([21,50,20], center=true); - rotate([0,0,90]) translate([0,0,10]) cube([21,50,20], center=true); - rotate([0,0,45]) translate([0,0,10]) cube([35,35,20], center=true); - } - - translate([0,0,20/2+5]) rotate([0,0,90]) cube([100,15,20], center=true); - translate([0,0,20/2+5]) rotate([0,0,0]) cube([100,15,20], center=true); - - // and the screw holes - translate([-20,+20,15/2+5]) rotate([0,90,0]) cylinder(r=3/2+0.4, h=40, $fs=1); - translate([-20,-20,15/2+5]) rotate([0,90,0]) cylinder(r=3/2+0.4, h=40, $fs=1); - translate([-20,-20,15/2+5]) rotate([0,90,90]) cylinder(r=3/2+0.4, h=40, $fs=1); - translate([+20,-20,15/2+5]) rotate([0,90,90]) cylinder(r=3/2+0.4, h=40, $fs=1); - } - -} - - -if (0) -{ -for (i = [0:3]) -{ - for (j = [0:3]) - { - translate([i*15, j*37,0]) - rotate([0,0,90]) - vertical_bracket2(); - } -} -} else { - //vertical_bracket2(); - //vertical_bracket3(); - t_bracket(); -} diff --git a/default.config b/default.config deleted file mode 100644 index 8b00ac5c..00000000 --- a/default.config +++ /dev/null @@ -1,65 +0,0 @@ -matrix16 -0,0 N 0,0 -0,1 N 32,0 -0,2 N 64,0 -0,3 N 96,0 -0,4 N 128,0 -0,5 N 160,0 -0,6 N 192,0 -0,7 N 224,0 -1,0 N 0,16 -1,1 N 32,16 -1,2 N 64,16 -1,3 N 96,16 -1,4 N 128,16 -1,5 N 160,16 -1,6 N 192,16 -1,7 N 224,16 -2,0 N 0,32 -2,1 N 32,32 -2,2 N 64,32 -2,3 N 96,32 -2,4 N 128,32 -2,5 N 160,32 -2,6 N 192,32 -2,7 N 224,32 -3,0 N 0,48 -3,1 N 32,48 -3,2 N 64,48 -3,3 N 96,48 -3,4 N 128,48 -3,5 N 160,48 -3,6 N 192,48 -3,7 N 224,48 -4,0 N 0,64 -4,1 N 32,64 -4,2 N 64,64 -4,3 N 96,64 -4,4 N 128,64 -4,5 N 160,64 -4,6 N 192,64 -4,7 N 224,64 -5,0 N 0,80 -5,1 N 32,80 -5,2 N 64,80 -5,3 N 96,80 -5,4 N 128,80 -5,5 N 160,80 -5,6 N 192,80 -5,7 N 224,80 -6,0 N 0,96 -6,1 N 32,96 -6,2 N 64,96 -6,3 N 96,96 -6,4 N 128,96 -6,5 N 160,96 -6,6 N 192,96 -6,7 N 224,96 -7,0 N 0,112 -7,1 N 32,112 -7,2 N 64,112 -7,3 N 96,112 -7,4 N 128,112 -7,5 N 160,112 -7,6 N 192,112 -7,7 N 224,112 diff --git a/pcb/LEDscape pin assignments.csv b/pcb/LEDscape pin assignments.csv deleted file mode 100644 index 8f2b7c07..00000000 --- a/pcb/LEDscape pin assignments.csv +++ /dev/null @@ -1,33 +0,0 @@ -Signal,Header/Pin,Port -S00,P8-18,GPIO2_01 -S01,P8-17,GPIO0_27 -S02,P8-15,GPIO1_15 -S03,P8-16,GPIO1_14 -S04,P8-14,GPIO0_26 -S05,P8-13,GPIO0_23 -S06,P8-11,GPIO1_13 -S07,P8-12,GPIO1_12 -S08,P8-10,GPIO2_04 -S09,P8-09,GPIO2_05 -S10,P8-07,GPIO2_02 -S11,P8-08,GPIO2_03 -S12,P9-41,GPIO0_20 -S13,P9-30,GPIO3_16 -S14,P9-27,GPIO3_19 -S15,P9-26,GPIO0_14 -S16,P9-25,GPIO3_21 -S17,P9-24,GPIO0_15 -S18,P9-23,GPIO1_17 -S19,P9-22,GPIO0_02 -S20,P9-21,GPIO0_03 -S21,P8-27,GPIO2_22 -S22,P8-28,GPIO2_24 -S23,P9-18,GPIO0_04 -S24,P9-17,GPIO0_05 -S25,P9-16,GPIO1_19 -S26,P9-15,GPIO1_16 -S27,P9-14,GPIO1_18 -S28,P9-13,GPIO0_31 -S29,P9-12,GPIO1_28 -S30,P9-11,GPIO0_30 -S31,P8-26,GPIO1_29 diff --git a/pcb/LEDscape.brd b/pcb/LEDscape.brd deleted file mode 100644 index f61a9e2a..00000000 --- a/pcb/LEDscape.brd +++ /dev/null @@ -1,8462 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -LEDscape - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -By Matt Mets -and Trammell Hudson -LEDscape Transmitter -Rev B 2014-08-01 -- + -+ - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Maxim Components</b><p> - -<author>Created by librarian@cadsoft.de</author> - - -<b>Thin Shrink Small Outline Plastic 16</b><p> -http://www.maxim-ic.com .. MAX3223-MAX3243.pdf - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE ->NAME ->VALUE -P8 -P9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - - - -<h3>SparkFun Electronics' preferred foot prints</h3> -In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> -We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. -<br><br> -<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - -Library of parts that we use for our Blinkiverse designs. Some parts copied (and modified) from the excellent Sparkfun libraries. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>EAGLE Design Rules</b> -<p> -Die Standard-Design-Rules sind so gewählt, dass sie für -die meisten Anwendungen passen. Sollte ihre Platine -besondere Anforderungen haben, treffen Sie die erforderlichen -Einstellungen hier und speichern die Design Rules unter -einem neuen Namen ab. -<b>Laen's PCB Order Design Rules</b> -<p> -Please make sure your boards conform to these design rules. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Since Version 6.2.2 text objects can contain more than one line, -which will not be processed correctly with this version. - - - diff --git a/pcb/LEDscape.lbr b/pcb/LEDscape.lbr deleted file mode 100644 index a7bdef6e..00000000 --- a/pcb/LEDscape.lbr +++ /dev/null @@ -1,1089 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE ->NAME ->VALUE -P8 -P9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -P8 -P9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->VALUE ->NAME - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Should match A3 pinout - but not completely tested - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Header 3</b> -Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08232 with associated crimp pins and housings. - - - - - - - - - - - - - - - - - - - - diff --git a/pcb/LEDscape.sch b/pcb/LEDscape.sch deleted file mode 100644 index 6cb90296..00000000 --- a/pcb/LEDscape.sch +++ /dev/null @@ -1,7234 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Maxim Components</b><p> - -<author>Created by librarian@cadsoft.de</author> - - -<b>Thin Shrink Small Outline Plastic 16</b><p> -http://www.maxim-ic.com .. MAX3223-MAX3243.pdf - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - -<b>Small Outline Package</b> .150 SIOC<p> -Source: http://www.maxim-ic.com/package_drawings/21-0041B.pdf - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->VALUE ->NAME - - - - - - - - - - - - - - - - - - -<b>Small Outline Package</b> .300 SIOC<p> -Source: http://www.maxim-ic.com/cgi-bin/packages?pkg=16%2FSOIC%2E300&Type=Max - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->VALUE ->NAME - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -Z -Y -Z -Y -Z -Y -Z -Y - - - - - - - - - - - - - - - - - - - - -<b>±10kV ESD-Protected, Quad 5V RS-485/RS-422 Transmitters</b><p> -Source: www.maxim-ic.com .. MAX3040-MAX3045.pdf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Supply Symbols</b><p> - GND, VCC, 0V, +5V, -5V, etc.<p> - Please keep in mind, that these devices are necessary for the - automatic wiring of the supply signals.<p> - The pin name defined in the symbol is identical to the net which is to be wired automatically.<p> - In this library the device names are the same as the pin names of the symbols, therefore the correct signal names appear next to the supply symbols in the schematic.<p> - <author>Created by librarian@cadsoft.de</author> - - - - - - ->VALUE - - - - ->VALUE - - - - - -<b>SUPPLY SYMBOL</b> - - - - - - - - - - - - -<b>SUPPLY SYMBOL</b> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE ->NAME ->VALUE -P8 -P9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -P8 -P9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Should match A3 pinout - but not completely tested - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 2.4 x 4.4 mm - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 2.5 x 5 mm - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 3 x 5 mm - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 4 x 5 mm - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 5 x 5 mm - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 6 x 5 mm - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm + 5 mm, outline 2.4 x 7 mm - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 + 5 mm, outline 2.5 x 7.5 mm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 + 5 mm, outline 3.5 x 7.5 mm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 + 5 mm, outline 4.5 x 7.5 mm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 + 5 mm, outline 5.5 x 7.5 mm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 2.4 x 4.4 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 2.5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 4.5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 3 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 5.5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 7.5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -Horizontal, grid 5 mm, outline 7.5 x 7.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>CAPACITOR</b><p> -grid 7.5 mm, outline 3.2 x 10.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 7.5 mm, outline 4.2 x 10.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 7.5 mm, outline 5.2 x 10.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 10.2 mm, outline 4.3 x 13.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 10.2 mm, outline 5.4 x 13.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 10.2 mm, outline 6.4 x 13.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 10.2 mm + 15.2 mm, outline 6.2 x 18.4 mm - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 15 mm, outline 5.4 x 18.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 15 mm, outline 6.4 x 18.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 15 mm, outline 7.2 x 18.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 15 mm, outline 8.4 x 18.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 15 mm, outline 9.1 x 18.2 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 22.5 mm, outline 6.2 x 26.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 22.5 mm, outline 7.4 x 26.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 22.5 mm, outline 8.7 x 26.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 22.5 mm, outline 10.8 x 26.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 22.5 mm, outline 11.3 x 26.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 9.3 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 11.3 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 13.4 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 20.5 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 32.5 mm, outline 13.7 x 37.4 mm - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 32.5 mm, outline 16.2 x 37.4 mm - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 32.5 mm, outline 18.2 x 37.4 mm - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 37.5 mm, outline 19.2 x 41.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 37.5 mm, outline 20.3 x 41.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 3.5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 37.5 mm, outline 15.5 x 41.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 7.5 mm, outline 6.3 x 10.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 15.4 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 17.3 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>Ceramic Chip Capacitor KEMET 0204 Reflow solder</b><p> -Metric Code Size 1005 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 0603 Reflow solder</b><p> -Metric Code Size 1608 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 0805 Reflow solder</b><p> -Metric Code Size 2012 - - - - - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 1206 Reflow solder</b><p> -Metric Code Size 3216 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 1210 Reflow solder</b><p> -Metric Code Size 3225 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 1812 Reflow solder</b><p> -Metric Code Size 4532 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 1825 Reflow solder</b><p> -Metric Code Size 4564 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 2220 Reflow solder</b><p> -Metric Code Size 5650 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 2225 Reflow solder</b><p> -Metric Code Size 5664 - - - - ->NAME ->VALUE - - - - - - - - - - ->NAME ->VALUE - - - - - - -<B>CAPACITOR</B>, American symbol - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<h3>SparkFun Electronics' preferred foot prints</h3> -In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> -We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. -<br><br> -<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -2mm SMD side-entry connector. tDocu layer indicates the actual physical plastic housing. +/- indicate SparkFun standard batteries and wiring. - - - - - - - - - - - - - ->Name ->Value -+ -- - - - - - - - - - - - - - - - - - - - - - - - - - ->Name ->Value - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - -This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place. -You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line). -This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace" -to hold the component in place. 0.005 has proven to be the perfect amount of "off-center" position when using our standard breakaway headers. -Although looks a little odd when you look at the bare footprint, once you have a header in there, the alteration is very hard to notice. Also, -if you push a header all the way into place, it is covered up entirely on the bottom side. This idea of altering the position of holes to aid alignment -will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins. - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - ->Name ->Value -+ -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - ->Name ->Value -+ -- - - -<H3>JST-2-PTH-KIT</h3> -2-Pin JST, through-hole connector<br> -<br> -<b>Warning:</b> This is the KIT version of this package. This package has a smaller diameter top stop mask, which doesn't cover the diameter of the pad. This means only the bottom side of the pads' copper will be exposed. You'll only be able to solder to the bottom side. - - - - - - - - - ->Name ->Value -+ -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - -This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place. -You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line). -This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace" -to hold the component in place. 0.005 has proven to be the perfect amount of "off-center" position when using our standard breakaway headers. -Although looks a little odd when you look at the bare footprint, once you have a header in there, the alteration is very hard to notice. Also, -if you push a header all the way into place, it is covered up entirely on the bottom side. This idea of altering the position of holes to aid alignment -will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins. - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - ->Name ->Value -+ -- -S -S - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - ->NAME ->VALUE - - - - ->NAME ->VALUE - - - - - - - - - - - - - ->Value ->Name - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - ->NAME ->VALUE - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - ->VALUE ->NAME - - - - - - - - - - - - - - - - - - - - - - - - ->VALUE ->NAME - - - - - - - - - - - - - - - - - - - - - - - - - - ->VALUE ->NAME - - - - - - - - - - - ->VALUE ->NAME - - - - - -<b>Header 2</b> -Standard 2-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08233 with associated crimp pins and housings. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -.1" headers, two rows of 8 each - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Header 4</b> -Standard 4-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08231 with associated crimp pins and housings. 1MM SMD Version SKU: PRT-10208 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Header 1</b> -Standard 1-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pcb/TODO b/pcb/TODO deleted file mode 100644 index 139ead2b..00000000 --- a/pcb/TODO +++ /dev/null @@ -1,14 +0,0 @@ -x-Add bypass caps for MAX3041 chips -x-Add shield holes to back of 8x2 RJ45 header -x-Flip board so the BBB is upside down (rather than the rest of the board) -x-Verify RJ45 pinout -x-Add ground connections -x-Fix case positions on RJ45 shield -x-Finish routing RJ45 section -x-Finish routing digital section -x-gpio on p8 pin ETHRPWM2B -x-Add extra pads for GPIO like the HDMI on p8 - -Future: --Add HRC logo --EEPROM for shield detection diff --git a/pcb/datasheets/10118074.pdf b/pcb/datasheets/10118074.pdf deleted file mode 100644 index 933ff2a490748c46659dfd5117f032df414a1044..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 196965 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%0A?CQW5i8R+3l8QW;Mon+77z;pM^HRj< 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%0DEM_``_T_!;_T@- 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
yuZ@^BK+Y84&|nVXb@OByROK2-To?UvPruW9 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 H@ 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 V`) 127) c = '?'; @@ -54,7 +54,7 @@ void Screen::draw_char(uint8_t row, uint8_t column, const uint32_t color, char c } } -void Screen::draw_text(uint8_t row, uint8_t column, uint32_t color, std::string output, bool flip) { +void Screen::draw_text(uint32_t row, uint32_t column, uint32_t color, std::string output, bool flip) { if (flip) { column += (output.length() - 1) * 6; } diff --git a/src/ledgames/screen.hh b/src/ledgames/screen.hh index 1c42bce9..f5465642 100644 --- a/src/ledgames/screen.hh +++ b/src/ledgames/screen.hh @@ -13,11 +13,11 @@ public: void set_background_color(uint32_t color); void draw_start(void); void draw_end(void); - void draw_text(uint8_t row, uint8_t column, uint32_t color, std::string output, bool flip = false); + void draw_text(uint32_t row, uint32_t column, uint32_t color, std::string output, bool flip = false); void set_flip(bool do_flip); private: - void draw_char(uint8_t row, uint8_t column, const uint32_t color, char c, bool flip); + void draw_char(uint32_t row, uint32_t column, const uint32_t color, char c, bool flip); uint32_t *pixels_; ledscape_t * const leds_; diff --git a/src/ledgames/sprite.cc b/src/ledgames/sprite.cc index db7a0dc8..cf9ee7f5 100644 --- a/src/ledgames/sprite.cc +++ b/src/ledgames/sprite.cc @@ -75,9 +75,20 @@ void sprite_t::draw_onto(Screen *screen) { } } -bool sprite_t::test_collision(const sprite_t &other_sprite) { +bool sprite_t::test_collision(const sprite_t &other_sprite, bool fast) { if (!active_) return false; if (!other_sprite.is_active()) return false; + + if (fast) { + uint8_t visible_x = x_; + uint8_t visible_y = y_; + uint8_t other_visible_x = other_sprite.x_; + uint8_t other_visible_y = other_sprite.y_; + + return !((visible_x + width_ - 1) < other_visible_x || (visible_y + height_ - 1) < (other_visible_y) || + x_ > (other_visible_x + other_sprite.width_ - 1) || + y_ > (other_visible_y + other_sprite.height_ - 1) ); + } uint8_t top = std::max(y_, other_sprite.y_); uint8_t bottom = std::min(y_+height_, other_sprite.y_ + other_sprite.height_); diff --git a/src/ledgames/sprite.hh b/src/ledgames/sprite.hh index ca6df3fc..6f921ad1 100644 --- a/src/ledgames/sprite.hh +++ b/src/ledgames/sprite.hh @@ -20,7 +20,7 @@ public: virtual void draw_onto(Screen *screen); virtual void set_active(bool active); virtual bool is_active(void) const; - virtual bool test_collision(const sprite_t &other_sprite); + virtual bool test_collision(const sprite_t &other_sprite, bool fast); virtual float get_x_position(void); virtual float get_y_position(void);

kL z2@E)l7fDRgIdI^3b)F8_sf-yG7+tsR2B2H%xeKD?BYS!ummsEAjdM@}=_l z<;`xBg?@Td9!v5GzrmE*fQrb$E9H;~G-y#gk%~80;j&SX2H)hcActweDWEALta`wV z<>Se$`m@Q`^$%e~u2j7?6E z>Oxp((UN1`s80EotIkB*8Es5l!ket;3~m-8F{NTYZ-geak7vf719h&lg$~HC9h`W` z>>&5HV(yor@LT4^X@;f1lTPlv$3)zqs$wi?AnUpz;7vy<&mqDy1Z zOz}0ir^2!#F~m#nh#c;r2cbgN%T>cRMK~!b*5I|zpLY{RvvVz&k)D8eIVrZGLR=g_ z?Ixd4(-aHQPda`(((s%gE_{Y)R{^-acI2Dqggh|yY}puIDywT?xSU6oV|6fHCD^-I zeWjUH=EutSmx0sNI&Cca94dyGK(+m4eZwxZ5w>SP-g?`)(~`zyz&XH$;4OpsAnWLn z2!WB^HY9!K)QsKJClzoHBLQq|9>jB+@#zuyC(PgS%dDfgo($^m@y?f{@myp~i z)Xovmyo!*UzH{Z~X0Bs39+ER6`8XqsNl#Mh5uXfhTni=VbDkGFZP8goWKI~5%9Bl} zJrIr5rOpUj8|ifUy-s>IdXB=lUs7GU_C9|N%s8P&?M+P}b11M_uf>U#ObRshy%yvuwA@DXrQVg2%pPkqL;sN$clRvePj*)pGM3_r3X5 z>p3ua8MsN^wUqhJb9%HLoK2|RQV9ni=1dJUBypCQwyW0#E(*FE_>@A;1yC`MBosfd zCL{B~j9s~Rz1~M<9Vcl17};V|%3Pw$EoZ7r>FF|^eWjua`Ps^1357Uu2=j9ul}hgj zK*mZtuGrnu0t;ER!+f4=>wReMDGAV>;6^6Jptd?4Gw{qbq6UqBc*If05p|7hKk`#IDoW_6zlt zudAsosazoFUx1SknnR1E!}>uQg`UC8x6F5fefjZg^{HohT#QVpro$PT z&tc`W%5f6|DSE9?ASD#KYx|H2C`q$nhW(Y(bC=!#6c^MPkL($9s+SLtMN2rBTRBUoO?V`FQ*L>QF|w}BQEStGK7OYi*^ih|BDs4s1a|}#UWLG`T=M}v`0b7u z?lQi@63+VRBiHcdof1;0I*t0i26}_D^*kvpkwEydzu$cJJNMo z5IZRA7I8*AjyoQr=*YG9tw+PLXq~YljfN=6Wl+p)!dG~elO$U#c5o`F&hLb5jSutG zUUHNea^bY^z;}_N48qf$kUgJ8e~5ZEJ-g9+ud8?H$?&(6xt1pPMsLq1hpKrm-o3ry z%S+tV+3{&l%=zcpHua1L+U+gv7w)HBU+Q!Qaaf-O7`he)a1~GY7B8(Gy8C*(5Ff8J zQlScRQBpbvhtCUIq((C9&r9cOzv|5{o2`U$X1k38IMd?>cT*M~oy zJ9h25YXisDY%Z&9#<%r>0OzSv1)}8r(ACF@b@mqf7Ti3`D9;&lJcG%%QgQ<{Ci$pQ z>|Zn&on2fK+LC0!XiCb%So&Lw(seJayb`kvytg@-%U_ZrZz$gss!uF>X|+?~9ZGDj zH`b~B8Jutg@m}J{#$pQ#jxJ-6WfK7y;@jYGFmQxm3>@JkKDWVu?onE@-RecmBKpru z{d({+qz8ykI!ey6m`Ss>;FXCbW^kQ0%c~kkF3_{8gD}3nZJMnf2wHMro=C55*vl`= z7^AjL_!vX*Xv6z0OtoH{5lBX%Y01` zil!qGeZ^{NzigqZ_Lz|Nq_?95*y325y(XRZe%ezA95Ot%J>`21(2Za{C30b7L$jTa zTfW`2<=)`vgUxS!dH=g$&%Y%qU<2m6etw=+6$j+sl48vsV!QGtYVEV+6AI@U$u{ky zKWHkp(~&AlQfykEN3^Roc|ItxqVvi=I&*UZA_iaNVzyc z;f9}{%b&57;9yV?VBp~3D2kGz!hc=`sD$K<82k(u>Wl;l=Th>r@#6DE2=wVg)Kdxc z)N@P>Feq?v7(@fp+kxbE91;1GyPwvGj+B*`hm#TX$$k6D3;F~`G@+-qhQ_2S?v75z z){dl7Hb%A%cD4=%PR38~ladNqS&`nd|2vX87&{s}xB#W!2Rbm|FBL2UEEhZ!JPZs5 zxMDCUuz0X`uxs#S@RrjUl(R997VVKUHCK#x3#Ud4n6KZRg<)U$!76&X`>T*h`ITB0 z5f+t}4f);k@AAkD>w(LI^-n7|ZX&FF`79&vUQ1^p z6>zRFK^`&IcAl<&9xzW8o z7hqA&8Y8<-+d9BcBf21y&ls^)PyH|bJ5T*j{W~v#57kS5*wfcnjM$x5g{r{OlxH}# zr*^gAt)NfH)30Y`*s~HNygU*Tyip`P!;*8eBg1nfMmX|X+6wa8E$>KrBU)Q~3E#D9 zDcnOjPm0_>YcB)uI7K{rc!~&lI&{j2ZJDN<{B*@)-0xIqc^R&*?oCP?VcQ!&!@7IR zY<`zQ76MOMb^R^9JueyYPMc4;ykN9_eSHlGFWF$Cizo703hR3D-+%Qzg*W(YG^U$t z_Z+TBPbx!{P*lppPVb(br>?V+uz{fOCH#BJI)xVd38!dVJfN+C@3R))dtR4Zr_C@Z zXJ?TuXIGivXQ)Szr&H&m*q3A1qR?l%Fqa?B(y&j}ugsvYSYS{*GR`@lU23PotRZY7 z{^osq`?&nuI3R$|zP%kuzrWc2NkfA9ZxRx$fM)I=csX|9^#owZL8k@5ApU&a{j)E0 z+x}O;+#ui!O^c&>uW886OOEO8Y-hepB%c&lo=|7Pxlg+6A5Z(NRJ0Mxy3qH%!Um0t ziGV^oiVfUef z%Kd3Q$Y-&iUTouER7kyO_;6lf-(8p7o9tV_gUz=Zb%YgpRwOmbhFjTR^kQ#8u62%6 ziXf%lz_hRVis_v4K{lfZHcMA9bwwJaA+kEUen0*iQJ~5-_GGXYy<(q+oen>E8@Uig zjE_J*;>QI(YU4M^xES$(1cVuNBfcH_3Z4J+)y746dPY}golmhV2oX5_9?;F4SWxN$6uQB6F&_U-#xEPL7h>=)jjRKC@RikxTpq|9Y@Exf7s z;jKuqYMiclBYrJ*i0OVqr9o;fo=G7jDN;?F&`ISuEUY5FwSH+6a1@tgCwz<_B16YJ zfOO40<~rkH8hVb@N)~%rHOp_ZG@X%QhtDaLk^N-oi;I`HyZla=FiVuF?aPmoZeM3p zKeuRWbNHz9uy-ygWXG;MWyE@a5hXR>?-NTWT8Lbnw)fe!EfjuF3U|a!cY)HufcU;w zW9eQW)ZB6Dx=U%Q^6*}b0>#rW(@(z!j+-|cXboPbRd=ytByVKFLoCfd(Rbiu>nuP? zZCfd|fY?C+aytD;WIeiXB7&V@9(L8V@+%jQvS3o=j;wLlQmQ#Uw<`R6d4ApHW9IjS zpU%e@@7`9Op)ejx!249l0}H;d7bNlOY|*=#K?xyKZRHnE(nF=y8{hoIX=0Bz+Hwl& zub$f!sIcS{%qPFx>gh&1c)Hs)AenaN=oX|9c%`Vaa z@_92H;(Pz_Grk@&HLn#`exYmXQ^Jv9biRg6sf@ zm-ru;u0Iloj2%F!RzQXipgiebDtV%)(X2!I~BlnNLx6hFG`O^8IOMj5{&_npT_mD8czKRAB1 z%I4DYXd9*eIjPSqyG}<_vY|Il9_gkFWu7afMMJ$?JO;j1J7CVl z-IaAb^4}05FZUTww~QTN4{EvBA9#jz>s)*j>O5GS!39u{k~!vY^a;DCC04RjW6^FV zubYotoZ+-miyfmnzN{ySS8n6y4ky5DI==_gKJ;apdKaToCXgKaHjR=44Yw28-Uedr z!J-3ZD$HWyK4h(%^ogpmK0(;4{ghM@#dr=|@_sgr3LiGf0zREusTXL8Z`8hOeNiq; za-)J^h2N%4f+Ld^*L_K;)FUjT+qakO8PgpjP4qTF0>ke48KrIXIPTttY^Qx_mSe+% z$Ogg%nBJik?h9aEBJwQf{qJ7zKg>1$h;9Vkv_F}xK!LcqgQFAZ{w4h-Zv#NJ{oqfs zfgonTEVro!cVz%R>lQ@??1N}DLC4;L;6U|29jFW$^zq-8A5U`E(OnrbD52qY`2#I> z*V&)wu|KW`bPT8t1dO|@1C@P;;r-DG=z!ZwVE^{OAIk5}`0E-OQ~+uSO1%KBe?8!C zA5;(82BGcl+JKI~?Ev(J+#LX_{BirPga5St-T~0)?f}sL^@}@n=i3MyI2wZnSyE<@ zBl2IyyFA4`~fqIhf-Bqbd#X4X-gd8keKdLEbM^yl8++-P@hl-BBlQbj`HRL zmul<69n5C1X4Pi-LfMU%8O6FWoYDvWwa{{QH5-zcs+^PaHsB2@1_P1j;pXTb3)qqB zY3#*AXAacwb~lb$E`)mW?FoooYTr+>k1(h3H|mva&^`QuS%@$}fZomOV={$xM8ZB0 z(0BswxJA5rpcA#{IXD-%Dp(&LLRjQQAER!VZte;_IVhtayutDS`cv8HJ#W?5U)bdD zb(YRxPazk1A@HM>L(JEHxklrdd4T5jHNo?B)HOCoG#Z#c{eCQrfUDiI`uirY*>4G6 z=f0ym98CsQ2&Oc-BTmaa#!ArT9}=sCnN5P6a6TT#p^$kXfm|{aLK1+vovhe)f%%=#(T&9&}xlJWXGzyx<0o>m;WJ>ji7%q zLXyz+QoI%)33j0_tlrmoOaaJ7mAPbBdKTf}{FL&v^|$BeZ_N%z#YvET>jp%TN6q~_ z0OYE^EjI9x zIANC!(w7OAGn$r)`-;(O4uhy+{(oru%jmeZYzq{&9WygCGqW8tGcz+YLt@8l$IKKn zGdpHxW@cu_*nXAMaL?^NcXW^Md+&!vNvf@_E!CE4tvT143pWI&{dx{xhvM+K*T5Hc zPu;*oR-VD*_S21;&s!nw8#t$Bb=BdbTh~Zb11}5gF-SLG3EabtR2GZmZh?hiIr$-Tuqg>f;V1FF#R*|$Z2Y)*Z8E_i5_{$J=jlwY!H|gRkX#SI153L?u zO7Ka%m^|vU$%}Mf!OD21%8Gf4CwMeO#{i2+llnu_C@6#vn=gxE6GGzFh-a`5n>S3h zF}9Ajc~l9$Zn)yFucq?OjvEiF>mAV5p1DjC(_~<}6!LZeSy{V`D$CN@qodA!-!_`G zh~>mKhp;p%cuD)Sv02(2icOun>X?AQ3I}{v2+>i4JNnQ;0XZmwWB=)R3Q+T~EeNxP zGh7nR*&&I|FO&$O6$vJ&?|OnsFgRpeAQ;O;hM)y`A!8(zxHNrrn6KQ)Es{;b@L<|U zYGXOvmfzX-m53K0E5wRfSKP0vqoeCW!_YIqoE$Jp9q)djCRqApC$dZB)anlKzU+Ug zvqk(E0Tu87`tV+ zoR}B1WUHqa6f?6*u@MbRR*GbKG(az--dJ|q2F6!%v63f?jzCM#kG`_>*pqXRD``|R zibkvGp$J2yc1xzW*ju$rZ((ko2FOam)f`1az1}f1;*(T+Um-feJ`cwbee9kK1j&zJ zHA*HUC>5a!B!c#dL{0dMSq`RkBeTQ+fi?tA+dh3-;M}=}O`%AnFYGJ&2RV_^EfYFu zZP^j7Yn>Rr(~^;uVAZ}J9t1WJSw*fJeB!KltV_=y;du^kc8XOHElFF35<4ktJTEPm zla?a~N-{!qgo9@i(^9eBFeI$%F-;y8sFJ_t1v5w@&A{wObp6_wAlqSRdHbey4PWxV z;UWr?bB2DLu04&TJv4b5VomB8z4)_?8@sZKwEYlwoxS>KEc;v>#si77qf7j) zpzo9H2%Z&;hCl*!Zte~aSS)1+Vm04X4LqcUV(|)=2x)9~P4WCUi$Mq}RV@_(Vbs&% zUWtmW2rB3am-70C`K0Ah8>LoY*9^Ijw)D5Ri`DhZReOdN?l7h$3Zz0o+KE~OGZ$L9 zCU`Riv&lvmitR4PSr81U@G7=+9O=sne3x#jR*2aXKOTX{V2)fcI|Us}a)`3WUWz@M zy!-4y6`i>0-e?~Pe$c$3_FR;^kr39akXWxVfg(Y%wZLwnCY3bNX3~)h&FmO@+&y6V zA5?ODYwj0u3Z9KeR(06Hk$lm+p12a_4Tx3T%NX2_c(qn4(Gx;s{Fj|6SLDeJOrO0g z4!(Bswgc%V1;L=;s8MW0m~lflr$Mv|T&KU#{W|r!y7b>WO%xrJzdIpTPEe!3$(8JHanRvhVLj-Rlbm` zj7Mh$30W?{fX|;jB7^}W@5OJLwV0ocQaWw9S_D$d%G=`XSk;VV?(Z8JhOP=zo>b_F zRB$SNS-eV(v+6mYD^6~E1fLTNcK8j7-;eB{_GBsR=xmT)&}nv+)e7v> zJ7moWu#TD`ZNezwsuo5iZ;5?^tzPL6v*ig&pP9nA66Vv>7LVh#at;$dLb6fA3UL@1 zX^TS98caI`mnph2?4dCO?`A1O(S;HxOGKtf$oHuAd8BSF-PBZC1%FKL^~n=KWt0uF z_vv{3NnLt3j&Ps15+lok4CuY#ZJ%_CFmN$Jnm_{@=k$KCI0}(oX)|bP94$KdAT6_- z^ne%{NgPrJ_<(LHB1H4_9>Vb|Gq65sWn4~gu@%c<4%_=>9!Ew*HONP{p+%e&SDl3htzwu2 zrrx4-FoA19a;6o~Z9^6GjI;I_Y#wI~w$xyIJC4lyu1!Ek?0K?IgPNGsI(nMLRwiA~ z#V)VHyd9%@6`hH;y4QVDK;=M&njEI$*7(Q zO{cBbMJ7oEkuh+u6R?VgmFjn`3Nu^Uk_TCNGb0gyg>r1E*?C%e7D|4~a}z>s z_PaHM6#IC}ug_P>5z7gmUa335?W9U@IOu=!deqK6L2s5Mr%zJorG4lm4`Fr2Z5F-3hA-I$h4H}`Sq;&=_qnN_&fG0mNrILnU)Xw;1fFZ+~S(FQm&?3 zJawXj|7sfvi+!D9YKyk}PK?$~r~MBgA}v_Ww&DSHp_**Q^^DtUe1A3ThF_^ z1Wnphc!48eV5t?8m6DlL z(Un&gMD*?KG$L3{kux{zBtV0Pg3A55XdvXF089cNYt*xOL*eCS@0~a!HN|I<_B#EU z#r$yWC(n4z^Na>k?b-KviRJX{{GGADVR5G0+k;%s^(Bj8X{~|Kdz0O_?DQ-Vrufl? zVmK4J+(5blRB4^%Dd${JA3-w|(L;51pJ}!*))JQQn>+L2N@B3=ME3nI>TtCw%jp-w z&dl6C@92n=8)E}YDCq~&eb-O*JQjuC(}cf+3p2mft=cx{M|MQFN^h;~%E;NAT>s#m zE5^G$U*VPRK+ua3R8#N_r2UXWf0c4q$i5X~MxJUqpDtsfHXZop_5SPq)V9KF;d4%f za7H!{HUX0pQau?3hK+oa5=&Z_WnQ9fjgr8}r6$&ersj8_XFI;m4wmz2kKFKueY%uk zj|1_xGvh`RQ~3u7xdDx=^bFqMcql-as~G-QZk{T3E!EdYaw{Qgp{MqU(d_f3W)tnx zT{vu%I%I7Wk#W$=(O*ze#_UXBHyW_zD$r2{1IXW~{gS?xAC#J@l#(GBH02xBMV|s? zcCgAI@w$sG;iknavzsgQK}M-6-XNle=~92g1*>dmEN-YC>e^`si@=d6e62`}ZiG z;9^|aL++E1zQz2Jt4lX#C=Q`sW>I8qnCv}`tu`EDQw+~&j^e3EhaiQsm8-Q7=Z#xl z%ENCl8l&st-HAlsqO3<(K^I`rlKgUuOUb#w9gAKyA)Y~*0qj!&42MY`H|I#0Gxmuc z#f6TfZS{?)3n=+)P3bTA1^__z_gT&c2p{<8EdK```Ja$#razAV*I7QM`q_S!5pn&Q zhI1vLs*UGMr7H_*fHt8}c>a-69;E^&URuuAPWgOV#jp^1Dx*)|?mXNt+jkY2ao|_C ziyYksRj%rKA?ghI4TUD0?NaDdn&%ibtNY+~3Us(beul?7Oel}HY@IotDQvX}n&sL6tGxEt z&e6dL%#|n(_bun{umSJjvvH^WLDE0I{&4DG3<5T9fcHLIAy1hUfYuC;ZxU@*w;3%O zyT9%FJ=4y2EP>cUDmP(Zs&vTFc4MoX1E+%WZoTTE%C<*%6LHZ;2d`c@uilK$qA93= z?Ojh_t}i_12{fe+T6klov{AXX9e;p!~zd%gJqu8yjXLKWw~ID^7Sux?2FmRC1 zEWt5b`)LJyy2QwT`i)6Wu4i=J+kK#(Uk?*Q(L11(EE;4*b*`MeKlGfOzx%zff0rkk zQ{!6dt9CLAPeH055tWflMS^qyyUi8gHC;f9%jQ-$(LFTjFqF5`OYTzrR^!Zd4@#S_ z=nVp&|HJzmRw@*xFtu?~+@Mr6Et7d=@{seUz1+fFg@9zz0Sj4%fy{4*nTI^$gUYHj zQS#><7ZgSe;pg&g;+dmGHVlrB zFdHXyOW%{LV4O`8ywn|@QXLBELJm0c(JCR{juaZ8OX0AF)e~g`W*A-!P1LGnNS48Rotu;l+O zzV`>y#?A#$r}`_VP4>^SJO9G80R#>JJ^ne;jt&r)@HbXX4IuplSp6^Pw!c$je^6|H z&})BCZof&m-%11k*w50<^nVjr03C*Z3-V$9Kgh}7!}-7Y5`cimpM)?ue{cO$3G+A9 z|5wXDK>PpZ^PgF;|s5e_m;h0&SGK6I@`yu+z>aXi>Oa&Kv;8ZlxLXy zosf^z;Gpl~Z!o&%AqsuG`m5E@;uNG_hF*auDf0@M_*MdW@5bd4;o20PLFTF@p{b_( z1!jr@OuFA)XpDC$JgI$oMalbBh>DtNl~R2Y$!~66nX|{EGukN19K)wajD&F3z|YII zz4X{$kqm%*n7;`Ag;o8>PxmkE`u}NF1LiHm?`H*IN7|VJj7N9C+P@pX|1@p^`fUud zgn;SIpz&{}@LA5$^D5_#t9TdmA?tT3 zb;eay(+66|G$g3yf$u3GdC@13j2p@Q}tjf{vp%U?K++Ea@Vtqy z3y}}Ja#2&C5gOK4>>S*%%E7Z1t=!M*ym;V#P{1Y9C(jyksCc)%e%33SJa$ap;Pr{v z{W{Irw{J8N+N>1SnzhS3tE2<2KI!W0SdYIv4ckIrHza1dSrhouA4)1RRSy{=^2|!c zTNhc2O&Kt5{|(FP!}C+&@~->F;#db#ABG3#yB;xc>R^gLTitW``?_f+)DhC0KjNDM zxC#*{zT!LBTLwZWHa;xGCVUiv3@larZLW(!$PO8~{S6v{V(BMGNi;!o5l+I9Fow3|jXQx(R449b?bxj~?eZ#?C~ZnD?(b@3 zOksZEsORGuu!AVawz==f_Zd`KAh9jxV7(u(!NkmBFx$@ZO+9a|lV28Gz6OE!tchoz z+@rKS=GMnkl>o~h%RyAloYkYK`$ho?dPPHIxv z>=)$(n?E%;rxS`ph-L}VU&UAksLCAGceG7bAP94S>u0n}yHV6#dEQJ9LBtcBzGHVT z*4uT~6tD3#IcQYb$qKuO948@S7s`(s;$`e7Td>2&6_~J_S(hZ5CnXSkmE4&M*ychu z{_K&&7_m2ayiD1b>p-36E*PlZr%R*Qpb!Od*DF|PTz0A}lT+n~8D`d1(kyg)dI`nf z8d*{5TPScTr*@SlT#dwvQhh%d6>&P-J??`8uisYwdGj{aRw`x17~g8X<|ZMlczatw zf;ntGr%jr8o!rWdRb3#4`k4^exfFR4#Uh5K&v9Ulz-e-;ga1i6!AC!lYlx z3ML21Dp?p}{BZffgzr7A3tS^G(gukEu`%F4_!I4}RgVm9j}+mzve1`jB(Dq7ge+ce zp<++Ax4;j1Kv++6%>>wAy?FlN&T|5^IR0s71LT(fTW9ibRQ3PPjTlpvwFl%nwO>|k zIf9vp<2pULCXfv}Obu1K2h7=eg~eh@#1mH_Jiq$(uFp%sgHVKk_yhU-_}q4AXIGA5CVBTzIo3pZJZ^vvXFz|-|8l?SA?QF%Cnlm_899Gy=+sxO|tOO1AX z`5}HPfpll}na)>C!zB%7jf_p~wp`SxS9f+}!3_j*+QqJCdUo@WeKA1eHT$U|{VKPg zIDJ~QfAUdBzS+ysqpdVKHB*Tl?d?)B>_6BE$mDt zq=EXS;korVr8yLI{5Rd?Jg2uSFg-f~)Up{D+w z%>@BAf;xIC7r{^&{IBAWC}AP>aIa&>^H=ibQcVckK^4yp5{h74qvE#5@hXanV0h*O zy>vD@WkM=!u$68J%ccVnoAbr{1GA}&xKXN6%L$5j27x#;xuTuRwm#vAT<>D|*1`dGA|=j=o)}@~^F> zeOWqlPfuU}rH~|m)w+gr!TWSjNFI)&fsP5k$-`{%f|MO7) z!=wI>zVjc)|Eup@o}_J!!-N>L`KUgY2Y0QKjHQd8K7}p>%cg0ObJtDkcA8Xfxf9d5 zNn*}H3T7>Aj9$mg{bO`+dT1Qu1UnrUhhk4=2XiQ`YX@%}*1F!M)oNipw`QW&pefWw z>aLlqE{ZKsJXSWQxJ*)RmApn;!tCl!S{7F%&_?OOsHEMpL-ydZ(~HE7dp6L)?i=Cl z@tC;vvRv*8CB@!8Z9htj#UyF}@#90=^A!76Y*!n+k*gk}9keBHK|FG&DII7k-AC&5 z#7`SUb?RJGckz&|$oipr>2`j+fu+jy)On3!KZ#3}qoOjeC#hPM4cwTVGdPtgDcCZi zrLfkeXOKn$jvy0W6-W~NnYHx`d^D7b%2VMIvcInlq==lW8W;O|TZnSN7ZKlD3&GyTMV78K;wvszM#m-h+%`R?2>zOeDS9hbTAC5t zDCdfZ=Wj(|6-cdue`ckDAbq0qIYBJTdEQVg-%!jz>lEjwlqAc+f}jg%rEf7(>&pMusOIAPhaEkRA^(y6~>Mxl&dWuPl>u=F-!|nK&9(V*ND!x?!u~0TUmAY-8fHAupwDwzqd%m{(`pwDGICQ}=>>^&+aWaouiq zy{gjkXP&CN>?)fsgS&Lg>rbt7kCk`o3+=6Enl7N(i}9_$nz(<0cmCn~ih8(+E4u)a zA$~h^f`n#tCd z{^Vpb$PohYSwR~YQzyIMLj#=O&C=LZNgN<~_4gzbW;PB0{wrqryA9ye2GC5z)Y#s{ z^j|!oj3iGLWq0(!ulB<~ViK!+jp4NYs=;H}Yz$-ZKoub+A%T&FB$mJgMZi!+MFL9` znHOwb#Nftv1H}2>X;~$pp)i_)@G&%dV9&xvl*r*BN;$N} zK-B&!G3d-fbW_m95GNtQIe1fcM~_pAN1!h7Eug+&vVsWNm)XgTAhU+}HW01d9o3jo z{>odp9#G}qthdOUQS=}Xy7R91o)~>V_z?61D7HhcXh9IMd&F^(h=|1if=^1J2}EA` zXvbpUv5F@APOw}NI)db};zKYAp-zghXt~=K$Y~KH)7bTB=b|Cgx<`h0tX^Q5LgrJ8 zpy1s}TcVI85>OG4)Iy(gA{Zr>B%eYZf*m3mWj&-wk)K6?nF3QpXbII2)5F^PD*8V4 z?egxf-)E5wkCb9{P4FcUr7nagj;h-vrTLX4=lOJi_p zoU{Ka?RxFI^?@-tn{rA+YGeu?d#lYuilku+vvG=as_dBH0nvfz0SS80{y*v*QjIv>e6ZrwOVFUHTr^1F2@G3+M~XM_BhX z@jWOHB|WgJkVoweQ2T)lV|m=SCzV*IAZ+>q@4+yx;@Uie# zA;2M%xbNYq#!MP$?17mBX1KO^@wkyuJh&9N`dm;MPMO>p@SN+8h1?ODqZtqx^4ycn zoXz<^>zmJ9e;!LYqO~Tq+PQr`eHoM8O1f+uv0Xdw=u#p?V}*Kvwrgcs%UiQv6JM|L zLj2r^pNOyhx#KSIa{%w?XK{dPO}AdRo>f(aUUD1MM$U%TrQ#)yPz$4&2E`gp#?AI? z{)@}g_gCHr*K4}F^)2s(#|Hfv{lv|bO*$m;1lkisJQUx<%VUN|g6mG~E=UPT3m8u1 zE8A@KY-R`Tt*n4%K}*51Z*t&oB%Gug1a16Jf}zq9l0)7^9DTfw!OiNwJSmA-+3V@< zcBe25yA6Y@0}Q_+U<9iNUqW?u3RDaHG_dJjhb)5B?28H=mY}UAy?GlN2FyXtIg2@t z>51v^qs-|?BVHqFqlbRpsQZZd!7r$jojTw>(iUpI0$f)yf;_ctc&P7Y&PEa-LKp)a){V2%}-v~pLDh|+3s!w+hluh zy~_5dPr!l0+il9M+pO_&CA`Q3?zy(*#_sM@vqq{g6Tp;o%Kr;f9(vYxCyqXDHM zyb-w3v+=6QqG_vHvw8Zb)X$z4o|cAI`qrX0qPFyQwD#x@=#IdSk4~@7`!0vBvu^Y5 z-5&j()n1L>xjx0diGJz+p#iah-a)~^&Y{mkZNuEdKSwx6nnu}28^_qj8phei8z$H% z8Yej>o2R&@TBdoYJ7)N2x@SdZ2j(Q_M(5?`rx#QgmKJpux0Xznj+SkfuUFhwURV9r zz}CXo5!aJ8a5r){sQ~IM>|5>IBHLp-$~&vO#=EC`&U?T10}tR1k`4(DOOBY2+K$DJ zr%tp__D>y7U(bTikvOygr6M zVLcT;b3PBgsJ|S(y8nXsmGVaQ*77d>zV>1J@w-0#W8m%UUjQ`!Zow)Tn*TOg6@J$g zav=m1P5J|uXHYVAws!@j1344^V-J9^aRD@O2AHaUYa(lEVreL3??I>y*unURyZ{G4 z3E_A0fv}Uk!(V@+WdDcp4G1;(lWF}YR}wH1CwpUMQx`z53<@G*fWq>o9xi`$`kPlE z{KMM>RN(jUF-&Z*R!4SWP_j@;Bh4pVuexID- ze|&-8y^1R{0gB20?cx9%%z%x*5f^{76}GprcT)bHh4se}gq;DUHU0;z`qQ=i$>;co z?as!?0+6r$&$fG?`l=JoAd>H(`j~X7A2CzL>lojjKZs!neQW|`XgG0;24ZyrM|aSG zC^LUo^l;PC*OXb7)-HM|sd^>JCjpS&$XaH$Z#TVFQ+Em* z?RJb1ra(;w$B;;=5O! zSM#*E$;qb8=$rKUag)+@lW7@K30Bnc;-T8>*;ADk=C$>UHBWD66ZMi*w5sBoX%vkg z@SE?eJJq{m|4TspMVYC%7ye3wE1%wByzqk;OB$nhKRtvl${Es|V(IPf6@{kuydoG&CGWPSibL3IZ-P5ZhsOQ6X`!Z~}^XSPPWf4_h1}+-Y*o zhK|T>qYKfT%o+YJ$qjPdfn!(9+%+s1%>?rXHC2_RoZFA6TfsrbFHaM0!2@(~bVU#) z@7ulLyde?{0Un@6T*0R!$C!eYT{|@xeOHA#(5yg9YI3@0_>&|P>`Wq+aJ0uKaSn8K z8NITuw0ZdteViYj7({?f00@($f{Yq1hh#FEEySRS?xK}Pa*;6zxDlb;-jLAnDN<!&tEd)WB(AcKMFCyntL<*|Iq2bl zMxH5h6D8#4gdC6@@Bp=#AZ%*rWlC{8vEa~foCOi{dPr0AGQ)g$<5;Xh_=wd~U~5H3 zCSzuT)k`uqj>=>WD;g{wgn#Y z5&q~Ocb#k}Oc4pg32ytqngz<)Q{c#-Yi7{ep$s3}p<-TOt`p1a>5Yi#iA;qly@7ox z>@uR?L>y?`G4~%c;aIIo(vS**LpG%&OMW7@7S26?J)v{-p*1g~#3>w)6L^Dpj;an%Yt&`^sQ=*I zJ36~@ExqtMdcE&xztqW#2P^NbxOc?U;64^Wl|2Od9dRI*3JJ&GkLdjL0d3fe*k5D^ zB4T@ZdJl(}x|W!1uxyZq}&a#n=u!~y0LMF!mEW%#wl2w!Ajx=+8@Xh!6MjeIfdz3pv?P>^_#`NgnC ze=*Z%3Q`RYZMxr?D^@q$4T~ zLz-}-h}6*7Lu=|B!VZHIKYHla2w$8cNm`HlVpS1t?DPDH;6nlMvK zdr)lR<*1L=cRtivBj3r+jaA$Y1S0n^A70UY+Cu9-}FjlEx+b5~G!gi+X19LZ1ZLE)8*-x^q ze_Gvs>>YOLyMDoapE}94wKk9ANo$jIE5XdzFzV2wFFbSk(xkcg>okj?R-^{CwP*}8 zvo>czKso01Fw)O}H%C$-K~q2uulD^JF1&p(~N%g}e)xM7Ctu1&I{68IR_2m11-U#p;*{tv7wvIXrY$9%An&pMjV9 zq}8A{0po=c{6`CdX>Jmqj?IEB#l|{rZRa{EmrgP(=Dbd4C8&J({82A!R!px3*b|1& z#%RDH`;CJiRDTkb#^Ph78F@`w=9}lZ%w#V?RbpC+QFKmhiUxkaPu)`aQd$3D-(+dC zbR~@4I%xrrBjFrLilmV7JQD z%0fjRsA+% z0k&uSkpz*QgHq{PycAh)6Diw%gQW#*<6KHJGlEJIAfaGiN9hn!%;I_t+<}m;q~Uy| zQ_LHy97CG=Y7of-zDd`d2Y=G=7>V_qgo#v@;dVMd=ddO6`qOd{ET@QGm64Z`9*4gB znE;H_h^pLu2%U{JolLIM^jO)?_$3-_6PlD!>b;NdotLFl?j)pp2)>WH1skng+d$MYm#7(On>_TwL@Fy zXxk{T%hjstm>>5wu|~Pq*go|TmlJwAZD%e4L!m1h{m;Y4S9d!;ek2USYlAVK*y%#v zPZwy3AX+8grBOi+uj3jwGqT_zR%2`|1Gq4Yq(br!knQ-k&WCAuc7C+g8ea_45MD6p zqmSnF2v|*>SyJb6Z13INLFZ=!cL$i8OSwia@Bm3SqXiahE$d#9+B%Kc+gq;HZf}mM z>pHIvA(ihj0U~3!GoXw+-OHR1*vYa|YE81JXnqze(GSdMekYp|jW4+Al*0e@G1Cf^ z1Qe>PflA|!&`4U#w3K;#d~8TJ_t=Tlh(HEkqZ21{81#dVb^twieG*-RHt3bAu};oQ z_}1xt+Lg*zY9o#SN~CX9Lf78!J9@1lNgaQ^ZJ|S5nU;cv-dValE&W_^j*nV#z+PR{ zeDb7#1tLTx#}#Z8bX2bF5hp1kH#}5el<-X8!3Aom^2}&O@~?RY%~P(V@tKouQRU>+ zFUdMrZ3;s~;+?CRXealI$9cJ+0c{oqv!KRaU%%xzZ6rHsa9GCD*>c@)>ZtU=B%)kU z`jk~TiFeb0+Qlf3Yp0l@T3Ob0jkC3q>bwyqO5ddoAbUzjoMLAUOL-fNn?H_v<)xg+)pq; zYa(L(Y;c^*I#J%^*kGi_LaABVLMqCY?;$}ty-ZBc(wtpKcE)ylAjpsTt(7GF<*8!)>7^ZUst#C?KB+v^H}gj9BPU1S!WcH`HX) z0R|hoWj`J|s$^l}`sTv!CuS!7G*6<-!dq_%P4(_`qvlko3}?^bh(^1qls!!X^=RbS z&pDoUM!8224(g9~H;_3k%QIX>EJTn`d|vmCdnZCf$7!}zdI`o+yd)Nc1Bfc-xD_Ut zgB|r>X`V+ybJR)|AS?^G)oK%=lVE6+Do{lO)xwE|Xhe~Y)s&bSWK2M0iBXC#vc+yq z$AhKiiHyg03lRtT^3HpC5KaU3AKX{GJI_&fuq(p)S=PDPP7o_lj0&_uta(Q~b6s~r zTmHVdoOZQqPv4J=(K<1-oAtc9YI?EXMc7JIRW&%%#SQ=q2OT?Lyk;tANH9iE`Qfjmcqz0`Ap zm}-Mk%&>%&@jOBx$eidQpmF^~mPt%^Q12HPp=8~9beA~4kfp?*gTm+pFk;eiR<;() zfWO>#yvP3PNlA`7Niz_&qXx^1-oh9;<2LuxM>`?>RccK39AuA$A^D}B$Y0-4VoM!2 z?f^s2@F>bJgLX0R`0b3P{4Pq24T^OdR8hhktWDlmc=rtF(!ZQ zUfsQKH)?$!ZUa1+oj8amS^~PMGw6FC4?gw}JcqF6d|mI*u80qdHF0O=u&OyF&v>Gs z7vf0%FNz{@&#kO5#@mp3Pwr85udA%AhBBMN3vY8 zOw(S^EPhv~k-pW4b@Zy!sSw|NKIt{%Q(-tb)J4m{^?P@ zZF`fGJ>ls`Hiq2rK0k~Tno;v2+CU7C56Eb#=hGf~R`XL^P`71?jX~ko7@vJ@lwc%f z`@J2X)_%Ust3G~8gzyHt)69AA_(>ugMIT0V(k{M!wUFnCY1L+?ebu*xSs_^60wK02 z%X*H&$g<|oy~X4MEj=j{sxL-AX}*e^V#^Ou-+t|s+sj`KaepoSmH6sLu?L~0Gxs3k zat4LYZR=_LB>@{L3k55_0%%1NA|e`N{m>@gnH^AAc6t4sWT5*yCN>jb9+4DACE_vx zDgOG-lg>%}J%#f3lAA@}01H#J(MZ!@V^dwb+K1PZq03N09ph(9iC zB1%Y@x7tGK6$c)*LI^M4!nNFF8j#2@zUwia8>&!GNsLMtF7XO-feU*6(&MxhufA9( zUl+Y-aizb7_;KA~bJb#1ZVX)entlq#mG(9D?eyVgga|9hc7|`T%UOTF_PuS#zxd0D z9$$jX(TkEMxc3mg>JNl%dbjlu?VVzwD40iz%a-Wt<^svq5>#-JZ!*lmhd)89 zVI2+N0h&t1mI1o{Txj2{WPp~<3=G6rr92RFHPf|Hc0#+RD2X#j!X=m!v~Xu?;e{FM zc8`%f>w4CntA8+H$c9G|>Lr;|q_-}AYtzv4B`X>&JJrrwR}jx}Z%p@SS0Ix?8%M3p z@NHT0E=BFZ$pH2Tyswaoxz&`it5w1YA5mX}E|U1eA@`$+g`V?5U7p!=KxcLRxjRJH z)o&5%v~QdqOl2q3>-v+q)S}H9*vlAB@t7<}y7n&Y>QbsY+0jZJ(rqjmDF%&Gu5&TN zVlAp#OLJ(16Q+Nnw&a#R-HGfn&?YEYdh1e6#f_aK4I^@V|0 zZHNG8kJlwL7moPzFB#{f2`1tpTs5%d&br%gw7mp<-)#5w_HpYdI?f*Hr$BvV+cM*j zMU6hf-Wwr?^VZQURq$24#xe}R^4CYHT~*vj*EgFTKb&mRANHuz%1I?GSbD0qGeMDG zd)P7oyO*Zg2k|9;g)m=Zc*r6VaVX-_j$7S7gAV=?K=X6>C>}{&L*8cK3MYhpNW9r6 z{0Hil%%}b`1z3tB7d=8pJjkl;r3`%4Eo!xvOHefyVdb<;KbvU0pumd=;kZ$t0(5CB zcPvVbuI@-bOUo6UZe^zq>$MankC4%p;RxH1Uh(_e2`3kLWaTAX&$A0Ek7)#%ck{L? zc!3nv?qJXsAv}@nQw_=7=H07`V`PcS6GSq2D3LH>5XGICJD(8Y>-eV6o2%R+2QbX- z%jH!`k1*<4xBTh`+LbBQ?ia?@vy=xD*#-wq%3igjcvh}@exM6`#X%fzk$$uBd3E(3 z-3d-|t{=7O8g>G5soC%m?Wi@(#{N?21C z2MG9GRlLHyI3H$R<(zOnY0c$?>+CLje`Cqnn>ifn!GejCgG{KKlU< zG-_lW^6$XvUxWtyM_~1DNF)F({Rgo6_n2sg|M!5^KgAgQ{{gK2C7SyG9fJDjFz~-e zKd>?XE)4dc5!5#IVJDnnBsl$RG*?GZO!Bk_h7c}`W>_wCsxZF-EM<6zU=T8oW+)&s z`99q9j~e*fuU|CVv!{=&{BX5-5!VIO)YJ~V8S3~R9wsOjcl+;VO+GGO?AY5=Y0YM( z+0$!(7+iXLZ^B(O4YK$W)plhlr*6lsmv`trR(cV5XZ$2&sZ2qOgS#3ti{HR;Tg3^L z=~`MH+maqNC1-`TU`l1>oee)Ky$i^4Jw91gw7-;K>=sjJ#14&d9KZRhGhP<)$p8Fwsm8DZMiJun#WA9?si+iyH1=y>Ef5| zov-|p47kXo7=#1UN)E|``R?lTxJymS*uk{L<YU8)k(_a{PBaYm4kv4mT`=$*@t ztj`V^674W5g=HHwd#t(Q$X>gD#2oq_T??F zfv{7AP;=V_wSK}^!PKx+WKx!H+V%u}T9WR#uJec35lpJ9^YgTHZ#6IM9WWf7{3lqPGp@&!%xZw=f%Hm zcR~Yij`E{HJ#EC=C{H;_n@&MmjQY^D+ko4@R#~>^eVVO(G7uuK7`#sSwnw+vkNEof zT5se^5~2laXwB0fJo^#+24%Y)@w`iqQ*lW`nhh^N`*_T+{RlTMIBYu3vDWB0OBu6Z ztyqRRd_1ffVZE!!-GKhEQ|bDNaFixd0;Y7j);|QavhRm|^(ekw6~!%AtF}+d7@zzh zid%%;3%zlk{zXypuJwbZ&l_WE-L*~60L+3CX%P8%!B>&kZ0=Mte_Ohlrw85DoQ6Kg zt+!xo%U`ACn!;)20(2y6)rqVh%aa=yG0~>U1%~}b6m-0^-2#JjIN9!IYQwd&U)Ba< zC^g`m^-PjVwU_duxw=D7YaOTygdt||(9^WrTr@Ge!`>|e)M?UyZoEq(#`?wU*}5f{ zL0<%QF_MlVb=r?Q1K~69g&^I)2XcR|yk8B@+UxUfVtL55ENy;ubaP}SzPTKADz*{2*N%1s&V8I#nee96S- ze9^IVnf>t;TsYj7-8E$ABxbj1e!LH7uUm&+_<;x}9s&k(9tA5Qg%4`{hVJv2NAgk6 zg9N#_R;)mDcK9u8#V1~9OU{|G&sq^DAHQbb+GK7QEa=CJ*K9SmV_W#?d*%R%vf7PhLxA}%9iu0c`HQ zjq6sa+%hA~t|_RdC)E~o%7Q!ruMzwAbLlBB0n31w=YZbC#l_&|V8rn{9Z!l*^w+RO z8PwPs{1W))q7ldCYaiBY#DIj2!c<3~}2mjq@OWz3B{4bpO){Un(s zU@jf_F>`z1rrpK8i8kOa4o)r!p^#9!X~^J#K;>{bCw2BI)6cMnP9?o`iVio5{kI{B zSO^LYd>>c=eP5)@QzR@|i~F%TU~z={Z9((uB!j~xp5GJ|C3mwOpH$;@l4BchAq^7Q<_qrUS8cN<81stkj+%yRIF3!TmYG7Y5-W8gdkJ8nqDgE#Lgj$FpQf_qNzv1lHH%;E zM|FOQ25PGJEN^@M2l!!PeIwEc(W&cF?Dpm;s89s#WM;$c2+PoLD0K zu<}WML=Wr2Y+1S4*5Va(Sy>?SQD6B!DThz)eubnW48PjMK%;D3O{SL{DiIVifUUu$ zYBakL(xnI%ojjAd7?^pjC+P;XLTg`b#^|T~NUn+63?b86?5{jdLZG;mH~}OePfEf) zy1hEl_P}0#f{taskAhdUouu!k$pnRuw`glrD)HFLa31>DT>*p`LpXCiikRoOFQ2u< z(fl>-W~O^emBkGM=G0UnF*mU5d_thoV7coqnM*r|YH8;=sSEb{y^^-o~sgGpf0ACR8%45>i^;G8-sLf{_W1#wr$TD+qP|=v316_ZQHhO z+qR9&`@gx#tt6G?!%aTy>e^ksyPxjr{`KDLS-qATCKRrDMJ3k3ho|;1G z0hMyGWEO40NuZoUi8irV^HqH7xx78Axx6r9bNMLG@*gS>*k1|fX?mZk%<9ix$4htnR1lCM0PctSv;(@Q;(3y0`v||vRKK7@vr5< z`#10xqw_(uCM(5Vd@6mF|aA4M{>N!@lb4*l_qie&6{ zeg0LSfvZ&7-`0F_6mI3)^^^L`c;SaGjS1CLr`R*Mx9j)A!G*iHWZU$n zGb=6aDjqBGAl{=E{;|>q$H~TACO#BcZ1apXs*UKAJfX(eqm(eECnrPdYB`XHusb02 z-wl_LcfkGZxo_9rG5Xa^DS!r6pBV<8 zc&pb{7G{Znvz8S8C?njQfY2#a@fPlhXL1 z>i+Q60V4OvL5ua0I-UPLBdoxR*kA3v8%V|7M#|5Fy)SHjB7zUvxP=mGNdd__YDqDn zeniArH37gnYTxPwQcC$COgsL}zSgn`2xC}5#PuLVZfop|Jl{!xNmpV*V+7_aD%XE3Q>B1 zjb?qiUS1f#oX(=9F-8rZ8AREBUA4!leO7}KWHQ%o5Yb?nD7-T&v?cu{XD7nHZGqXJ zU$$K?wyt-1E1a%xN2gmKtLgo#AGS76-xj|QWy`iL!fmS(>P%pG3hHP4)*7Z1ZYx|T zyh*no)iEYg!*!KxzqlFJ*UQP*c*er!=&jaFYc-g@s=BGZX1qPLCcvDbn9>rv{>~kk z^Kv9(du*sU0^^1iQ{HclYYiDi!O4R9?K?#_eJ(5~`-=vUDkQaGD;e*Aha~R;HQ%?i zw6baH=%OW`%Z^Vsm!BKk*|q9)(S^TOtCqWj*Y70{uELP^?A_O?RfPK*i2KjxUMW$Z zszGSyg`t>C_JmW}W-!#2t3VP(s&8MnrA#+0?y*UqY(I~g^zID~6N?M1EA;$kjsw1= z%Z$e&K?kU4psMgG>s_q#qqzLTjEeZ}uP_fjNIhgp8x$1oqni&<-AtUzyT#SDR|a9} z^bnHX#GTpU2Z+t<56qQju}{z#zX~_}?dtYmcE(mgn0?X7waS};*Tt2(t1F`aFrbrd z@YFu~5v=+$keg20L{=phNcVYuV9O(^XzL(L;6F+Ai(LCTPi*9x=ysn#)AUMN2Mj7wkWC+RyUVP4bN?ozuYFobqW^cVyF@f}^xmX!z zB)ZO_h4?SIG7I{}^o{cAWYzHK@W->C`KOyj;{_vpxGUk>aIhrVrLJRd)#pca)XBo0 zvxE|=ADS2Nq|jn*P>W=@GB(LVRa3-`7ht50NF6eRJBeK0w7or$v3rusUdVR{P0a2s%hJxM+=* z1GRVUZvpMG*vgB*ZXe$R3rZSl6#@1&Y33=lOFI3=v2a{agDfF_C^eHo47K0r9F`J> z7vGs!Qg7F=3KE~0IO?LEz=EXykX=Sg=&}Z*44DE?nqLO4LroQURCZ6}h9-9H8VKnX z{4nMt{a%Wn@gM?z4TY*T;;d4-P=P_bPX@jH3m%=2YJf%LhVI{&nvaeSwdxw{jt+I* z%?eHX0-}0So0>GKU`j^rpeE6cl-iSDh8;FeFqw&1{%7@4$8N$m5XA4#d zu2x~io2>P9iY%@RX$^1TTT5eivfB&eH6+;=t8pb|Hp@Se?ooL(nA2|5F`SJFoY6R9 zhYd{p_8McE;h8Z6s-Si3p#cjIWBB0xp&yXeGb&^93S+snsGB`7bj6q~Rg`SZRhflb!@G-q|2%HgfdJ9o4+G9_TMd!%YI;jO|k zMPVm&y_}l@00lL+I2e5MQpos?h>u)U3oXz~R1X*3^1iE zb}sPNX829&C%Lex+zs}@WQqx^wp({s@c`U#bb3}DANbSxhg$nUa#{p!whbAqul>-N zrh@ys%m?I84meq*7O<8a=6n-QIXWXE!_DYQ_W`4&>|uH8`)a#*nRhr|b1^}=Oh)n0 z5aQH@2yB9x%EnN34lp(e0$w^vZEFIOlBveP0H6@&>MsF?;5BQ_*oyf}^pKqLO z1vMTDE~_7$(xtAC&f8Ms1n^y34CNCQi~@6}UYN*xl^A{b5k|bHKO+nou`XTQ{C=id z7Cy+hJ0O?w6pK=D_GK7ss2Ome5HU9a06Y8bj{p6p@G;ZrXnpvgtm!!Y+aCsYwZ9(^ zW@XTdg&_Qbxoz#JTNvH5RstByBm?XIT>RXYya64OGyBEgNm94N!UknwQj5{yspMOk z+B$UG+x`u(goJ9Ar=tk5$$qo^yudEjYlgP{ibEVil~3{SNGRswYUK>8ZXK1osTXYJ ztD#;!Q5G5n8)eOXn!tc#bVT^3i4#WB!_Zz{Q9D0=*VTkLgkw=hh0o)u-+ra*rS;~qk;oe#N>doM z&;g4!A{YfJ>3ZKE|7wu(4f~(5;s1sD`u`Cd{;#Se{~a6tH?Aqne9*iWZP z>!~|slhiqg)g?GGHk@I-J9-U$U7CB$g(6~=e)C^7d&_X_PZh%wks>CDBii!=cEnSk zc96`=^iTxXz?2Rdi~t`(0$SH2t> zZb0TK36VTOUvUP13X26n^^qqJeWLY!FB>s9nt%#EU+2zq^S%Weg?(~*pKa|l%ak@X z>9W7S1Z8YsgQ==VV_CG<8#8K=<^$ciqeO>z30Bzv8b9WGfX}`g z-yl(gg72WOgK?v2vxXOkzdN={)dixlaV@%qBuSid-~5QqB}m1~DVkSIa?5r8(t%L> zdi=gW=H|d~6(a91O-fP=MYc6yY9z2AMn>st!;IvtM#u_|vYnBS&7}q=MqX6OYfICQ z?or_gY)*}pW5D315iqJ6rK*iD57YznVHz@&_LBzD2)3NH3lmAoNSG3lrQE7sh zJt1-#rC<~Mo4T?y5C=A8Eli~fK$F^bEM*zeSMJ5OWdyBB=|F>~Kw7wbM@iWMkk~v@ zK(m0<5vosLR@swA$uiHEDEEjMI(DlMjN34wg;hH%Pv7U zM_#y+kvwWQG0+O9P{UAInZ`ojvuEij{SIUWqIP)^yH38)^H5+Ase_@>YDK-2Mu|I= zIHfl!2!#0s{^jUyXAw|+zV5SKiHR{+HFdvA&DPpH7=s1_CVvA8_&@@UuxRYs3I!Jq zk)qy>BjQm*K8-7odVAly{o=*ZoP;Z}$|(T~g*9e|kTY;~L&PeV{_InZcKAc-*Ny|J!7jH8iIkafpy6!c zGZIhip*?cHmUbdT&6skDGLG-q`62pClwe3%g_l@g-=u1F8g>m&&?qK>3vVt%-3d0p#wy2HbdSLtxZ>jICHzt#M_Xx7$jWE4a zh!6fgAM7my+1uOk*$-x*;P<|gDEr1)aLCX$aqWnKO{vl)74Q6|a{-(T_UwPcrm&l; zC>nR%>qIYJHApQ6#^FhiTXnnx$>eli_4TQT2k&8LGAI}SgO%CDbpV}fLLY`2tu0fW z&xRG-{_sRAc6~fb4hj(S^?E2x@Et>Y?Of-iG8`0#ufzmpT1M^2jA4rAWJxa9)iWDn zl`{;k!lktsbt$@sj6DfXC+)m51>8;8`>QySmQN9g2i@ zQaou&Br!tIDuGrjHG53g0hx{KM|^u^9z0qd#}zFXl99 zKHTk%Va--X9?A|o$?>UU^jd6mwaAhiL;$a;1!c3qBUn~9M@#bE(JzU7rS4Z%FRI<(SH;}FLBDg{+ayG;Jv3X(H_f3w#HEhnFVtbl!9#pSA;MiOHn;Zx?j#wD{f7m(5*XBz6t^_C z4`5PCNifZYv_ucPDd0;sJE>-KnGW)GsNmwm(>*=}O*r`kEt)k5lEDrA>tjmJRsM-R zQ=Z{5V`&9_Z5b2g@ZH03`I_uOWb*cNayBEib5g$k2B&@hG?21Azfdl^Vfc$9@lw8j zo#@k!@npwqo?^C)of(vcq43WE4Lm}T{|6$=RmWBhf!$K9B1ie(vr4D#dm@Vqv)obwU-s&UyV8J{rsKJ8m0fnq; zY?0HXJ%QBOLXflM$?20Es(*^4b_;c@c;g^$l^%!2GHiZQu(+2VLo*&mpMlQftG%_qQ7dB8>Gi}Z1t z2C!YCN7{le*U0746Q8=M; z&y3&fuaFCoqaRTz?f1czc5pwsFLzW20H>@iVf*5?nof&Y5xBQXc{#Z=R#|=WEW9*h zW+{&?hlr-$r)G+R0)1^baqj_E3>|URSg>!LChgg2vbanEE{p9WxdEX z&Dv|iWl0)BW6tKuW|nBZJ9u@J42YDM!zCgu?dyTQ$RB#I4T}n-fp(&;_EyODiU$v^ z8)QV`SMCw-5~bIDfBzW2w@gFu4`*pKNhTCpCX-XH($*wDYlWtm?RV}wa>>*gwMj9I z>sBS*FV^)jpf_v5X&GL@fu8=gcg2(?{i-~nvJ#X(FE{BSZ-DAx7^%Z^b6B!49YF1V zrZ>2{%ugVPX^Zm)B9TA>?0s`77zit$&Kp3LWlbPwi)7k=oI9*6rN5GpWI5K!1T7Ta z7P7#DNg{kVn;E4icy5wu7h6;a7hC1JM5J*br2NGvzCkKjwB{P)&xBpZ+(Lug?$q|W zKDsW-*CpS*m|?7n$k-uy9B$=Eu#cTD0-~eqvQtPPw=?cVwV3vOtHUyBMI?&e^{%=j zrkpzB>5bi4TVE#`w=7v`u^a}MzEaz$uC83G*me;;z1{;2?sw8Fmgg!bPmJk5B*kmf z9Vu(M=(kW*(l2JEQ$gOS)1-+|Fm*+C*au=JWmD@P27z7{3N_L=piOsPBaG+h?7oox z?b-Gx4&A$3`rGN};~AX5ijN6-F>#C@ol9^Z-5_OQwk0fd#k6OjX9a?@UeJB17eL%@wjsp$61J4<*lN&{$>%C*HTkkL|;-5 z={Y4I8Hn6a^&A0kY@jg85e5>1fzXrJ-o5v&9OKQK;T{@Ym)6+hcbB-Dormeujv``p z&+E8{adE#$ciU*%H3F;2Ft;^Y-<~=RI1scC<*yc(x4&M8$rusD(`Bl8z1h{V^5rvf5@r5y zB;+2&_=UBhcsO>L4v_bk;bX`IQdAt%dCm5f;AOF5XwK{Z$!5h`{5X$Zx5?(=(X&wW zeG^pOrV{Bx#!Tty$OX&*UOeY%5RfVfEL$6v3$G=#P)x+B3)4WWizk#d52*-dtJAYyZ5VP*j3>VhztNI`Y_BW&HINB4SlXWZ0hJ` z2Zl(Gb0faLHB3aa{R)CBM~puGc&?bQ0tafxS%XKgN`HKm>NV=uFeS~0^*1RAc-$>_ z`Q+(%_^@#vGK=68u|1Ho5pcv&*~*k zhR<`?V+9g8s5ttf2EtRtFI9n5RwNC);;8~NkOOSDqA0G*n+A?MrT~%Yw`Veyu814&DRKcc8Q0=Hcp~_3}D0uE0BZK24$3F{B(r)XBz9H17OkT2~u%v$` z35{xwv?RtTmW9VCClYS7;TFMojef2TAI*%j^Xmg77}=BB)g};3GT3R@x@P#&5rVZ^ zUJ&Ke%6X}BU~(6UQ@I}tRMt3pZQG)5yr*^*2Z@bQfMWn;$9{p|2Md)7VEOOZC3x90 zG%H@L-98bbl_%e$B+RRZQDIP_QF%oA!MF(YYaIf+F3S!MqX2P8E^p_{>)>noxGHaUMWsKCZTV#NF>ePqr#cukRi)PFccY42{=zpbl=l@GXoV;|;4qQ;L! z3*#wueR;$4X#x%yDFO;OD1-{6l{bp=a?Qkr4Kz9?l}4$CB?F_Fc(t8zLWU%lAw?lL zgdO(!98YUqk}5Ln`x%10+PF3`P6^L^0L`uZ?VAVK<{&<#g2fR~T})rYZV^Foj=9>* zy*oVlXyNhqH>7C8?@4fxxLqumKUs0qb3Xw=NMf;sxK`}noicOl5Ylr#?AGXJY|AJ) z(}**ujaYH%ItOQJE9c&sc1Yw$^yiw^^oSY?fS=d&6{3)ZVbp|qw|&sEQ!sC8Ry={G zWSL@=dCy(zRc;CVe=ha%7x1auI6igRqme80En>-SoAd&fPe+VOAN%QbZE8RJT3jro z$Azn|V+rzIlihq~euiBb7(pnaY*uCm6K2D`t6SWg?kpCtu=yB z)7`1o8^Fu!a-K0bj?BSoh($1_Q1rTUGBGgYyZvm5#t`(WNc1E!~u&P4v?9R52F3 z0oU#`g)hZT3V^`nNV8SaFB7MuLQ3E2U~DZ`AT^aIu@FyHSkO=AC*y^ZDReiNuMi`-aL#RLy#;^1|ZXGw25C) zz3kuc3k}F+QOw{$_fELK>P2FPAAg~&8qcj<6l?-bB6cFpTHXMKAAx(cxb{htxje;wHWAM|VgkC5rVtl9rD zDEx1H+W+PQ|DQ*w{g3|d|2e2B%a60ee-#}N`Hxx!Y(KgM|E|C+^3yESzp;b=-_dUW zqYe1KbKb5cxa8c2g*VN*cj=n0R>N;%83Zd{gYmTXqP*OHc*3GqSamx->9%?`b8E9W># zaIj$-zJFv301KoDp-krF0tQDSp0v~^3&LMeB<47;4&^SvP6~;X-d{Esh(7*yyWJS- z#a(XmkJwtFtT06{fsm$vMlyw+{_^Op`vfjM_$3SrZ}}bc_1?6~)AbR5RSXJLN>4hMxs$xImY3d4&*t{6eUrK zvdZXuAuNMP+3y*SIa^WuD&|Kal7C9UkNW9a38##Ci~cRC0pB!R+%}MMp;c+w6cTii zvEf=N#zAz^H+ZK0jJ+_Xy>`3=ID@l9gvOEF$5qMnGta`x_%DMoHmi=nl)X95ZM%=V zsp&xmz^R+i5$SW4+HHkMP*NlQvDz(~!YBfjf>kUfjVb7qe4aH%Lx57XN(Sn*jgsU) z9g!izk}_zdQaNrB__kDovX5E>`r_9(m<7~cf2uT9i_GDY zEFg&8^M!G8Mt>8%l3e!#^OyPII)y*1k6%vd>H*fM*lZ4-e+qKIc`YJlTJWevdY00M z3lY-d(L=;Y`PfBrIZ#X?8kp|*sO4TGyBjiD`)i6d(t9jtn@DU~c(^k;-dWKElLRz7A~!Da(K2MXGD#S)rmNDa7(9 z7V)i8ib4pstocWp2zLTOLq1PGg~@rMBPLZu1AVtsqVzaH9njsfbU9Uo7}lKM*Z+=k z0W$XY9;cCU8;W?88j|5tE(#Tmv_fPk8sof}Bvngf1M#za!J?3JVkXtIM!SeOiSM&P zMCGX;wu+|p>{NFy6YUW5+=pjVkdp0IOI@5v1k+mfO6U;lIC^u28g6u}go(P&pj(MK}gPYt? zi1_M9(E<<^XZKKZF~3=OnfX53%=M)(X97l;M8G!~8t=4yZW;Jz#(6m^+u&On;Ry!| zP$Rep4s#jLoBRZ5&7pP}8qgkdBWk?F+*Z`_jJ}Z4yM>PjukQ=5>8dLmo9gU~RlIJ8 zrtVHp`{$SA&#$*6P*LG`QW&oWaf>wU@;O=F?T>*h-oFjq9j&zY6=L=0tVv;RXM$=8 zN>#Opkz5D4GRG=`Ub~J^4;;ah-cc#fYI7D;qY6!I546Eu6Wm+{6dHzpO0zwBt;^sZFq8n!(WjVcUcAvN!2sROAOS_!`$?lC0&qg$#> zlzzLsNY#HqJ*@{h2akB#ZU8!>&*(WG%PZ4_&J^{`H7}fs^}itJi+Iphm>|9<_q)|N z>4nD%R^sI($;eIayC}-W0CF9?=vWK6G6j#AKpuy)SlRe>ZgaJ?DqehEyP@=XZ`Z)t zWwQ_l(eMReT-9w8h}kwNFi)oLR$3Dd&@ABMr73ZxwH6aI2$>{Dl}AEREtrKYVhc;|&BSjOlt(uE7MBYP&y-){Q`jdufG4gE(*xr7N9SnPegWw?1Ix%1uPX* zX4|=}MN+7B^L&M36s)Pv-U1f{9%oHJL~AIqk0R8HSJ)4HgOFXp4(MDvs(;6!uiv(X85tO(9M8_<-m!Oi9i)9my4SQe=X(L9Gre^A!>X9G7U-fGg zjfHF=WSTfvAqEl_%AXKBTT2uk$1oFO;)sZf6a&CSD3)`PCQ|Sb0nW`AG82M~5f+-L zip%2&ig7$=Qj^5&pJj|kA!~9guhIs zvQG$QSzO8&1BgPj4Scxtg|bcPu?;6BEQLbrUc8A7^BbD*F8wfQ_>F6BA-@8xtXGn6 zDdEqi*dUrG?vqud5^w}-3_S`m=%N&%`uYc1m5Dsh;>Ug%#(M6C-8krQs!S_jOmsn{ z1KNo!)*V4Pyu4gLw1zR-S`=v?vG)tq-Z(p1Nh(?4BZ{6siu=E;zNSP6s{C|QdNK>)Y(HMaHFS~ zA={((E)Ubm4jrl8%eBWczn*AAM(X#0F|?_KQ&w;6(1unXnEwjF}8fjp+MATSl8}rFm*# zrnR1^fJ@-TK@-@Cz(NtPTezw8Q0%2ZItx~qdrpTyw+a*N99;)rc|gWT^;gFzR*Wzi za_B6;Wg06<@k@lH`t}QqR>VjN{tl215hotL<|sZ)YigF7)H;#}3_;;xzDKo#5=?Ai zmZn}g_x!pt;*bhHNhD#dkp>rU4{%NNGx4RiI`w^Ii0&7v;>3l9>?I>ExO5K17STw7 zDwtqoK+6TGGa;p!01zn>i7g(*l?O5r*wIcFGHMdqu8*29*6*3q#H`gjg?{9W^mGM5 zK+5?Zc3q_zwZf8r@yhZ`t}k6f0D%AH)*5RxNUQ1Guy3yrXR|j@W#96uNa_BWA;LOp z{VU(8(BRS&C}Sw*EtoTqRSb4FZzhoO}~f^C`#%1%rW&m8quD(ZpgNHx+L(A7mzCtHH@7{ z-DGX!$dR^spO7D2_j*ig=^@7=1z3030ICt>p%DS1bBzXk`kI3&lTb~`Zz|;j3f)-i z8eA#Kxkx=Ot!pXzsPTzWilj#yG4na+zRsm%0ekBBm6#1+7s^LNR5iUdh&8_RpBcsNms5FpmC)sw)3%oaxu+JF-m(Os}s@( z;(=?UO0km#Lcqnz4HL|9ti=P7u&PbOvqMoW$#J(#JJ8wnI^yLDRUfbmWCG2#PiN;+bi?c0(GnvaNwprHi8Xu}%M7XVYm`{W8Px{o0 z`d&xULg9R*j={WW^<)u0S9uUYz4OiV6Jk1QT^25!DkxM1UXYO0Zka}A!}{+L;-JdV zWu2-xt4FUW^v0O}5`es0d(c0NgRI2lfuLd?AnG+w22R=}GrxXkKklsnsz7OJs=PW5 zl^s8-#Oj2VZXgn^hS;eb1vU&O8uzD8j$v4fS2=JxB^dY%bx~Mh(iT)D za5g3y_!CpT2rOCGRc=kL62FhEUZ4|?llUZR^sHSH1Hv!{S4?)mSAI|qshkamC_u?O zL)S^gKivrUq1q{TOd=E)HIwpGiz`w({*1LyP9XU$h+V~XIxW=Cz{1$B1@L#Ecai*| zYoV-?LMINH)|^{X$bw>=)M&$~Kn>AvZry9ex0_mPg%W4ASGr7^&}aitXhmKqpv~gw zXGg}c&-7PaquH6U*3ec|kl+#o+01Kb_i2UUhITEIo}s!%t#M|wOcV?;)$MXE<5v`3 zrBm5r6un#(NK-3pYhZh2V=ag;cXW+HBNMO?$Jr(OsLoayBcufTVZi z;2A$J;HRRs7^;n=w>!V&*O+bqNl`nndijEnf`u}(Ag>Whsxz<>*BGyWqEH0Ec>Agv z+myg48KVZup?>%a3Qfs=JN5u)xMvu804KbD+tT(&lpf9 znyb_^t&WN3$Mm)gZ?=~=H%UhpeZ&jicjHW3K{m@Cvf7>PUyjHTj_yzAm$&s`RhMPm z+gDsuLy4C=<=4I2V7h9$@0-JQ)`!dU^V8^J?|gZk5t<<2{Ep#mrQ6_LJhHQP=+p)f z`pB<6QYQS`BGM`C8=AkA-P!I^YH)1INULa5tS?vtWCrjUg3g;d-Ga@GewAEZ*-Z#L zs@*RJxEr>gt*@^uf9Y;^^ute=kvAab!VawC(LjRw4D{+3QD zAx%+FVQ7OuS_D>Pbe#_v-3mB>t3ER$*crKTjQ>r9ke6mOA-f(hI!nAmRef$L#C)r! zQg7ZT#GDHyM*pwpPezOA<)v?i%@k9xr8l&$Xv#w2f2+Gj<#JkeA4!9sO4H0`%`%zT zA`ffyw9UgnvSAh=44HZPz%K#^YceVal#sThv;SuQNnImnrIZNDAW&xwwmM_-M}^KO zpjE}5^@|ScfHmVsx6)WnPacuh#Gc*um1JipzzK%I?V^J8(&^dL^d$4!6D10AI1X$HKeR#^NZ}Z50U;b2`qHa^^Z&M`>qxFC2mAF^sMw-v=9re{sB`IL;HL{mwOp(bx@J7Siw1N0&WjE_+Qo>xode zRl*0h5@D6pWKfkO1C{}$U^bq83J%GkJ5u>^i8eFeN74N4XXd}(f^5a*$9gx>v!7yn znv&+b{ObC|aPA5^UC2p|2#z&3t-~E2BFJn2R^T+5igElck_82`a+=(e`^Z+C-D05g z&KJmq7S>5QrtS^vM0r3oC|(TdM(Z?IlRc5Us1-s?d)U+-{FB2Zi*~FCktyQLP!Yip zm}j7f!Q~7Pz3d*1wsZ34Z?ly>9Nyjzhe1}zIj`%GVip!x+VKL|-8lk(RYNLyU_l>^8qou2er#(2bKfo!B#2b%Ra-h}+57Z;XcMGms@NHJX`Q@6|8xseF>FX#5 z%5i4@Hhyw_wDa@v)Nw1A!ISO#lkWTNWj6|sY~=nv~qQXYB=d6l=2 z*lbq7!O#24sztiQqTa~OM&U)|O4v)7iqE<@t4eg?Z?>>Z+VMVKJzRC{pBR^Tp$9&J zrU8LOOAJoVkknAP!dkB>k&f>FQbcOS_-;(j3pmF@x0jszVN3c)_^2oe4WdxU0!bSc zVzD4Qzq~o1eBOx&wN6UhQYpTPLp*KRg{d#3vSb3A&<@Os-bo^b{XwqwHOW-JcMYQS ztOl3XcgPPU4RuyfI!)kU1QyGcyx2+N@KCt`Mkm}{cEv;-#M60i>nElQ%^7EjQPfbQ zRvC+@O989!g*yZ(IgkOZX~mgOSh{ODLhL)K#F8d+(m4K3HNVa%h$pq8N2ma514osn zj_!+*q2H!Nq~R{PMkZ@jE?~GSfW1;8^eey6l8QoIR)kryuArHGPNt|4ryWe87Ple+ zB-VFruQ5q}b=DWh$>1n_F+n~_W1s6w3YX9E5AL-9m|m43nUKn0EeMJ&_9D2KSqhtA zjaxL+=}?{D7ElG2?lvoBd@ALMU)3Fv@^t$V|+cFrhxd zJa?3_Eh4rJOBQS%d+{hrYFgI$3Gv7+DTKQ=tO!U`>>aDuK;n%>)fj&NUDpq_{}w63 zwV;^M3b8(>^i(KlREI0NB-r(-9!R?v_uRY-Iip4JX`H+AFsl`D&8R5#b(*Yl1| zASQM6_h?Owxp31yL?psdHFne7KH6FEx*;iVw|eU6^jENc z9!M>#>+*^9Ix7?R^LVwqxInddGrGO|M$+fPZwtd#4$k%J>v{c3`*}F3YM54!5ZBg6 zfM0_HxJiU*RxVT9T@r_&o1VM{a?oU^g=)$rAp!Q>ap#n^_H`A=GdYNUc=*~H7f|K! zPW-~r<*h><*D%%vPyw&Oe!)v8YrL4X=-qx8!ke<*nX(ck=ztB`0y!PE;-;hqBcoC{ z3e3A()TEs)hj*rP^PXa;_Sse8qX6vSM*+V#|1gMM%cr`|c%PSw{D$JIauYPf-rNn1;a+^J8+I)kf!IgWKKX z@88F>h0njsF457&hAw}(v~Samca@IGN$6c9GqDkHpk}Bl6)~GuavanaKfk-P6LS40 z{r35acwib=1y^_SfnaMCIB1;Q`rPUIPk1i8zYnL|;m}?yOjv_gs~JkxDnKBY36A(H zNFVjRJtlOwo8PU4Ku0~gFPc>jUCXa1zIca4bvYMs3jA#{&vl%ydCRVrGx_Vwm^D!z zq)S-?5w9y@q4e*}w4@AE8|{(UUpmaY0<<#n)R{`hH8W5dX;>DVXGQdX$9n)J6GbQH zE9mRxtHgE|sm;#)A=thjD?h#CIeGL{18RBg`zIr;?m)RM%cK1^Oh_V-rUUhkyE^M{ z{J0J))vrznJEG2iGGNiLDupzb-74Tw;Z?TVG9lPQUt>)(kBv!T^&KamxU%ard*Qjy zmsdMt>RWp)fzF3li{Q=u+ruy^tQcciPC8~t#L}e-U=*Y(h7>~@_;oPLDNqTmX z)CL=0E`>Wfm&AqtT}L#+`^DFrY`Xz)?R_*3Z)wVUqhPjPxL9IAgxCxkR7N|VkF z?NdhnlY*L;ua%~bxS418=BBBV_JI!0ty|~>ieWK{{M-}tfkMzhCrT5{ffjadg$WeE zu$Yz{DTg#boU;DJ*9QHjxt~hxb;RT!8xTtrLfl+QInLZX$} z+bpu7Vp)DP#;tyy=`~kgZ2RfYkP=LxG-=-uKUaXo#7~3%@oIyVLM!MAew6-GLbNE% zc`~DaY3~n3tzz18G>^Mys#QS599)@3n1YyTT?jW6!=UhP(70zVQ+HT^_a&^M;qzhk zY5{qOQGCg=N@)0_BD|zhL2;l>yGTgh8Zf50H$(L2{raSSlLx9>H>2!yujElv;n*@i zrbs}*LM9oIDwg$ctqJ8}NEpjN1K8QtvbBV} zu9$6|I_zvAWwMD*tV79~0}7WZdf@p$v}Y<%h=HhGPAh?Kb+Yv+$8v<2DBq zQs-H4L$_E!tF(lX+6adN5!2=lqphQyHAQQ6&w_nBq_p4PCgPD!!zvEuRUtxK?my<} z^4a!g00RA16gH6lxdSTuT3f)W8rEfez(h%C=UCcttj&QdftEzl>Oyk(LQ?CKWqs4v ziu2+)wHkSaJX_9zFAoxmy}ICS0t5ZV$bMP+aWK^)vn(lkOS zdK;O64ytPuOMIzjAD|h>oiD!MiU-u7wU&&sDl&ZsiFJqq*&HRTO@q($p&+r#imhL* z7OYSp6ci{$!>XKfL1OS3i|dZ|_tu`&I#lUZdvI#cMz20ct=S2|JFdd8Rpfyh9w)Hq z$POc%&oQCqr*TBA+2Vq#QstWMlNZm~^|*%5krPcu(o=ES(p~|b2XSL!dr(CfPeU%^ zuH~paWJt0CY28?ljSN8>@usQ3g^?8UD`TlTL+PcgzeK1IMr`d& z*mo(_c7)CZ^I<6>j))mbW@<{aT`dIkzs)>iYny*~p}yLXB0R8$cAlhmq1u6Epg=py z*FWBDVZ#h=>ak7*D8l2^W2^h%p zZ8=;EwhPE8^Ump=kyzT%?MS!+TbBm|iO=aZ#bhBtN1 zlmHdzV0V0^ynBAHce-riaXNDtqRDA-?f7s7j=O*-7&G-+4OM$8W^i`bSWe(?&dBq{ zzRSS1ypE87!9>D4-q(Y@(8B0PRljf8%@J@kkCV-0p7irv$8=HvtqdfJ21nr568rbf z4m>5%UfrEWo_1~2g1jre)g%vR=jc!NkAM8|bMZL!L{MoUNiCR`Vre%2w|mk!8AG(m zraZ@0MZd0=VD|9b6)Bp_X7J~A_lMi_Zr(#snMc_7^zQAS;KJs%_odb=NvLPMSB-wcCC}QL>`%BX!(|nap#U)F=Rc#2mkNMc3-pOZWeHq> zVz1^@2*ROC4s2M)G2UE0mk&V)uppKZG5#k`Zh3gdLxcoQu(6QHVryB=7hD*_pZL5mR?=l1-#M)*0-h7MSGE2kz()uvwK zFHFW(nq6Yj#B!6zEHAq=sjN?Xnv*?AQPXGv4K@x@mF%Af^oI`5Sawb~bSW(y9n`MO zsDveOcUBQGYmy?}XD`WoZ8Fk%)nBcNe{5TvNWR|Ihg&bFY>7!&D=V~f zqkva|*=5*uu+Ob1oX?~~TF^@5xHv1$t?lGEH8mj3Rr`cUoiXW2?hh+=&*aSgYGkue z=uiOGigLOwey1S)^{a%eVV#Av>eru_B<}Ba!3Aqv$Y3_27h!ZfD$h-=?95%TDNAMw z>BlD^6+5;_B9vB2|Mo!B#}swiK%LENWJQvVcHlo+)}%D2nV*NDu1!svjb@?~sVhQi!ipBw zJ^(N#YO5VM&fAW4LdqAo=9v;EZo(jHWRk>cFN*ujOi*dFP2u-@H|eBH4q-yDAcMVQ z5N^rr0aF38V=zbFen@711adIcK+#wPhm%R-X5`1d{3&CNuqzY-=f*(>-?!x9s7Kpv(?q5r_aaNWG0!IEY}~l zyj=5j_qJJKyV;1=V?G8k&w8n=5MV3;N~xJ#GzDHi^Ta0Ng+r4kUnLtz(1=I_)oK1? z7J1kYzA$azYagOu_%ORtO356>5utbrd|du8F=II|!yKZk+^rqX38Mb=d$CFdTGMs* zR}o{9*HvKD0V80zLFXzL!U;B+tXJJ`r4mgk!IYmD%lK8&g*a=hXi^59bSA(UK>Vr% zlex0zAp-%gr|QT7-gPAFz|oNyq|RkJvn(l7U*&V4t>o7ICzB4j%`px%SuzS;ZLC>x(R>UY3<|7oeB}?sLeI+|OpWGQK`?7vtaEnxR zt%!lGUJkD%e^44OJwj(nXiRRYY@4r{!mS@G0B=$gjXMmz_KEPaZdl^dM&wX?&Jr^@ zJJQEa2Xtb?O*vgQ=6mzb3(o%F$=QZu?Lagvu zbfwr-m7G&XZd}O}LFXreEuc13;AaPrHn>zy)ySmVU89 zTnTIMk=I$ELNl*Hl|QxBTM&$#tjZf93ATt1qJyz=-wFe+4=|%3b12wL?U(+=9e)_el#CoYD2P$u3SkwsEKcm4AjL%?jhmPW-JS$@n#^p zJMct^fNJ&aF#`AUImuQj``XVqk#lz!`FSZoT8g@ za^xDDz`Y2)aP_VtypYMe)SIEw;>16PN`u@G7mOa}#F3R4-%n6j{8iaq#O+M*MliW> zkA;Ac!Q^N6o#+!}cs++MZRrw6BetcY@Ok(K%C=K*jZp+m-NR88R*Pepp}0A{QWVkF z*u@~7sY7<2th3)rCBQ^tz(m;UNtse-#c@DDOF%WTnB7Jk>7ERt6UZDX%Rar{o=0i0 zWWge}gz`K4@9%Pd=J3&cac!=`{0^8@_);`M92*U+rxD^lE2LMLeK2 zgl~}+YTkQXr5dNGl2kaEAZGr_B8}2e8oft?0BI`rgbb5W%54+tx+2_}zXdv+LuLlN zYS2XSW8#Tvwu4}r?$6C=nzQE*$-Sv3uqO=5P=wFZH#{|XM~~A|ulEt_lGp${!Xi@# zg^-u=DDhkTE&cAFKXtqOzFuDLHeFw@uTu}-Jie|@zqdXf4@o8m1s8;V5p!q3@od`8 zWQHM(BOusUKiB9b>~=YuL8-*V@wCbkU-9-2S7R2X4qv4sTLK@qJpa5WOFN9+=1UjB zhu6lZ_;bI9Y=^Fcj=5m7_w;aVBQ!pIk3gV5f*#(`G1(DT%Q92J@%M&M87pOX|MmV) zw4Y~4kowCrp4ex*03J!nr%vCU+v_cP!{2>WUN_9edEu>*TlhE{G(YzGEgJ`F3-Oj! z3QHS@6d8xAUkO8GLYNsdYu_hkZkHA&#U+hF9C3Bn2}rG!DV!aWL~kh^i_dJu3!!uD z*l^lb5W3ybO`(f7z3*`%;>a_OrZ$$;(9HLb z9P8o`!HX^4qY_Y=NNfAg3fAs&c!Vu1J(<34ubZXph*3o?Z6Op zlXcYiX|as)puC4@;T+F+?`CgYwBpF)Euuxw^C?LrdE#96ej|tgNy2K&JCWZsHwI^h zr|W0wofr|k0M99selK<_^ZU{ek07(4^6k8Uy@C^~Mr<4Z%2_`Vafr{G%)d{CF}D!6 z`*-Xv)rpv5=rQO0MC5Ex+XqZaYtPRF;5>cl6BB$K)CCfV^o+7l zm|AbEA#ZnpnJu;oqi==8ny4HUusOhrFc-HTYF|e zT>OXB_ssT46DCFI1RPad-PTHRO9#&bbNW}L3Jv5O%6$vZh5IKi@!8r~vQTn;G zAG}0fXq2u-D8QDWhDWGklQcY}1*riI_Gt%Oimm#71gDi6?gwxuC$kaPlU8QC%mD6(v3f@=!RC|QV|xpL7f6dlSW`%p(r z?Kd8z5?LBY$FCgAo#+w$0!w~Qk(%@)D}>chE&#sJt2wSBwZX{c*t#1IzUi!xDD5`f z$m4w^v~YXbqgpbpsmZLRaBEF;y*f${C<-g%kl;D8UEW5zaHxo0)boajC+n@Yi436C zjOCtudnAi!(4Aso){)&{IJX2OjN_o@m0K*%tXf7bcDCYWN}M1o&9xCzVv+A!EqHR9 zQsTIQs3G?_;bpP?1!5AxVYCFfwKx`_9oP3x;7BeDl+rz&aoSuu%^`Rv4nyOF8&LbG zb{>*2Zkw2iVs*nHT-K!&wm3@7(DY&m3fzhsn~`xA-@wSV{9CK{H0kP7V-~8d#dDqd zU$RS2BK&_zGb`6Ma?R$i@l;!$6 zmZ>tJxxLe0vbnQe?va-5n4e{VbD(lctSfXV+olj+fThVya0s%R#t;>QtjYZKmauW> zfKkJRKp9Ye-w1FewDh6_6|0xwg=2b(h>btR>L-TtImt5PD#O-8)YKgSITG&3JlbrLc_T z$8Cly6p`WrB#EKm5S=4lmPg!ve82_As+GaTEn6MbZ3iL+^3%xuDeDLo@((D{p}Gj9 zx`A;0I9A5EJoi~BBT`EolZ(5Bx;LJY3smVGAX6()$N2dQ!J%plqFs3WiN<*^GkhT% zOB7aur`aQ?kjF|$N1x@C7xy*9*a{v(ZRbB3*jU{7Irc6Bk!_=eB1@IQJ32Ejm6G>) zYD7N934NQh(K5;!Aq=t`MBP9FhiPavmmA#u8`ho{kFQ$y%SP&mWKKBN;8Ag`*1j9C3q+&`%q)D>Y#PJG2F+$wZcX*TUN3r6Fbo zq)bXjQY!^jk{~58Q0`i#bt;R&w}>rG2r#jru@VWlM;J32p_|wsZbyi+Eu0Px-L@t9 z%Y<5IP`zNs@8p2t5lJQlBDD}2v#T}X0s}|ynk>d3q~?A+@VH5y_XO``xtiq~ytq&U zXdR`tn66rHXWDYw^GW|m9}2`Z5*h~us~&7=jll3`-;D@0yiQDzCbUmHdM$-ll1oK2 zC}6WOI!6qsJ}hV=AXX`K0fk3%Gz#F9VPtB+dXZgP^!$O6F)oUd`~DC5;bj7y6bndf zP#O{uP7CA~!Tu2&p!N?%kFJP+_5YrwkaBckATLa&)j5$JlNu`%Jg9J@)2KocNecQ! zLTj_Tz!*YJU`;b(a=DNqcxED~Ac7QFqN2co^7xcC3>e5c;dsno)G?Ylum~6?HVJZ$ zbOB6-X3wzYeOvoDd|9-P225n=k<6X2*#05S2k4Y;q(7bb3zQDwrlVjU$Zc%PcYRb3%zz0pkJ_N;9z%`-8V;G!Ym4 zsA@m_5{U!*mN3_C+_)?50DT~3RayC1n=HV20xA-hgSTW8looO|C3OOoc~~C$bnMUc zc6|F8AyQ>TgAXua`}+*B(%Jv@f%Ep#y6X43Gp)w?NdJ01{lsr$X3jbb z8qI-y4r750?hTxfy8dPH*n-htI39Maub*qFVe|95K-k&)@oDR3a=K<4{&Vo=;trQ; zkMD!==wkij7za)^M7K|iAkgTi7=8U8zmMIco6o1Gv$xP+SN!mIY)Rgou%899N~lMX zJCfL>T7ysYUztA}p`Ho6HNmc!rnn5TG#*mePiFlJ>!QAWUBDbzCHzDi#%G|9OC=ah zxw5X~fE!nzb9FLyHzz}5P&DNV151>PJHoN?EYtE93e7JVnF6aJ?BGv4s`K8Jxnl{# zJXLbwht0`d9(;;|D0$Y7Ly)*qk&VeJPdR|Bz?IyIIc)0ppxlXyCPK;j@`#jJsk?AI zK!#ClF6Eg-{`Mk=wKT#DWAM&WtpxU+YC2_4R;mPpgdwxn{xSSGcsh2q*J@ z*U}fxJ24Ov$EF;PkQCrdCWN~c&wEba4L-^vojOD=8$0 zNsAuxv9$h3_{@+j&WTn(7GJ?=go5tPxmSPeivOqA*U=*f&&TOEMlatHu0x})_4T{O zz`Ff@I=_ET>O{%bpif5yr$k6_fO3dCDx9D}HuyIA3aT>A>BYnRgrZ=__r%Ui`$Ol$ z@~)#3CyfX8UXH9Hf)u(f{1>*Rh99>3nf?my-BsWhoxLy>h}5umZA_6Qy|um=vDyBY zucQ6TYrlu9GxJ}M_m9QL;b(UBeh8QLmJW4uW$Kq-IDd{F_x!wyXx_4ic-=Xko#7Nw zSv#;Oc%++5wCH($x|fJaI3*BD-ksga3ajj?S;!DKk0w_Ys1LYthlO|~xl>S{1&03g zUt=f|!ZY^jBR%1{$)nTSzS^w@G&A!IiSyKOVS>CtFjui-r)P@^YwWD z;c)wRwLx6}5@L&7`WOt#|6@Up?T~=IV|Uj)mVlqQVjACvQO1ux$FJ_^%|SfmFP12F z@jcvALnP+7JqCs2nVq2CT?$3L1_KZLji#Q7I&Oai(E(F^}uf{y$6F)4`9MF(RG@i7oi zj_cSq^KI0>8Vb6M`1xF6ABlQ;b)X3BNxM92cODXVZR&m|XIb-!5Q3}|Ca_92eT zb(8gY3PfF32Z{S$nlU_HDoXdg^17n90znk3R}O>aanRs)5?}>ceEg#HJqtos?x5)% zvVk+hqHq?RBL3LaGuShA`(@CC2L*DpGCo7N5y~kCFc|JVP^LjHM~TO8r~501(x$S* zxR?XDQH(ky0iGjpdSPtVoRREQsYw8{?qh|$xr`&9qlB_%w^KEnHLc(K zdf`!Q_-`!EqEz`L$aSq)7~bv*-<#2M-(i3RJqyAq7`SwN%ui=7q~1>(iaH zs4UBtGuYXeACv^K0$(ap!ns!jQ;NER6?F4?fJhZhy?+qCZRVYa$WlB~z$Lf-J?<<^ z4WHSj8gqOsMkHXO4iKi2JC^~IIc{Z>hUktYT`qAi7<5p6sE3eiDlTRKPfA(Tp658A zJCQ#rmr-RBM|Mk{flv5-*W{jzsw8UQ%%9@PHjXirAY4w>d^%=!AZAaWMH;4p7K=RM z9&udnu}i~QR31mqNl)6D>L&rVM{gwgJ=g~KIPxQ)nFu6`gw8ahM3dwkjl>gzT{gTC zB7yklMZ}Bbd%8D?Mug`jDuiz02?D=Q0_UA-_oB_s{C1H{5Qeq?!JI$mHy6tnF6%2mmUnmyc(=6MJnQWQkQlVHE-@e#>~A5jWd zprI`@A`>UDWgMC>B#^?XxG0KNZ#qM}8G+kM*P+2DBTbg$FzYOC5|2EM;>rc#EF2x{ zoL1s#{sq#Q6sk?J4@wD{~jA&T2T4x;Qgh999Meo=7XSJ_o_?}0H5 zC*UgiGAw!?5uUy=&#Xs;as*8DLdbRSWY{-P^c+`@F6G2I14fA!!`^ph5ZA2(_x>5@ zJ1dfI?CzyBa)9nY0#*CXu1Qb$^{SZTKcMkw+JG*^iyYPGkcKZSZ}+k@oXuRsBo~Q& z^qY%63f3btG_S0v^5TnQAa-s<2~#2HNC8eBPjf#DM&(_S6fH-vQX6V0NUlB{({z$h zZEL!D1m5$0Lz3tWCsi$a^N3bB0cQ|v&4~m3pHuuJA{=SM(w*>MGn@~TJ5h`%th%Mz z7L4K)L;4MA13XIh0XhE)jQrqmm(&5v$=#9X-{QBXG3(zQnX_sQ1!k<1kx=t7L(_fn zu!GIgeV4@#unlnjo|4UChc1`aSW?}$nD35_Sp6n()V>Knh|*9J#o)_72*ou2HwNpm zk9D<|u+Kso4&utoIS?&~ZS7&P2>mm5vhg*EV1?+ht(aXD-tR__!-699oVL>nz#>S$8oNV zd=F*Me2A-rkf+d`X{F+KkLz@;Sg>|sU%ara5M8%TvRttIQTm^0Ki*Dr<;_OXGA~nu zi~0B8?`pdFd|Up0oUZPL(zH29IlvTAukDy8`M{>-X>`67e=N>nPh+0ySf@kO{B{`*kwrtNFs>;3XH^f5#IS^pM;EFiM^@{=*h4&>IOiMY^ZVJOBdNiM4e z{;gEem$~)l%mka*VWc&?kP1n#$4K8$IN?ouM*6m0^i2}TBqml?*2S5eZB5pKK#6Usz`OOx!&&dHhlVgn+*J} z!?S8{Dli~i+(o*wvA5(uM&q6Ll%Lx#jM3*I961jJInS z6b?qyul2F%pbOp4dGJXWe`@3FAaMDWcjKE-RD9mO8|4sG+j`J?xa_HgZg^-!H$? z6?}@c1u$0aLV5IeJ)YrVadg@E4o|Jd1)w-~bP{mlFgYNXd&!ZQ3xmUZp&ozdXK?U4 z4LRbuP+VMCrPdzD9iF&=pbm8*EKZ!emJD_))1$UUI>hJSmD4t$DE6 zYQ&6I^?MPD5-OMe6X!Mvrd!x6n;vcOpn%hjCE?5XM$}jET-ZmCV2lNcL{ToW@kmBi zh%Ul$kaS%XB$}YAYKDpeG4RL_h!_5ei*(p6a>*T0c(o)9;>f5-x_0D~u_4k|0jSTpUHOt^QZIqExMH za9Kz-LtGUS_qT1V80eZDS|!}M97SacZ;Zo@<;!*xGJ=yje!bv?g`RSKC)*B)ye-eB zp4A?&AyJ3ZJpD4f6dBWjM{D^bUJbwKx}&QOxUWv)q6*G!pPv?&!;yX;J4dTl?H?W~ zSi68YVX_a4N3Y+_A_twAI7&FLajmWsG_&1V|9$@g3YAj@`fpS<{*jsZ|E#L zRn_F$AmUfdXAq9ZPI7 z{d(@W<{Y_IZGoFNAL;2hW^dR5G zXB%cG&R;gf%5pS}49>C@$Y~p1oWDIOLGcI32G^~F`6!XnAV7a);&?|N#1NAYcgzz- zdDCI1awW-D5AX!)kAM^QQVrG|Y5y1vE$HlLkB0TW4i42-z@g}zMe-#>=cd?JOH3X_ z@?Amnr|N$x!;pN2Z$H`GofAe)dR0Q#bgVgo8OD9Oy%11-e(-kq+`Bwj`I1pzg;kij zElyN-8`WI@UY_uq?($}4+RB+vRWj$7?+O?~!u5z;CO1FWbl}ysAqO*_b=ZE#r?oRBRx2fV-~E~Kv$tSeG8|G_(yqx|Zyy>^LGuic8}D@) zUg#dQ>_8tJQ!vBmI!GNA$Dp$geW4XV0aSzLbBjhC1`nI%n6uo308vy3UDI3GRK>6XwH>*Mg8d*7K$2c85X+*YidQyA)XZA}TH_N3 z4HU@GO0w4*6Hc+{tgen%)+#`0qF(v!|D1pjfg*7;n-kdNLnylzjF^ zO?h*E)fA$v zKF3;%_jxBcoRE>Zc11--3jv`kZPgD}Kuf9CnUL{I$Svfg3A)AX;dZ-e5Mj0r)8o{C zLJ5^cO}cs>EI@FtdQT$e=~@?wh)|(T1g+*Lb!hH(zU;nQ}$?>B+pey2Y0g z!(_j2lduw2u5mku2Hf6_D^!KZNJug^7W~tTstmkootvsG`}d7imx;W2X2s**=JcAB z1ym)XiE_uFCMVbeg+*K(EDnn7>EfG~Frd->iv%GDl^5Q9usi+w_#FpIXw?z+piJHv z4?N$kX2io}Nm&4ol&mX!h(G|9dKg>!g1hfeM!8QnTO~ef5zqVzzS`4!NDUW@@JC2~ zStP=?UUpqR4B#qswSyQR{O&_e&B9jXTFm_4qQqe4tM0=EQ;m738v|rjH)WV9-5}Va|-6$M$`@8@|yzNp@JhA{I_i?J$%GLFzy}SQEyduhIlo64zC}I}c!ZeSM{dLw z3aMyA_ZOYI{&Hxu-yeE6OHZ`8Pa3BMh()<6n~?>`^~)eH^}{Lv->XHW0|S_yah1%5 z<`|OLU^kfxTPFS{rF-5k&+Lr=Z3;^RXNRT$D#Oq-!mL$`ih)KOal?Fa&?%nLM5rGs zT3-y4mQ<^ZY2Qtz8t*Wx!&1$WfoO93SMU@H6z@t&6!nGZPZxT!f!*7(KI_x!x+k}{ z2b6|a=O6#>N9)F{!r`$|vqhzy8ue~fT`etCh@2U5xzzn`5OaF!pR|#znP#`CYd4=i zWGz%@fQev%oh1x@7Mdo|i`lO!D?qs&67MOUPm;vNdQhz`tcaIgW=3X&j)L3@u`I9m z+rB)14gK2+kIu@@?8dFj?m#z2s4d=7;k_|>bX47@w@JVHJDrVrij2LXdfIH;ycwF2 z05&3(?aP6?BZscW>>`Jb#QMmx`gLB@kdY2VZ7LF!OI8hF$g63n$bQj0fhp3W>aD5h ze^AK*Pl-;gJj-Rc2CqL{$)M6w8()z8Qz&fsSH7KYOmSp-z$9^!A*yi+ejGLtH3b}< z+PK*tEtm66a7O9bqP5C^3|wkX$T07Sg$GDTOArs}Orr}|P(qp2{(`%izD)+W0{j#_ zq8hy`mZdEfA$9h9#u{6YVgOsa9~Ht!q)Sm1WtQ zr~;lQ=;A)Qpa$F|ZJ5L2PfvLxWcV#C7^_U4@9T>3*NLx9fI8l+vHOC~PZch+=ef6(lOL34ZA6db-P09J$mPT&uZT zd$|KB%}S53epoIUJTiS=$Ve0< z%_Ny+`NG$vMn4izZaIon2+)$D*WFk!%;Cy}id~#upiG$noI*00alfR7aaA_FzF}@e z^oIiNf5JTK9DFfZX!PI##>y#=A_+P&5fQ)e5=~F*V_#bicmgk)p4*1$Z{#Z$quqOU2l|)C+Da z`fWts8q^muAmrx{CD@-Ir+UjP8JH0GUxf!MsodXNsGehZ#9p$ z9pX?9cCnSffJ9eZC1Po#{PJj-hOE;Wqcy?x2ZXg)GcgsNyw;R5$-H@o#Nfv`5?ppQ z^wDqJbAE%usq;uK?N1deoXeb9y^M$35M*^IinEC)Ypk{&sZG7BeA#$jB4ScVG8A!= zLYIgFR01TGKqROtuowriL=o9FF*W+A(DYQF9Oqv?9q&QYBxL-gK@Hu0`Ii#aFjFkA z&p|NOV&O$-K}GM)#Z5dky(+f*P_L)Vj`j7y>nz^a54ZN!+IP;3ZB+QNFFs@S`SsJq zPR**ae0~D{kGW5B-qk#>K;i&76jaHTFKl{aTyR6o$g8YAj65j`oG=s>AtQlk)o(tP z*5;?b*^UwbA1~q1mD7iD%g+GTa_~vuTGB_WSoMPQ7M8f!b)!ygyR$%zTcXAIBe?i2 z240D2Q+B+8Waeu?uQ85Db0XiHyGE6RR#A*Ndj*!AzPZ0hCv4d~723%Zmg5#Gq@V%1 z*D`6HccidwAQ4&FS;;4Z14T&h4OfzKh&hOhl^#CHPvO5|GylmZ8jfDY)4}wcE*P4d ze)9wcLnqU3roi@ZUI0h0Wa@11>SS!{O!&VP_5Qa;;D0!+{9j}<|Hbg-|2LaqCS?CN zgZVGS=D(K<{N_ggTQBhcA>;W^o-zNyc-T4F{tvCW$7A+e(L|d+q3J3T(4_&QQaVr0 zfj_XBH*H;jWe|XqW!E!ONLv8zvc3XOugQN6r$|YooECvr0bohAx`|=Wj#ok3YVHKO zy6}tc&+S#~)m-iQ6>OCiD^j%|XIEkJFK4$hz`eBN&V#O0tB$W)HEtF56-kF`cPfk| z0O^|vu9i0(Yqf|S;3$}W)?l(^9TN?KOv_O;rpp@z6nMWWvQqW)#ZB&BQ0?nl3Z#@0 zESOx%d9hoXe!i-<-p@xz*XMS2oB4($nB@7Aq)+7rKjGm@_J`ZrcF(W7YpTh)pP}}? z9iO(Wy}$Q=kR6Bk9}QvC1%SWk+kMi`)#R?O%iAa9c4!Bnv0v`61+8}(5KJAWoK9ct zmjI|A@O&jb-_PHMlPOvoXL72xfsA~m$+lcf=Lsqd9dxfTHvi1`P6bjQF5Vyr6)TAK zNL1eyKx+Nn|9S783Hi78_lEU@+ofebsd^|Hv>YN$>IT&$GSu>MN?)V4ufII6H=r&I z*cz4@3&Wt-QPrSh!ooO3Qz2|CozlbZCgB*@LL*a4wkGP22y^9>awUTXJuvp4X$!2D z6~_-hK^i4F*mR&&hfg4$zp+6VOxiLMN1c?jnv|Q1jwjGV@iLrx za>H>gKuHIyI$S!^?I^6dXg9vq>Nl@il5d4m{@{LX0u)?Q6n2lGhX<@2nYj=|N@?2t z5a$701L^MTa8VvmTkm{<0 zSxY=0>#fsW#@8HuD_>oX`2f>BTHtGqc|4vk^8>s*=86mW{z$^FwQ1ICt2(dn1u=)E zT{i{=dQ!lf77rzHvvsG*{AG*)u^eq-LVu)P6#^kUN$=JR zE3yGgM5+LpxiObW}`wLw7zIwZgxW4My;`&Gx-kv(4pNCy_ z64gI7oZ?e8iS8JPPpmg?mXXHV#TVc|fpR5Si_xfENlWyMV%x`)3kq^uvI{+dAba#T zt9ElHZQ?7wIe|2FZ4l$JU#2S|AKOfe@Vfy)oq-`F=Oi$wI)hz$yLZ+QilU#*Uv?%15^cRb^lerhbzBtznKQ|$A z{3DWF#il1%4u>&B_p(^8^FBuL5#MLza-BjDdAn zzkbVPbAj=@s2D&f47i>mrx$b$r)9i~yUlFfd#e7(r?Vt!TQL(e{?&O>B|{-GuSX$p zjVP!zGQYgF9UF!-Cm!XX2zjXqhb71CB)8p^(AbMTOP+pZwij!?+3qn86;(GT-fJBZ(D-*_E1JqWfabT0(E0lLf(>xwNJNb)`;9u**SqTWquZ z=JO8|Kud#_f%kH&g0FAkFXW(lL3Bkn1$_T33+GC%z(G`2sonDDkCrFAKWFigklG6Z zN_bAtqpn`Z+RMMO5%ZwX(u(kIcfGX{2=RZYbTvNoM`1~d;RPU;ki z$wIL%DDk*mdj3pX%n+t){lo@NibWcHfO#(FOZurbAZH*Xc+e+51HaUqAJVN`!w_1- zVy9v8N2<`Bp$xW!5`a{2gQ5G=`o)2D)>;_F*A46Bw4fj|t4!t|*Uc!Y#G3x>7*J*& zLF0fxRSh63lujHd4kFVa{dH~phyq1Kt%nI4rnL9_lwMFh0W$1LXl{U`5YUGdO2_rs zL?{-&f$A233_y~ya*S1FoS=yC35YVK!ssF#4MzdY?Y)tTHiiPImTxnJoUL6u!Bd+T zM5y-JdhdlqsN@qgO*M;J&CetbC6RXzFlp*J5EB7?`P}(*Mp=r;`$hY|9<`8n4Z=so z=Tj3#ToUsUM^{`V9>STW959mjkO!m;%>n>ty%0+4@iG{abe{Q5-Hy;RKBQ=MxZX{B z=}*;QAR$zA$UT&}m!wO%!q#!pOFDo?vA#=0!f;WI1jll^#9+Ci0WByHG^TxKG1RR* zMPlZ0S&i3?f+X#O79}uxr)yr1;A+h}leP-IO^Ec+L(N@PzBk{t`We{%+#7gMw}3T# z>68x0(?#sT-;jggw|%@RN250Y0hy3Gnfw5Xb}HO`rl(m1X_^3IIM^cKL(zyMG3Z{@ z@LWy$FBzxsCfK0s7Yc?t>_%lv*3=u|8+*UI!u}?*6Xy}Dmp}esEHn7uQsaq2ieo?< zp~d`va;V6@R}trxqT(^JCw&t@;V*exqU8-7*ica?h)&WIdz@v)^LYB0y2G?uG$#|X z60hbzfiIM7_y{|{!k(>G{2_tOKnI-m zwx>B&X%bpW%z;hfLs%xAN4;t_R7-04Rm$wF#gXv&r`MgR(nc5zp)twyUL9gR=qIG^ z^wC3k&KT{x;0?S2=Vo-)mpm#jcdSKSjU{9SdT}3HKNk>8RANuTd_fN}sjDiqt2F)pIvwF9&?Qf3=srU7$62ik0YFv_E^czaV_0 z+zo13+6>afWd}UuWQpmIZ4fruSqS3dVn}7=&H@xg0XnWIJP{AX9XP&@&59A?+BTNZ zJ8LC*Qabk8=yKxK*6tQgE#0F*2M5A{a?zUZ;SxB-bwJMCW_vmUKUdU(wddWpH91n5lxn(Qv_V?ymmdx_h2+o^kN23>KoWEikv_+hp`3j=jHpcYyn#ZNf}PpU`| z@SJXX^_WTT!L2V>^pN}&M)-9+pZY%SUgL+=Z+ql0&^(TXI{3P*i1QWUU4{3-n-hsp z!t9sG|LODQGu)e>OSL8lt|0(yaNd?c;Q%8PTBF0+#gv1nNCuIc7$GDtRQv^U6!dfJ z&*yn8MYI0Z45SuKpAoe_j)%>#F(UrD_P!zQ_)1z45GltfakLMWATG4*X|+pZDPGmB ziX(1=gZ6Z>7{+{=P#n0%S=XNzqiXz{clmQvF4!T;^%Dp#LlPD zmi#bW98)A5P`!#tEVM!EdHS2qsUxJy)fkwZcr*OR+ne{G3N z{px~!5#msjGYtp)rMsB!#&FFS2nHc*B}X5X zj5dp5O%j3i_N_JsVNLF{U<-e5Iuo*n_##}Z@RH}dk4P<0ZGG(vL0cB;!zQ}cCdX8L zA}ixGsm8;SM54AsD^c~u-4R1yjxABZ(*=eu+CtPPr`sYQX}R7E2;5x2Y;7kA&`C4P z4r^GuqEXv~X<8yz|84DlXM(KqywYrY^TR+*HZg*{-2?bY_}Xg=e1IG1K!-ryN*0LJ zYynLOwMjr?Z6ys!qWN(ED%GJ82E?NS^guaTB>plT7!uiJTak*jsn`>9BnO``|5Ogg zF-jB>pleVtPJ@y?mePQ}vl;1chDd4lSt%UBMF~8HdGuNtR})Ta(i>6{exb8od6seP z%EQ^~d_W=JFD44;vPD4a8qExS_(9iiZ|j6#>~Hp^**4Mjh9KAGuAE zh`a&1o*c!zwXkkH+?z+Y>wFSJ?>oCF*!V+~mOfL^>ZZ6FOd{V)>iJr2eWSt_hTVea zp$!4mtcJ&92+74~)CB0^G1-{QKY#Bq4Y_2XmhGEG*zF75)onv|+xCCRNwII`a9b>M zuVmjoiZOgms$H_nVgPj})_zZlD<-GKYv1z8yxJd!`y# zFZQB@g8n*7%Hui9P`?eOwDA~hr3HRi}Dehd$=m*U=r3l-`jqdS~VRAd5rHEJmIXPM(j4)7$yu z*l9S0cp2co0B(4A&&)hxveHg6id&AMDM~8h2E*^ zSES}NDi7-L!O$Hk7?nw3EMqmHa(c==3ZSs@?`OVo2qr-ZK@BfF21g6iNbk^do?Jng zS`HfVG9t;Cc%@df>n)7N-Xj!L6RrX`MER9eHGemUn52e?S1T(oi~OcjxX78SwkFJ^ z%c7#aXeVQGo%}wZ5F}Yi_UAE8l8n4BqCss{8PJv>ULAEEDk4^D!82QqNv&{B(YT0s zWvSQf@D#v_wxC}#6Bn&hCMyI_4lShU*c!zdYJf1xN+8v(azU2BR6`yl*^WvEth)&H zrR$wg(FbVZ{pBo`gK*_Yq?(EH>_4}|lz5Cwu8o?em*3lia{**a&qRoctZC|{@S7H& zgqeX#cg7u&lw+2&&MfvRE8Jl%o?aXWG!Fm zAwp~K&Bl(bCx2?}U7)6CAWcH7m{a{@hOU3(F+T`{rNs?SJ)9VkW=k9d{)|L}Fp3v4 zSckDnw2O=$p>E7N2Poq=J@U|ge$bmndX6NYltvnX2{=gW9sVF$k*seYO2AOD-;dv) zZ!^iyK*kzpn&}#K_GRQl1$@_hPHEKZoAfA6y@!R*!WaSUCeG_ zlfcX!be4jgU((dWv~jsM0ueBKQ$7@vq04}Joi~9wkdfQo+hoV?)s72DCBZJmEC_QF zeh;ua;!T4jSYdiBOqm_eas{^pV|b+=srsZb`UK{{z9Th`6VKxTJg|{0jMMEtJgA{_ zGIzKHUFxb(c68Pn0nGZNfQAu+t7m;hFuj&ooKRkKC(2sN}&3q zVo238a=Z`%3X;*(s1?lGJ~jP1#37s{HXHUJd5QMMLon7u`<=jV-bc~UW1QxF%n?k1 zjR+yeJye`4umFCN`Ka56R=I3Vec$0Kc^^rvrZ`4H?S)g>OD<;%K|wzIt*oyoHuR+= zJq59PEJ;0wY1t|-Ie^%ok@BdC*tSl>M9WvV&`P7ikKTTo@_kNX= z>+Rh|W7MgrP&}cnm7e*v7RS&=94@AvFXFi^ZfF*+MG#2osB`=e?%pZLlQ7WoEO*(q z?JnE4ZQHhO+xEZMW!tXmGP-PY>)zd&*xB8O8ygezFs~Vj$ow)Rzsz&a@AM4hNzune zPhN=vBo?Dq8;el80oT2+Pi2PASK0l!NUqi&2I3L+qzK^7^VoAH zR1PbaZf~LEtjQb*UYyRBKbIra`@P;QpVIdFecq&wWPSi=?`ro?_iBU&p{Fwa?zRBY z;6+IpY7(KVn$<-=;Tz}ph0uVt{&uj_`}N8{r9Nqg%Z}J}tv;nFK$~gr6en0B0)^V! z9A!wxN!dgTsWBOugUOf>FRyyfl(Vjjbwf2LdST0!%{zTYZ88PNvv3S|q|b=B2mKl5 z?@kUZXCUGBhcwJrlVeJJsRiNBFA`=zB%mSO`@m}{edRY!LGTwu%nbn z0$6QWe)#et!OWw>yJP5W3~<(s)`DUXpmEPa#4mh9i!r`$>mN<~07_=@{Vm8X^d96X z+KU6@CCb*eBMATJHoS-Ewc1=vN7EfbJn*508d2&$@91)8_xIVsX@mH%gYZsyc7(y` za0Gw7Exk|Q=RH4;o^>7HFAb}d-+gNk{fy|sw4~#zz^Dl{5mZjeq^eb@zUWNUoAg7}cWwRPk-`-3I|OoWAhWFMD*zQ_nM*?iGMJUlB@T1=(~+s>JRTs`JA1;RDW%x@L@ z&I1up|AUhZzo13AaM)q1s*2S_h znoBWr+8NS5)8sU}eAr}{xFOzB!lv+V$qdxPBz^D%RbfoLe_j3^%+#!yZ#fQl>Gql1poW@%TB9vHn!7znw z2S#9!y($8cu~H_?SGxF}P+tl%W)Ri&*@wc}L@00(5_aW{7B+0~)FDpxaESIczgmwIQ5E58n4`%AP;OR5Jo`^Wtz&lNPBWlx#-EcJnE>k&=`D>{GB+% zG9=#DkKszbZsnp+@mrkEm5TcJ;E&g!M{+v(y_%nmeQ^16bMNJ<_@lSS+aDn9pcVhi zN```CKF97s)nQ>Za3`@?1G0TSNwUkhE#`H&po5n2F9>UpgR~QFu(zf(Z!&)^zF!f| z88DlGI>V4}Q$tHXC6dk1zvBReen=lNm72Q#BM|v3o(P)O=(&|w*b9rah``YdvYn4|9M)nQ2(m=slu3+R!j@6myY!NhX#9zc#8dg+&H z%L+==oz^3)A1>uiey$bksh9T`odFM6uW4pdgF| zS|_0YhA97D4E;htnr+hp^IA*bKwzL`&rAfZ7ER_Mbf1VlIU-ZA)5-x+sh+e>^e8^Z zB{nt0D5#r6TCE-ry7Tl(fuxpy@)FV1tJi{`E;Q2xp|$ImqJH9oG2|7-^0dFs9tMK1 zi2z-P-7`CaifWKGIV;rMP)^!Vo))49*SBVuP45HLjZJ*q<7HWsH<^o z9n6u=4HtDQi&j`Y`njjj12j#hkb&hHPOoB`j8M>e zLcTCtET)5eLE4WfW&0nDFdFd2;#7$3qHidpv9GZPG&C+<6rllw}fRuj_fz!l7f zDE}^R&UNA7eMN=RKL?_YhQ?NGzI6@E)isCF&7cK%cNlwH-AzvM@VKL zT#*MkPP84eiHk{tKhN6mp9lHx7V`g{tPTHpvHq_!`)}5UA79{q$;{oXKIyc{f&No| zc%_urWB}yDfHFE>QmvF3$9gLMmsM1`VH%bIT5#lY-JJ8D;WONsULYzZr%qG0d?QI< ze|P_{^DKBz4Lx55_4Q=^aZ~NjqbIwQ3hqi)i@H@$zpZmHxX+D1nW&fqMx2y&c96e( zX7^}HMm64?06Z+U2(eT7yE?x@(>6uHgELk%q+i3TP^haf`85^AByX>P9G3^4q9T2B zdH6g7)%IE~GlE6(!&$#MO~^{rF=Upp*tYvmdovSST8V<-fPagdKS>jKeIwn=?19xM zJp=y4$XutJc@^N&yr%FI8z(hFqcXw+A*0>51;mGzgx&rrM#miAGE!rI1iu8`Y%Nt?Q(KtVfv4y_Z!bz9-of=087?hGpsmAY8ZT- z&6BXb{Y*nGgYY`m8G)4ad)=k%e7f!Z*2_@HNq@-~;^I>C%`fx>;fC=+bO{C0k$$GVO{sDi# zl4@ve0q`TV?is<6)=3=gtg>DYsF53Q74YCng&$;#fJzpJX|4T=eLcOTBo+G}c^4;l zq7k(VYRITk3Ny|tT+-B~8PqL5$sbMq?w^B;uuX&(xzv=EoSG~FrMmL6n0_BNUxv(x z1g=?)>27auGv7NYOoJdkvV(|C0Kc(sLbw^{+t^!iA9ZhK)4Q{v*#c;=HlT%yFrw6z zeYkFKJ2LQ{mp15ko)LLQ-Epemp%|rDB)(;7Y);&Tc%>>kSL)Gr~r-}aY6|_>?+w6JF+rKR; zkH<=);63_j)lrERBt`#8u=dmRY0NM7vnVKf=%i22;ix@IevUC>8sD25DsaRV!jpw- zG=e!FR~;o~NH3lB9Jhs=ng8MJA%#1J6_E4a5t3=G35Sj|-RM`7kHc*zEb8~T1P`(4 zT%v8lmYFFQH@}!qfdIL2dGM9Jg3V$7N4d55JIOTH(aK$)U39M~@2X*HWhmUB#Ed2uy=RQ?-WU z-nz~PzbLFM!AHE>9yG5f;P|B*i6s;4dL}TDKXxUnxb2vae-y#0vHCQ&v^L%c>!x(q z+I3$@IDxl%lc7Bm!ZE}wR@8jQ>UG)ST5_2IpBDrMX!KGnCg}g|-Xk?C+5=$qtx#uO zIj6jbZYPWSu+sY-qS8@8ohRMyO8949 zUMUgu;3>a<$Vk%D3EtC5MHM7a#xd=KUhI?b| zF^L&&4tj=rmG1UG6M~piUG2iIFeGQQnQrk}QFgcnbvmD6yqGQ^V_t04OdP2_bW^XWATAo_@gopB{YHoP(JQSD$PK9D)#f$qtAeplCK29TO-PSN?zi@ z7?_>xFv}3p*AdXhLJwUKJncvcM>B3tb%)~*{NfIRW5i3}b&}t;bQ92iY6ZH=dZ@N- z2Q0CCzcrVpHYiO}r$RX8d48C(rc#Xpv~lELWr~Ef4kea}p&U;ePF#OeIla7jU$eNE zXrHFT9_RSjy7q&#)1cgiIIYkv@>YW*UQVYbxiZJnh@*;_7_t?=7U6mI^|bkbdnB>m zYi_@bdOr7I_SGLRSLf)sh4Rsp?N`NpA2Xe$Q{^-lXV2kdfALw1U5mjxQnRJH<~WMG z4O+m@!usfaL;QlUzxkOVhQJRxsFmNH{T&#Gt&FS|*exp-H{8zgG?Ifei^mC*){SuB z=OQLXlE%tkx;dH4Q&dSx*P3~XJkX7Pdb!U37H&JP#M3=4?DF5;>X`Q1sljB!Tui6T z=i}p#`_-2HxTnzf@6asVTW(Z3>)1My#O6{CCgY|n>-&(Aahp7)jY*Pv5DFEk1L4P7 z4U%dFJtzaFIi|k;2&I1o!PLVy9pBu!H=;@V*RxZs_eEH;Ctas^g7X z>XYM;JBlxky%pwb?rn}BBSZfDQZtNuW}|HeA8+&z2ECp*-vesdC9#7(q5$q##J&U= z6ip(D#4KBcl<|@OhyRx|lCG_~&YWS8R)BLUFr`9@2yy5g8yBipxx?}D)|q(ucr^QJ z*3~8T6tW3_0S7A5hH!Tj>9K{(GO;qSsvY6D(j0Wm9Gt|9>3&&(T(xoxbhHREXTq3h zkYr-;BPh(8ibJ>;n?pb>X4ikswEtwDt z`)Dk2MF)d9s+1N;8*BkW%dv4NWg8alzA(uF(QZtRkqm=m6$Zn^=pkDU*-ujb09T`_ zqnv{+o5UVV10<-P@f#0Ay`%L$<|J6N%+kdHEmDsL$Kj(P9LolDaQ`nJNYS(*_=R&j z+}#G^6&X|sBy&D!n+RnLWBKTvQA9ZeU`lCTyc>NnQ7fL%g;~emOgwRQR4XJ?uaOK0 zbi;tT#9T+s-Vs2cqaud*7%stzZ|ge)^SDy%s z7oVy6UDC+%512>QPAqtz0Wq_CX>v811=rX0A8q9%vm+xKf;YH-VU7`&I|B&1bFro}c zX!Smr(d>fFW5aAwuyQVpY7rBPb08Yc>I-R>Xh2&LbIvo+W=SK^+FU|v+xfFLZbK=L z7aSrJx^>H(|2Z0uBB>9JLc5j$EzqCGxVveT;pnPDIW^E?aYnTn15m+tk3OyR5|Mc` zc-?vFD+n%FQ{2;v5W|HEXZ)h?BL|8s>fPMBqoqpf(yko@_{SAermPUuioFco9u@)R z059UexZ#i%8wn2@S>{xQQIM{!xfu~5ytzYMakmlV69I03Oq?4z@)=OZz}%FE0Gy2^ z8Jo|)T&cI#wDe#}dYww><-!m+z9qrjA(k66>OlBk+H9ciWyog*USa*2kQKl=Pj)7z zw1IL^RX3tNvREX0OYG8Izy=q{U+ChaX_7wXZivtim?zz6TC{KgJ?>hH~r0wW!AxEbV z$kP?C>J5+Y!^$yOxnz=(R)3pteQ&58BiuKPJTTfnqxP`IjXo(Fh}}!LbnT);b9~!{ zJ8xRX0|F!twYVB5z2|tUN?jG`QR&I<57(-hT6^B-kjbam#X92)hB8i|S_B+@NSLS! z7Waq%CTmtv>W*q;d61+72Q&3?A8*Htd%FLtVE_K5Atl$!d-vuDo z8fUj|E_Xhj03Lk|1dkw?fu+^^J47do?QMcDNq8(7D^jWF)xy;>TYf$o_*XEsaIO~e z_hQ42RB7nEDT8!=@H7(!LoZAl*F8NoAZ|4QPANLYc^&2ZY;#2vD*1lkKkpQurDbbk z3W!N6|5&5SyB#fVP;)(!1=TzzhpF6g*_uou$|~M>mvckE4fhi!UrU6YYph2S^nyVqRu9s1rATQIVtm*xDMJWcKzHl(NP;TIyH_@zm_49PQmVv=T+1e&Q9AX366~pfX#ri& zg*uRryHk9SS1SY4k~`xVZiSU7bA;D9R1QgZ#1m$sUxCA_Fki-LMw~F&c*1jQuTQuC zaZ2*Ov5|3Vl7kgfql)|_{pp#a!37DxA&J0EXdeIZ-X`q~dF=9NL;bQrbh`2pBDo>e zg0a17SjUDSL~<~Q1mhitS}>*O!(55%3m9`;NS?z4gG@$Uk9vHsmAmvd?kCnm-XpY8 zk%~KN^)vYEP-?;i#H)k;xjsGac|fb}W#Ar`XVt632nL-+qyXQ@U5$K(nH%C|Y)cGF zr-1{=B4!#Yx{fi2G+hRID45s6#Dg3$2V3^SqKujivQmWsrNPjHlPaKdEOLngdyN>V zmJ@H`$up@l7x2Mu$~knDQ!tCeEGxO+y$8J&gVJQ=Gufmjo^n&C_(cufdt@*nK}iBN zJ^1!VhV!91hQMCye$7<}8LomxoqUl>y4_=!ZwSZ1YW{P6(pNZ4{fl^7*>AN=t4D`- z^D4wiBmfU6q20)Ze5WSOKa-%<`D^E5C0qKVbGA=!mTgnmxly}kgC*P+z^|`YtCx?) zg)U5pXMGtEN42P9J@06TK($`(ZHnHI1x}2On{v8dbXjx`ZZam0Cm=+@npkV3o~Uqc zB1_6b%LNBHB8Bq{7VL&bR&^CiGSxJK`rTT3C!tzsl(f{))>G&a+5yukO-eQ*q7wO0 z*ObkXw}qkw(yxY?IK_e#w!xw*1Z@^WTZP|L@f}3Vh9o=Xdkc?jE_PgjnX{AylyNJT zHZe^CTur+B(8AJ5iZ+#YO++hM?)b>1-Yo~$Lhbn19QXL--J4lxYT?kjq42QHLbi6H zRfgk~6hlX{D4GVYDprA@6V_CX`0H(i?`S%cTz1Bk?(sIr9`PwIrKbYnY*~fWyK(*ft)d2O3Mq9QXbJRC(P&0E46zWe z0#tbhQUUGwfo>`z`*uTcS@~f<-YIvcBE{bPxrDfPq?nzkEIMr=cy61yTO2|`EU+Qe?K4sI8HYqeI9I3X1cf!0B z!pDiXkC_WjW;D9yG6;fGR>AkLwChCaXb2p@$I6!RE4tx6{9~s^&!dg6bJmeRyV0xA zRrWnYKHpEpSBK~0@xRSp|Ca~9fv52XCeQ#^J)X9ec_O>WLi6|il*?tZo5F&-Vcl%)K#WGl7=RHzz>X+n){%{IsIz zTbL2T2{u(-RXscUtozI3hE2Uw%Bg;D)mYVZm#X}8_RTHBdLIycOjv&ogE(R5$BVgH z@o+wYQYJo=$T57g4cu-R-$*#`_;7-GLTJNaFAdOnUL=(z5fNqg0H8QGrK;-XNmWBt z*g;%r#B~$-5GfT?2*-_41^w$oLxwi>@S`IsI**XZJ{;5Ts&9UGgx`2AY;KqDIl!&CT{ zmuKlJNaI2Sxmk7fGN%$Zzb*ve{OAb6FF!p$(et;=r%j7z$F^;KKWRA?I1+dXPI2e4 z&LZ(EW|hGuHPrc7FS(?@LgDPIF!X}LRxlj+G}sGUWVR`fQ}k4yFZXYA=OHLprgI-} zw&zS|mt(Sh9|U8#&xAWi$)vaZ?myj~)_i_%H?L2Z|2EypNWVX1IRrk=A7zfY!s!$o zyfHg_S5DA!m4Ux5F`Vd(A2E!fNCH@%17V2RST`Vw8A2Qf@Rg~kyhV;&@}D}OC0u8o zotBq%UZ3>p=Gb=Qld5gvI-rxPv%mRd34MUK`SZ$)9)6KkX?XJ}CpO;2o1G!0@+l)! z^W;&@I>543mSi@KrTofn)2Jd0-U!>FId?j0D-a+p1?(QG5$V ze$3yVG!y+v8V=MamC{tcGEFP}Jrf!U-9&1lv;g14x&c1!{&$$AVmpl{S`rQ6g>85L zNd9kV-9rJ9n*$#nl|-`O4jCVnntcLJ;1oWk3npsj`|C^GeD!4V`>ohN7X^2w#A8W8 z@qt{N zr$+VGy(fFMqZ09G;@97z6WPD}HazSRDF^S-iKKR(<0#UpQUjW%E^XDsikW_*o}$#0 z)f&FE6`EbyL0S>Ia@tzKmQ+;kXk0Hcq>{!EuQGqAf@1z0{toT)oN-)&R*|#-!yeKh zS8M~n$<}H8+P>n^Y1McyLu-Clxs;@3Tw?{XjL~6uwP~upAN2cHKA^R%7N$d2z07`D ztatbX#V4Lf`G4yK%>NN^{O^C`|BDew=Kr9;{0~4E=KqFx`Jbp0{12#^|Mfb-4<{56h(E{cy3GCA>T-MB{ILkkv-oDLHox?l>Qr&)~7-)OZb zLEp#$?->wZ=+N=d7{IoegfiJYm~nQwYu?NLIPK-=OOa`EPKVCPyf7W`z6=WzG2Zd}W~G^EYTiu+QCLS4XBvbFFStvsJs;V%loh1@->keQ|V<{qDG0 z&R^}-9?R(b>909&V{GgxLQI#{I%T%kUbX<7ywNu}j{Lok!8sQ60-2Ej8}Fu!tHsFw zV*jqgjr5P8V#435gQEjU_a=(w4ItD!yc>eaH~@L0EM&38xDKc^jF-MB910_X@ulw% zazZlhJYN*skr%-8GB=zmMr2SNGK8}hMV>piVVH-lCJ96%T9LMn-4?gzlW#b9@NK|^ zk%K*jo0-l8y@7;xhnNrrX*afKkw8t4(7x%T2!>LWRsu4#fX}$3h>rXLZZToripaqY zv=EYm=82c4^d;fM(r;V}199j>@OfT*)rl#2)%Ddv7km5V=l zCKO7Pn*tvbIE=prY>nhhZgFI+f$k>C)?2f!x#R8$D3k3unr0!21gyMYaK3MSu>Y0K_Q4&$0KLXB^g@B))$o|UM zrs!gJu(lrnI!=p>wBF_Imi#F&hFL;7E`uDS_J&YQv6d9!;K!Kj^i;^b;spZqW;{Fa z{XN+#(m&RBR^^)#L>hP_<6)uFY0ZP;`*rmMaUSB}Gittri?gM-gN~^6P~B|cUTG)U zv}d(DDCt38NRhC5l;y(u)5yLe)pp_iSOPt5(RgsT2D4@7YM|z?v%L)0Svh&9(eISK ziuTS|pYr7)s$F-jg9AqBDhqi`B=F{&ghW&bUG|$J0S;JA2?&V&Mh5k~+vtyN%8C@A zS&^0(H%iBL?VgVT)%x~6RE#txy6)Bi1nQE1X|}5W>mYFR#o%3|dBvj`-ZfZlNa-`X zU(O&qPDH>$nsDH*$4<(?Lt#2CuS%xzU)R>Z)LU@^l{9;A+9+H)Dd$D_mEN*B5CydD zk1iMSXlvE|!)8xIoEGba*ew`?Xf10s`}HRc(@%EqI%6CX5yC9-XaVm0C(l;%4l^w@ z?Q%uU&yuW%Muoqm&TCfeLM4Kh!9AqijPzdW20HC5abmZo?CRgK$>iga?6<9o`f;Ag z>fCC^_8S9YdWCKLfsx0kz9KACMV|BU-~tv|pS9Ff(N(@=b&#f}MYrO8JAUBDRpe%{ z5slM|pCH?|(`=TRS9+r8zE#5LbQS*|p&T_UQ9UxyDpyGS=XRaor1IvoU{){h$p-t7 zKak*^pUeQ`md;wJ4As)CAb-%ohdK7wRw2taZTxu%4U%CtWTfsSKo(Sql~YirZGC&` zl@uey$TF`(dB|HRF(!9bYVU7y@YiI$Bna+_?e%L?Z<3@6z6D3I!UP~I+1YP&T{&94 z$eG~FBn2sE6@{*^74B$v{5GniOg)qF?$dZzECG$n{*-Z@cu@q+)tVDuJ@uRZ4WlgY z7gGj8;Kn+H!r{cVDZrSWfM%n3Lg*$}8~n(HtbTal_VG4tTHyFXY_1)+Ckur;xh~-q z4MWzpt#Z1_Gvh|4wA9?>^#d41f2uC_XF^xtCk@i(OQ2~ruZiHQ zEYGBt#o<8OPIobKZn=bAywdPnm}#cMMnu9q%!9em$fXkF`vrGxemL~-u-W=YW>4Y{d z?N-=*a>!TVh0CpbhyFriaddNr*&_-=4&M2ToJWGTF>7VZBNlxnbZ{~cCME#z89bU` zwo@Fe-%M3jNx;a{&h;e(`hQ58;wLxX(av3jT?U98A7f57IL1ydKWpm9re7V~3|M-M z+Me_I^sxRdp{HyMjJSJ>Egxv$Juylclw^>j>NLX&20FsBpPG-cO~%13mz!;t(Nhun zLSO-9EY<$fZ5l`Iq2mnl5_KpLP1UVV+TXEPv(XYJ2}oux?4MkTY#v}9e5w(#VQZ~@ zoO7u+=bH_1Avs^}Lc?7kU-p>ATvkkLBX7FO(5#iQ$R7JmcH)LYa)Skm<$8Gu?$-PW z)>L61R79hcs;t^*f4!rGN?=i$38)0l_;p(3I)@l1GZJ|Ult#qP-t4hWR}vnrC=(6p z3|u;VpjqOcvTU2xLTW%E$>by1em=SvDoEBG(>e693J4C*i$n)@m0k>bcE4chC51AVvG_fs-2j{D)TjgmZ^niBl+M=2h_3P-=C^Ghy@7f}q zM66Ld_4n)A-jF!}*$U*jFXSYvJ*}SN0I9Q)Y^y70O7dW)aelo0dZn%*z*k+D{3Wwq zJJsm8k#%Wn->htyvBGPsfGZ#$&Y5szWo51Pwc#^OOZ{C3@J`_8LwIjDL^hq2WLJ<3 zJ?y%4Y*L)(wA*cTT_QQkjX~y;e!Yt?tspoB3xP2f#u+x6VTzL9Dfod_x3_`~T|xvU z@TXllYa5&~vSQ`YZ?rU84tEwQGHI+vw3i)Eye6z8=$QWjZu1TY!hi--8O}7)378m87 zW||Q0mCfxU;%XNr9$q$a*)RJIt+Kd6!qz3|2w1hz@)&`WM>lRqE6T<`2rEEXwvc3C z07!La0>YlL$4PK**qZjechG0}y_Kci0mncpjo&b?W~D>ReIDl_5HJlgljs}}gp#?`~nLP!*}Vd!p{Ahx8R+^S#nxyVHiwU8wYx)G&x|@PhRH>wOnj zC$A4X-`4DWSfkFKzqDbF$__()>9*oKbMcgJ(fh?X_xT!?3Rm#SQtm6xs~r2scf4#D zjcXY-EV<>C&X70-baMZ)lb2s3*I+l7-P*Pf$#L;Oa(7>OJ)(tg=3eKtY!QH4Ecf&vsT(C?#Pjg|{ku7Jk)BMKvXjEg`LHiHQh)lq~o24G&n z$D$_zmxO8Q*{^mjd>EUHufxtrsX(v)`obX5vys1^6b6c)futk7IrpmDFb19cdN3K& z-J=(;1Eh+&!UMhp&twUy4KYvd5EZ-}$qfKaPof2rp&q`idLIIi6rSR*+@a#Z{U;__ z`{J9?ugAX}nR~~0c)&M_sHLu69md(X7@>GdXEda)?i}E|E+gCz%4RsI5PG>_@8}7k zR+K-ThjE#$YR*vIK+a{&A7NA@a0IDo?bLH)??kiV1-$ve-)vek5E(JHhE4*9vLfDr zU5p;qr?U857D%sE8yK)d8!1V=8EUa`z&D&3?;p3M3XtVq!zQz7NV2_fk4ED}q)-K6Y6Z`jm5@h$QaP z5pflRZ&@C?c9HllMg|c}ilvMX^bio3eH+Qs=Cz&Q0trv`kU=#e@xF`wT`G*7>ZQ>I(GMxIkl64s+TOj+WVS`b6kEH0WtfBK;8 zvE-K2N-fC%s1njs?RmRqvxtSM{k8()ysAb&bB{cw99OJIcTzjUBeN%os!>!lgYouD zupb(Q^@zI9I>O{S)K8r==$Cx(xpo={w<0poU0JdJ8(U^1Yr(>ZS7EOXbHu$RND(D6 zk54KFlf=F5A^ui|0xmjFNf{klNsz-GN`$I=uAORP@^Tf7l}HoZh^DoJ>Jea%+K|7t zhDo`z+(JFx7Zn)OxvjukjTt4@uK_F5O*mU2dr}3Cs!ZmNYf-DDfy%<7 z(fUa3Urb}{;B{sUf7qu$QIE_6f=1Wko-@QTr6BCaNbBrcIWp$Hy6Z&%wU(C6 zPrFY4;88-k6W|#lS)@?0tqQe;&MiNP*X9Xpaw0MNj1F~bP`9A-JL{G1)L>@Lcoz9j z(x8|Es4n6uBpV_k5)UHSgqBtZN0e4iK|&)6>r$AJWPIWzjWq2>jmR0|cSYx#)y?yZ z_lU?Z%dI01N$B9)g4B-GWH9=Da1jixT$?Tn2la$Xr=ns))X31X=f?TM5N`r4yp1uT zCeY3>7Z7!`C!SG5SfEx_QUtHQGeP`oaVQRQCid7FYR9lU{9VT7z+m+woO_7V#HRT< zmP9eo*WWuppTr6um}idd!7}j}hxWLXh*4tTxpWttw}wyle8STsVffsY$3YPKFm+N_ zVt7S4I*zIo(ufi+P}U|~XfK8$OKHDV7fyCl)XSE~lNy~Ywair(0OT-~J4AEU)YuZH zjAly~vSbUXCwN|vS#cpy&GMIIZ4$FcE(I@*&#zC}L$JTqg|(qH*iOt?fQD5?!Xjv& zDQTW`6(K5h5|KoXt~!O?d4it$PApzK9(+N9eFw|n1UOTtTagzES1vM@ekHJ+HEdhD zMGlC-t*;FoP)RL0zCXwr1lwRWMo(DDMY4kxb&(+@zApqeph?8PcYsMYLk?D_gU@ig5n2gz%^I=+5g-CrLMXFpNB(Q>9Ck0aE*$g{06~FiC+}tmMx+SzNx#P1O5_?uSJ@g z_{NxiD$Ak+vq+CMYbB*1E3xCmM8ZniSIUH)Zbbt@YJ)+{ax5BiRvh>QwNgpVTqi7s zR^*b{c&o**y4A^KweV>3L*=xVu5(}tm9=s|D-hl~{pWV>-eNzSA=*Nrq>@^?#GD3Y zotQ{g3**`EyQejCiQG<$P)KU!Muc-LOC~9XPZX=*`aSHv>2NcdxF%sX?{41>H9Tl5 zCGwmyuCnA6!6R4Q1g#;WM-Sl^zc8#~qIJZbJW^VW2mr8a#O7TekV!JN(8YZA70U|SaRlrP;2Ey*NH_BlDeMEN&>OFu@YCLsg)#P zy>vyjSecbTi%ta!#7jh(iCHavjbuYmF;RnysTN?zB2w=Nuwo+s)BO=3s}Af%S-Smc z9Uv7OhIU<|R8X8*a>c38To8B+({=$}9?Y>X_!AL_tX<&&>L$aFrD`#NX4zdr?24IU z2d0I_tRNlImjPjs7$ZP8Z4_ky9yO9poEE6n0I}Y7+QvH~jJqhWhUZUFazF=8CFugr z^_3UMR-69P;cA;ropeiu9gj97tD-Sy5il`4=T=E<>B@K^lyO2TSsi>L!apyWq&7;# zhr*$`aORQ6_MbzN_yC)|PBBj5iQnb0I6f4TYYps}s}@)ksS))fH3Cio zMJP6tW#&Xsm0+Iejj^e>o$+&V$yteNp?$>Ydk7E@u@X$lzsq)Svq<3B%iIG1?YU%H z8qmT3JY^(FaJKbG|*@dw16 zFdmB<9T|TkXnZ%w3D~jVoiHQ@+XZH(She9A_4)Tp6iaGkpag2=&?l7+giclC2uvgo2jdE< zs=`yEru!-QVqUG^aC*iWddSH$)}w9f^JeXsZq-{>zV!5A(^lQ6-#l7EZasgY$K1+; z*WfmDJ=*v-r{y6W*}8Dp{85Hd-2HR$YG;Oxe80@PJv%o(iT$)LLRfVRCf-9fC zF+PtT+}i$m5HI1=eThb+5&r$mE=leWLvxQ2f&qE}E#^hTmO;9(QKJR9>ql;gyew2u znku)@v;07AgoTqCLnj zw3wz+eDdGmG;W;C^cK&yKO(6l|6F`bQW8?(TOl7MoP(v99w}*^ttCoVHburOhZoIF;P`@1xtrw_@G= z;7a{SquK05SE1j!y9{T#3(<~ri28S1cx}V%?vxTh_FX71BsP)3`{_R%IBJzp{l|Qa z=Y&u^*1Y0}SaCr*57KX)n=1fK-PKAzZ!R?23W`=u0bP-H4aWw~1dv^&aibnaMbT-C zLQ{Ja>0Q5pNj5E!1S=|1ORkf%t2TGk9~!TXDJK*C!?FWBbruEzYb-CNG(Xg9yZn5; zcF_ib4$7C{y!9$ z{~H4SzYL*d{y)+6a18$)LdpCe#K`~9Wd0{AF#iJ{^M6|f=KqG;{BNlZ77kXn|B3?B ztiGAF+5V%zoYCBHBquSpClcP9#gAs&)ONRuvu0CYt3{Pj!m%S$C8wmm2Jn!7Cxw6L z%YhP#TG1b+uc?wi6U(v7x#!#YT8YJ{JAO(kFKeB|L?x;u~PTw}eSMn23$I8aZr))B-4t zj~uf0&kJp$&}gbZ3yoh3Eu*RqE>uVVyf>NRNsK7>+wn6gm9_t5PC zDM|dpLr)qKG+&PLO{w8#QJp+{%mV0NMO!ton6qC4ztmcAWmIX3HB9n{1v?eG92RWA z8)yQu0PjxDy_D|nMyaZv{dGH^KIgj6Ct$-@kYsyW+{k}}o0#NHKqlbWfBM%G>g!LB z%rT>3XmQ+c{&B2(d6C{j>2t~^cOhiHrrqhv zH;FiGj48Sq80Y_WHY29jhn2S4`H4=Y;Hr7wch{teI756CcIS-jhx4j&6y9VE-nxun z+G4oXXhuLORlTpBc@XkG=yvYsaoCy^;gQsH;f^f*9rV1?QHx)PfFJI1BG)a9kJ2D;UzsftbzH#^6G zh&3G~lVguQwC@25BndC{F{_)7T>=`yZ{z(<;`RjpiJnP;dyHiTZMv?eNmQS0m!Y)~ zwloPIKyx02rc!ot}_k?7LQ{ zaU0(xs;auTMuKbEB|aq5DjsxE>ifxy5={XTbV4 zQ=mQ!J4jK$ONR4s9ga&vb;=@^8shcXFXgVUt{USe&=_z?BuYoh_4TEdSV4Gyh4eqH zmhx_=gcAgIL|x($ZhetG^3qk{rxbM2wxec{ED63&Xd;N{ZA8 zeo&_4@uVSa*7*(E^oxAr4Fk#!sSrLEp6A?!at7UjyRu6l(qI?J|O zjTNy}w$CN)(E}97e-#{;S6+lL`pM^`O40Dfw0Ex?vd21T%C)6{%T{0gn!s@BnsH5b zY{SoLnN=p$+oRyBI3GC0QF@%KJtJvpRo&wrN&nMH!EK(aMX^nX-Ka1VaI^oL3!)k! z*Ep`r1 z$NBP`6uDqm*eCNmfGZ_pvk^6`R{Le2JQnr6yeC_lApC@4ia(@?1WiJI+7TM|F=EJB z2CmcBtECjs+8;NUL0jB9R{sgOdE|9-el@!(Xmx>AcfXWpF(-_yEh9{*J{F};_b7f* zUCU=oOE2F)833TI!)w@+UiGfDS9|*`icD z99E_Mo9d1WGRzS^h!VwrHE3+=0pA#&G*JkG2{_Qw1-y3e>xJRifyySJNBEscq|{8g z%&KS}ZuJ9Uvo~(u!#jkgU@5`+I>>T@-ohf07b%RRnJMtP40f}LR5esU;1I$Sqo95O zwk*<8Sm`h`u?BS41&<3&GHHPM7|{=gpWAK}F~zpQco&j8j80rH7XJ);8(>7mMbRTX zhx#k<0ghG@UL}TLk-`cgT2s?~o9rh04eT5k+m^An;eyfWXSffW7m|rbK^u=Xm{**2 z#&&{eJlul}uc5`@Nea10^8R*Zf&4|K3UPABK$oD6dLUa28Lx5$i6mCghd311sX(kF zV4;}i!DF+lh>E9BaP7VBZZtH5iHo3E&SQ8FPs%A|VL+MjmxF*FqG%HNPH?o+RI0it z0_tmr)16!EzGXAMgt;ydrrU^O8qD_G%w(_ug1`jzh3S*<$V5$j;lh!tmoys)bmTc z+{6{C$O6!6rrNK+Z3q)5g=r-07LunCC!^P6B2o?WPw;^9HQti7G0zIaXnf0h0;h$M-uBS%JE)WKP=kb#X4IL zYt#7@R5;a8q;v@Q^mt}Dkk7f1aGS|~6?{86(9e#vV!lv_m@+ydRVLh$x9}Q(4ssubl2_aQ{`3Xo|Uog0@rpzh-;Z9!5F|S5AO4$kMX9}>vinKSRdX_02`c6 zi0w4lnD$ZQ<UHGpwKc}mF}m{mz2{wMZYLdD#&>F2$mHTsH=yHf)r4Fj zwUGP3cm@UD1p291I*z~>gql(gYF^@XKoY5zd%y8oe`}P4-&xPxb%_hUv!u^KXp#p6p5>LC}Tt-P+RrDHfw7Ao}>6WAgq% zAcGm!XkuK!ZZ@96sxC-v*?hUD*Ew)%E^MT^%(Kb_mJSTb;0U|mw6w#&948uT;3*;aEaGN0yB(*vx+Ne+SKt63=YVs8 z{g#G(d?Nb5rPEfY>1*0baBe*u`T(p=5KP-sq93%dLe%3|FgZ)yakLuap~4ZuJ^0N>=BWi?r^d;}#CEv9LywYO1kXY!{=U8a{M@-rA2e=b5AYQ%L=(y!ycG4y5n1GD(Jd|WPdQMpC+XrziA3} z6wwlS4;qHl*wYp^w-LNGO8fP?7u8mo0Q8?lw$Jfe%oiCf)1EmPiwgxmVQ@nxzfb$C zkVoO;%Wj~#+?rU4%-~WJnVPJNeUq1+uvl}b0J8$umdDA-PgO!9xi4Q3kggw0WtC^w zjt-uxQh;WsF{DGYnPUFcq_%H&x9%FN%dlWvZh#jnlZ((Xe6 zTc?Mz6@CQ!surtw1^Uiy zFN2iA67x1N`uS;Kf7vMvE)3kGsoeG1B#C!WJ}><9@I1hbu5O1E^^XM1%EuyME z{OkQFA5YkBE+n{p!%{$&kn8#i+x1u)e(^Qu^ZpQUmmuz!Za=nT##F##L2o?x3L(2Qd*CEh} z^!Tm!r~BVaYwwpg8~zOO_Jo8VwOhU(FE?+2Z~k2yf^T<*pBr;~L*b?G2e0;>9en5d zf}LAi>+NrM+1QMiU0Zsa_BCH@eV`ycILUDTO$w9i|FMYtKlS1NCyx%xKL|DdOA$Hi zf8b~SKTKi%FEBX&Z3>f7%Jz%$N92FR4*K8o>2MM;f0c^=^DzIFLg$N5hna zIQIfB!-`Y84x4>;Jfb`c5oLHQX}ihU2*ohvj}-{@I&?A2jneRGi>TJ z9&vKkFSwfU@G+m{cB;@sp$dlVqDX8f<~nUsQtN#xe0-M;A=+yY5sSQ(Ez-tWp&n}w zLW6LwgCG4J8FH#i#M)s?AX+-(P3DP=yQpR6O1TX=Hn`U^@1l4HvQ)rc-|376f5Za} zOotX7oB83y>hJ}Y4DXjXZNU#bVc70}X_LHfCqfs3&1eXW<^Nax_tK+ob~ z1KRPoXdS?BrVtr7jT1$Z1hc}Q5G9!gP$?ofWIc)9 z7f(iQrojm{a!Ep<2dlA1{<#gh8tCGqvvHQe;d>f1(IJP4NQs)VJfhtD#^BIHsbSQx zNL;*0oc9H-hK93{lTQU|-eTqyjlq`9Y44#7NG2(04cBHXdt3vpsIeS%E-cE(zYQq9Bd z54&c$<)Oe?D#TxXZb_02zFX^(E1JT_yk*CHe4=p+*!0{Z%Gpk^ z+t0?YA>V4C0_I*JP^d+)|OjEp&?coL zGmk9B#|0vKJps9Ii)|ztD-zmlo!DsLRLF(pg-do_iRhEn6MEb?+}9~}l>ME^vG2@i zv={?>C0(WT`b`LL+!s0;b#H=2a*B_kn~+HGHFsw-91!1_Y2wmhqJO^?^+-4tfXh2K z;OW_kWxts;*bd_9sF2JHsPzF|9X5=-lBf=jpD`OwAWx#_qne6Q6x-O>C%IL@g$&j; zA24VHH__tfhZWqui5FbeN6`qBp9@$Q&mKdFtt)=jb*N+WPKf+a_>xzkXZ3a znCQWrkwB;`=yk32K7m{zLeNxV3cQgD00KR%3k`Ber*#zq8Gzup)C3#WyEC;rv>3Ze z78eD=`viOF$dloDOn~?_JT=_H0usp`cu>E?hFAk|@|Eyz*wX~nKVbN++q7ofW|Ucd8fO2bp(%6rJ|X(-&yhRns6d6r3zrh zaTJ9{NS!N8^dN5Zl3IFTUhtX-nixlC0-TRQ`~V!~$Bq-Z<)%z$92`WN2r(C?wNkr~ z7`x>Y7f*!b>>o}Ddh~3lqDM>VBw{vzql6C)z@V=P@Khss6gcqDj4zM8QRglVQ7^r z{#zZ0&V-^ea%mLT6o@iF1dlXJNferbs|!YBrt%Ij^GJS)D^q!o$k$V_S1JW=s9=An z*8Z!1fCyfs|8(5uWrDYp2{H!nq!kl5HaoI7nJW@_e4NsmHGyKveCoIsap2j@MJUVg zFVt#s(|BskxOwJGMh+@=r1+h#WuPiouPZ60nMi0*7*Rh^zf_g6bTRwv^Rf5ExCaNsJGv!SRsHDiV^qI2Bg1k}UQ$}?# zA5=)BrXNlxxqyvmFz)Dy$XR5j4_pRFn&S82t;bo_C-&i?S}O)yBc(9ePXs6~-azd# zS~rx$jOli`B0NmW;)QRSnomxLBWhsOgBsL z%_$Q3>3t*jIWKs{J!UL&G)j7)41!a`OFh-@gc-L94LTS!06QQ$hZ2?Q9Zq_XL_Q*v zk8l(zqB+sEpLCyg#9h(z*?5LA?DUl=6zY!<3l0k%Sd<`R9tRlAmo>swiK6&>NJJUK zQ!o|FQBDj-^b2y6Z2W06EN#XnTr4F+XjDYhnJIZjils6sw1kP8R8htl!>BEm#FP#i zP{4?qG|*uVY!j5J!#ohXJGJN~%#$bN&&_*Ke~qb>x&b>?;>XUyDEdnZeBA!T8Lny z^Sdep^uC>3;RcZUONl(~L#q+@&#(cp{2dP%g2;sqUcsqPHBiJWVAm_0jVm9=UYqLZ!m>V8Z*ot!>gZ_#&C!jIu=CXUuD@U z&*I7O_{QGtrvu+Xatowx(0wfg1l~3M^)Co0GCp!?om&LjSVW~zVL{WxXwYTVp{>y@ zxcx5&e}T%gX*d}JgxzLUZM=F5BYr$}>y7tzXM<{D2a&Jj{8?zeXiKzpzO#OGSU-24 zxSrVinD%Mw)X2TWvN5YQ>={AQj~=*Y*ecBzHu(LaUnB6#U{|1qBi!tBdHuWkpQF-= zn-&4S{AF&FUs&WK^%nM&6NNr95;3paN0ljJnm<+v5?yYtdwL&4*%kYNbL^pk1(Gnd zw0ce%c+j(2R%+j?$#==kxvOzjBjvt0vYwxl#*!Ki3(34QQpl140#Qt6d?j^dblcQ@ zQa{#Vnq)+bIB?_S?wuoKWkXsuQvhukhuP&!QCWdD|zWQAE)zoESzY7kiubT2>P0N5fPK?X4 z>!bm2E_0@9S8DO$K0*Trb>G-l&}$hm!4+ikZDtN6KmL`o{=mw$38_dolV&Z7td3p= zZLN;XUkBqm_N^6{*(M^ul+xCz3=K{qY91sD&ERFGjG`iqrc6fZORNILwQ#c*Q>s`i zjjX~{D$&Y9^~n#1&Q8@t*KXdMjpi~Lp9-im(8+(L>IK-XfM@=a`3c23c|tQ6MaJ^g z)LdQhW;q%sCB1tEdacUUmLb93IAb`9j01B;eJ&gy+~S^yYO7W*P3t$)N>$nR1wqS}b%0YTMt=sS{>&DDG9Mpc7tCN`bIxi@r z+R40kl}Au0*KDAWG-maa*aV>a#fTS&z>_DhKHAHOH;mZ<#6{Y4Xp~b`i*L&T&NM8P zhgH|9eK@U!m=PqRoGwD*sRP%c$aNxqK_eX zPBiB6s%L}Zn0MB}`Z!s+{26{U-ZAy+{V~hF%^;-HldeP42^%ToN9Q+y4>V>aOt=-SMAZA>8#UmcpBocw8PV5Pe~St80V-_6me zC9E`mnyH($!!a^Zy(t3I5ex-nw!jw=MRgL553Nb)Bq-B;L;*Aee`D{7SoqBVeSPF$ zIkY{Y!dlwe5jk!BbhAz<_)*GzlcGzl8o5MOA|h2zm8x8zt}I<5U8P)3ohp6shtPo= zgr4*TP{!OdoJ&8~?hfn9J-@8{TBHAo<{zzMHn|>4s8D`6OaFopl2cL;1IKqGY)!5U zx_}ll-AXwd9n!YGyo~I7T&XC?+8sCupdFyH@liW(NOWeTB|8ZXD7+VuFrN^yuP#fi zzy^bxxgo6lG$hGtCtP3YjEO2cYSp|h=*fHtgc;s z`Spu#CF%Kg@#^M46gN6##bJFTNR&*Q`2`Ep!{em-@Y+}7x$rq>AYnqUzSd?{*z1Q+pCDSqlK})0ra1M zW!VkzTrmQzac>zdOK-qmi4YNl7^&XD@%V8wR#A1{hKI{Tufoiwmt(ER6r;1ej`WA{ zd`1QrUs|#h)vedK13_o=U%r=iz<8>v#--S+@S+Ze`%fR*1en0iz`ES8?go6IxhrfD zEHyL4;I{u1w)qt%K*F0Mti0TWI7*z1j>YorLdIr%a)K%RpohQ;W(g-E39g%K=342MlS zEnK7#g4DAz+*@)|Tm_xXbw>z?u?Ie1;^_s97_!m~5s$^-PX}vN1cMGd;Sch+gQ8`t zSvi#1_u#$uH@$hxA4V$}o$sajW`))OP7#UHpTLzR+wQ<6SC*_mhz(FO8;UY4`{EV* z{cdAVggIeoY^^8aS++sCEkrVsze0t4a1{gSmQR-*C*1VsrL*iZ*tW^Tq1d}#mR$sm z9L=vZdzfqc>2x@!E5>cn_GC*@W2T4>lABq1?qKZG%L1iQ;-V72F8{XFVY>)YwB7dl zG4r1)UHysNwz&Ws=Ty531b%whar9| ztO1E=hXt^W5@VwnPCotBc79)33(E*7GnvuBw;YG8P{<1M%eEJ6F0CQ-Xy|z#96klw z5az!eH}-8Q><;ApN6XMC;%&3_g?N>TheThaTaw*;2uiNS?m5z_Yi@WMq*rcA%8)<3t#? zHx{Sp=2C_jzH#okFNBHo$O_WBK~^V({D4=3ZRpl^)R!iIt4u{~XgqLK zvpm5Bn9$8=4vY#+!^o_NpFeLUZ_{EQbr|Od0tbb}#_hXEZP;Ea#9>4}*0ANOZk&Jq zvn8=Ptb21Z7%738Mz)U^n3}8 z1`UiXwzhs38;spc)F>b-)^=}_z1t*5aP0na@T%S8uTLo^3cAphc4N-T>!yP50nfzz zS4VjOMzk=l?cPAH(pg}0*bt8z@c@-PC7J3r`+fafu6$|)bHsdfrRmrkj9k~TO)5$* zPDhK*-|%omJ?#shTo_a}(4UA$ zq?BAH`0@Z3ic-9r@&1}s)2Y)cinAL454{^uJ>|DSsq)JxlA@NTRZJrP23&vvt0oVD zFRC+O*5|Gs*3gWZ779*)G%4ARAS*>ETI&{OCo{h*>XVsIliY0vVMt!O(DK=i2({e* zw66a(_9FiC?m$VgN^cll7;utR65RwVitq4cx1{$PKY8 zimaY&i$pW^gMPV^beFL$95<~qSxCj6)T9(lB@MsupCiRIe)o|1FHTtTx1IF5&&5zD zR=ibE2lff}MJY(Ig_k5DXMOBl@jp2fvwa?YB|J?P;oUBtUl;#YGAPaeR4X8OpU(0M z92xH}y7i;5TvXq4e7Akl3^Ep(dvvVV|Y>?K)mS*niy- zN@VBZ&Q2f--eK4}ir4q>T04twA|L2jr#|-=(s=(m%4}A;q(PF_U(s={mPWd(ob?RZ zKhkY~$xxj+T~p}y-)qzy(5BPpDbpBK_Z1yApmVv>Obp^S=l!5!l)|J4NxUW%aNCF1+38j_H=0m#koif z4S;`C5FZ8f4|ogpI)GM?#2)94odyk$y(u|dymfo#bkIBj@ka16V&_K@VoWJu#q4Z%e9DP_eh3&p67}ExKN7oQ;i9xFT>PYC zs^nb?s>$6oS_2ZgaLnp2F(_(crOW`A_TronmOYD3Jv`>0cBFLr0r;SJQWh=J$Gz#X zH_qD98!|~+Xj-EPgR4=oC70iPf3knOEcpXxA7jkiRNYH_Hb>~VUertcgogwQ%N0Ud zcNW}ipOs&`OZct1)<&fGF(d@xvl~|0U%#0YG_fdHN7tV2b=lQxwxB~#|D!z{13=D* z=Nz9hwHvh@;*iGQWdePMx^pyMx0J4+#dOE=DtZ`0jjQt66u8l_J6Z?JOsW3eWF@2j z?bbst~wwkKFGv&y%(_A*;)A~#PK)r0!v@@rPL-|C*TsEAQwZhH^uH|jy)2scDbkDi<4GPaU-?X*j*16A<8#u>Y(6md8<1#+6n*-vA@FQ3hZrZB=Lj=TAaWT zap0Q_+KB$qsV#n8&E9o@EW;{%0+}tJ-x1?=5--<&kyZ3Ra@0FFLFaF)BeDfkl=Yjw zb+Qy)W(1Yw^$8r9NjiR?VdZ2-F{Y82YQ-ttFrn%ut~g}eeD`@$HJ5$(V@b zprj4hnn1-Q!O1MMn74|Xed|D^A|zZeX=4J>>?YztP_>{?Ore1~%zr+YH!N{08>vP# zJ`8&pYX2om#(x{)cQwDE#J!}QGA(!uh{_jWPPlZ)WYs=@EKbb`Sd`13eSpdK>Hca)w+Q8DNvoTY_v zA;v0;0I{io09qEE0XSn|zcZmwi0Gg+DNtwUuQP(m=Y6aQS?H#ojC(}2Q7H4x8bPI^ zfwPEQ^@03hbBYAnv5Cvv-n1M(nou=1CKx2M)|l}o(J>2j+U{6fFxU_+{Jx7Q=r>i5 zO+r7F?c;07x~vmVpKwZG*$)xPQl-tm^qYt%uLZ^;QdB9?={cXQL+=cF8N~*Fd!Mtb zDo7GT;JF}C9H*63y`e@2WSrJpeeOrippwc&v1p3^xi03l-@-QKh|agFPoIxYV}Vm& zYM-<{6Ta0{9uF_E#{+>Z??Y3BPGf-CvyJtN4X8++i3Hil0uO0}CBo}@|79W7mzyyE zTBpHGx^oBykBqGfhB6SS$S{+Xb0A9LJ*GDh6T(qQ-Sw8@*p}1;UeTf`z6Pq+uRd2b zWnkjv`-eM*8-ETG8$_*jiII<{ zZkOhMppb(&A=4nCqJ*KKq6xK;FVru*271g`#FC-Ay7$`OLJ{!{cpVaqFh1~NRe>`w zv0m|1IZ@Yg;qTbt=+s=rIXixC6xzgzYF!Homgw+@LMcyth%{f%3}1c_&z5FAbH&%g@I{K7d zrfHl^$)o_~%JSr_QbJO+GI^CbIn1Q*xt;ANo7Wk}_g-;oKXVkuw$WN|&+_Z0o->oZ zs$!HQ&Wsm&@0L?4P+rEyy)JtLD|X9$tA{rDnYbd|l0f+*v7zr)|1^AMy`D^}B6$|X zR8~3jA?o$uhiXn$!i4OUu}Gn%{h<69To*}eyJGja8pZcq<1EwAE-ePeUK9s7qFpwS z0)FrVX{3+gVt1QD@kkz%0v0Wsf0-!*Eg=zHK6nTc52+J*!Je$wUYoxrpwO5k*?B;{ zwikyg5le~mEcRlr&kBNSm-_03OkBFlMO3Bh3*`tj>RR&OcF5XbHSI|ZW*TUtN7cyqr z5-<3l%PD{uI9|e!HWJ0anvtb%|b|3ppBx18TQ1*T44cF9&n#_T+-V%TR)J@uws zWQyRKOA3Mi;9=4*YB|Wl_Xc8=jz<*rAk^wH(nNB#z^XNET|@G6Ip%DV%ctYN3-=S2X`Ta*PaFsdH2;kzQ_1-L!Z{X=;+NZ}1}ip)mV?Fc(_QW!5Wb@!<8 z&nV16BG|`)E>IF61Q8r~fevVD^t82tVgi|a;9QF9|2_<#tpccm{c6pwB^mYxi*$|1 z+DN9Ng?#@tjs<+B97nM(uu8dfspHXUG9J9cuLh_YR7dtg;3!i435eux)cN11q}Mfq z*3P~V|89FZ-C2bogzHV2xq2@B9(&AE$V8IreTGf!|2;#t=p1L54BWn4DN+3OOkz`ZPXJ-Ww ze@0h4VZnk&2kccc0}so_RuG^~lK<{W#QzlP^2>2BRZQTci!*Qx*554$4>k_39Vi6p4WB^% zi#r{EBq)Z4M;?nqwhi@sy^=#Dh*^O0Jn*|Wgyu;YV%u^3k>`Di=EFy??Qn~2ix~qlVp|}B~LR@qntMS8`l**xb6;05OS)+Z}J?EvUgJf)~ z`59_R+}gV0(DHBlC$OVCvutweyM3$1JcHIkj4@Z%_j4|&e0WbjP`%uRjPo^2c*)B zR3Go}?-xmp%8m9J&vF#+kE>P5Q;%YrM-Lc55f(K=_a;+*-uo}Px8MxsZn3J^82=9F zTp&>*_i#FUh3aGaSjo#IZM0(;b;jdu+#7kQ@#=X9CVUvjNNN2;6E9Vd!ME~}{@XjI z>@;&F3|~^8OLq%i?&HRvk3Ok(`CN|dIY88rD>r{tYI@7cWQW1m^-H?|JcU(V$6;|=><=r$@TB`%cx#6=Evvpj7en= zgrS7?h1k05=bKi1)xFsuKB4a-tS>>ERRi}GX!Fmiw&GmBhJE`Z+x?}GLNl%~ zu(q84(F|Y|<7xt4%5XbnIg{|-$RO__^SzUVi`Y$}b=38j&>;|yTVpq^V*e51e90Ne zZM+YZ_Y^l;mTH^veLrWdNd#MzUQK>0`COYsHhVE9oIw&$y&9CZ_{uG~Ev%u$E%MB3 z=>jN_z2hm2%5&WzZzNCX;aOoa+6i`^fM`3@cH&hFp()k^J`aHs#N@2urH6mgLUAG1 zMRNXZ3!KLNs8FuO5)?uglfrkN#D)q@Nk&T-TQH>>Gx+9j{_a#{Qoac3UfqFTj# zq-LJc<;eZi?*m3|!V)Uc-ZgJHNUZyxy~0(Q{o(&+ukgP>P&57y_X=76%U&Vd|GT|H zW+ratFHs3g8y8cjuTL987gI4)V|x=*qJOGzon4$v4Q&zO0FnC|)~c#Yn4MC8(%c$p zEoW2T0Q6cav1o|NY>k6YT5VcIk>&4mgGm;)8dXwR8O39OLZrf=C=m=28k~J%Bh?@v z$*^e14l}}(g~utM$2dqI6DvaBbw=h|M>rR_6DLbbtH$2rUUuu_AM^Z|@MACD0LjdO)&tbh=Zipi){RT#%!1PN^5Wi*h(#b8!(ptIs&u7sec z$j-}7T8M-oJVsDavtR=p;N+WN(&b>%>0naT1(1l-6L&&UDnh5pLSe>2;D|y^OzAa9 zoZf+W)Ax}aKrWYk9mMGYIN%}@u$K-PB_rf&9;oVg{>T&x%=jdC& zT!o}eh0@7eiceayj?d&`v>m|!!SI%EV9pr)>l3~lKyVx%S~NSm2A>j=n!7q|voE)6;uKk!WlS*zw_s(>*&O6)9pBMZto{ zIOE{52h3dSjmZ#{JN?yS4))f>1$A7U~ntfI8S0R@O=zREjq!APYt{){drcW#+eE07_5| zs>rk3=;B%mN&1Ct1oJfC z<7Ab;AR-dMcbX2sdU#r}@sB|TDSJW9yVEA};3G9j5 zI$EaZnW8qN(cqZ(Kq>jwt~f9IpG$$Niq=6#WOf4Vj+ZCm69}F@&caB}zj-YkJCZR} z@m}172oaH&ZY~z0M=XW36_IXX_7Erw2C6Q0x#M(271i1irFdH|r@1r*r&`v;#LIK7 zSIy-3Jg%wQNg8NPnj?;f=G@I(A$0J}yAt50w8>c|VQ_llmy4D)V7-F?(~AI#U@{U+OW4!QL`!nc-# zHS7#=X2g+SdUK6R4l?R zgIv>&B>=2}7WYZa1EE+9hh~Gl{veQSxM>a;2O9y2XgLp^%$l_35Yw%6 z!WQL$NWZ{yamr9D^*A+CkH)pMXRS3HTSs^{`h!Y^IMw)tCMaCcqn*ELEf_vlE`hl2 z*qN$Z*VotYA%)IA5QL0v`dYBV*m7GCdf~*(gc-%4a_vKW?bp2ag^~d2)+ykX14gGn z79{sx@CPzGg=&yN{$9D_;WtFVdxE_4tUJ>19gioL8MuNGFi!3+`6z+8AaV}wn#juX z;mOi`g5RCV9D7kQ*j+nt20O4n8V?h<`0U{5kyXE!e-n}-7qVOmyqyj@=TnqJIJ_<9 zAtUQw-!gADG;otFZ2F(7ur^bRHKpN<4R;M!==^m6?jr#mIq z2y;no!@k}vU%eKq2@`!G5PmlD;~TRQg^ol0o=fr@@8KivQ^bPd?`MYKUvqNdYNgp1 z8O=y8_2_fIMT7+(=HehU_gOkEt+Hx{6|J-_!yMGq1@(4cb#R>T4+RwjM_IPJBIUpdOa zeR__=-{5bwnNqS#0rOCl%j>_<+808c8Wf$7K(M;58%G9PYt-AfCCOMsyd9u3E;`25 zQkO}k%=bv}dKsc3pj9K)Jg^U*HFU3`5Dp*XI99S;a(2<9bYp%nJ5?q#!#mA#`8B8`&|1AlNefwRQmn^C%#s^_(MBs zveE9W^v=P$lW*`f$^T>V=BiCR;yG87P#Q+kHpHPI3&tdK4vx-T9K#|Gt<@UP z3g+6RrYG@3-w; zR07E&g$|U2{_Y4(KnLD0FFtN__jL9h(57wWwisW|fPc3Dg|h~Uss@p!gOKjYB|Z8E zEQA1Ndq5;grqb!OFr6E3C4Fo-tQ^5?nl51apg<8u^+?XgAqY(2`p`qw^lrOWZx0Bm zO$l&&*4yQiJ_+c+OJ0B9b>9*^f1J@qWS-pa>e*&xegZ@21PiuzfQ(-&G(B?QbYI8h zvn$-G-i8l@)Q{=$KY|gcTU=Ul-~Yoj1IX{AW1z^&L}@%a!bTaH`rN-FFaDwu>>1n} z#`YYDS?oD&tg)|QX7cKbt#XLWaE*@MZ#V5`x}DU;xli(-4TIe?TYnC z_$nC$Od6&(ePHlrq}l8cd6_VYGLD06oz7aIQZ zFhi7K09wAjywg6}4z9Ss89DSz_^D}vC&+rB zgO2EcnEPwDP`&9ax_=e^)-uQ~{2}DckC229!P`nUnkZU$jmaElL5jVcjD39cDK2AD z5mGtqSgPv&SO5m-N(fX@Tv;S@l%pb(9kbPL%Op-ZS5^jI_7GC`jhHhb6}qs5 zs(xv&OAnLIo0suqv>;lc@M|iYW*nf2W4uvb-b_X2s7gxD0`KeLKwTVsZq;q`O)(UBz%PH)whf-ehSu{TANNU_dvD__EUD7F z6Q>KxVNY$4NIJ`11kJubk^Ds- zh8+aooE6tvOr7WQ+o6P%-=(eMJ*jt<^Ox6AIuQC�(W1TIraS9nzNJ^%AUNy|X%4 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 zℑ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 Ds7MyH diff --git a/pcb/flat-20mm.scad b/pcb/flat-20mm.scad deleted file mode 100644 index 6715f7c6..00000000 --- a/pcb/flat-20mm.scad +++ /dev/null @@ -1,59 +0,0 @@ -/** \file - * Brackets for 20mm extrusion. - * - * These hold the panels a few mm away from the bracket in alternating - * orientation. - */ - -width=20; - -module baseplate() -{ -render() difference() -{ - translate([0,0,3]) cube([32,28,6], center=true); - - translate([0,-10,-1]) cylinder(r=3.75/2, h=6, $fs=1); - translate([0,-10,2]) cylinder(r=6/2, h=5, $fs=1); - - translate([0,+10,-1]) cylinder(r=3.75/2, h=6, $fs=1); - translate([0,+10,2]) cylinder(r=6/2, h=5, $fs=1); -} -} - -module upright() -{ - rotate([0,-90,0]) render() difference() { - linear_extrude(height=6) - polygon([[-1,-14], [0,-14], [20,-5], [20,+5], [0,+14], [-1,+14]]); - translate([10,0,-1]) cylinder(r=4.5/2, h=8, $fs=1); - } -} - -module bracket() -{ - baseplate(); - translate([20/2+6,0,6]) upright(); - translate([-20/2,0,6]) upright(); -} - - -for (i=[-3:4]) -{ - translate([0,i*30,0]) bracket(); -} - -%color([0,1,0]) translate([0,0,width/2+6]) extrusion(100); - -module extrusion(len) -{ - render() difference() - { - cube([width,len,width], center=true); - translate([width/2-5/2+1,0,0]) cube([5,len+2,5], center=true); - translate([-width/2+5/2-1,0,0]) cube([5,len+2,5], center=true); - - translate([0,0,-width/2+5/2-1]) cube([5,len+2,5], center=true); - translate([0,0,width/2-5/2+1]) cube([5,len+2,5], center=true); - } -} diff --git a/pcb/octoscroller.brd b/pcb/octoscroller.brd deleted file mode 100644 index d0192b9e..00000000 --- a/pcb/octoscroller.brd +++ /dev/null @@ -1,2228 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Octoscroller^2 v1.3 -http://trmm.net/Octoscroller -2014-05-05 -GND -GND - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE ->NAME ->VALUE -P8 -P9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Dual In Line Package</b> - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>Pin Header Connectors</b><p> -<author>Created by librarian@cadsoft.de</author> - - -<b>PIN HEADER</b> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - -<b>Molex Connectors</b><p> -<author>Created by librarian@cadsoft.de</author> - - -<b>MOLEX 2.54mm KK CONNECTOR</b> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME -1 -2 ->VALUE - - - - - - -<b>Test Pins/Pads</b><p> -Cream on SMD OFF.<br> -new: Attribute TP_SIGNAL_NAME<br> -<author>Created by librarian@cadsoft.de</author> - - -<b>TEST PAD</b> - - ->NAME ->VALUE ->TP_SIGNAL_NAME - - - - - - - - - - - - - - -<b>EAGLE Design Rules</b> -<p> -Die Standard-Design-Rules sind so gewählt, dass sie für -die meisten Anwendungen passen. Sollte ihre Platine -besondere Anforderungen haben, treffen Sie die erforderlichen -Einstellungen hier und speichern die Design Rules unter -einem neuen Namen ab. -<b>EAGLE Design Rules</b> -<p> -The default Design Rules have been set to cover -a wide range of applications. Your particular design -may have different requirements, so please make the -necessary adjustments and save your customized -design rules under a new name. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pcb/octoscroller.sch b/pcb/octoscroller.sch deleted file mode 100644 index 064275db..00000000 --- a/pcb/octoscroller.sch +++ /dev/null @@ -1,3660 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE ->NAME ->VALUE -P8 -P9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Dual In Line Package</b> - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>Wide Small Outline package</b> 300 mil - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->VALUE ->NAME - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Leadless Chip Carrier</b><p> Ceramic Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -P8 -P9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - ->NAME -GND -VCC - - - - - - -Should match A3 pinout - but not completely tested - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Octal <b>BUS TRANSCEIVER</b>, 3-state - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Pin Header Connectors</b><p> -<author>Created by librarian@cadsoft.de</author> - - -<b>PIN HEADER</b> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - -<b>PIN HEADER</b> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - -<b>PIN HEADER</b> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Supply Symbols</b><p> - GND, VCC, 0V, +5V, -5V, etc.<p> - Please keep in mind, that these devices are necessary for the - automatic wiring of the supply signals.<p> - The pin name defined in the symbol is identical to the net which is to be wired automatically.<p> - In this library the device names are the same as the pin names of the symbols, therefore the correct signal names appear next to the supply symbols in the schematic.<p> - <author>Created by librarian@cadsoft.de</author> - - - - - ->VALUE - - - - - -<b>SUPPLY SYMBOL</b> - - - - - - - - - - - - - - -<b>Molex Connectors</b><p> -<author>Created by librarian@cadsoft.de</author> - - -<b>MOLEX 2.54mm KK RA CONNECTOR</b> -<br>Fixed Orientation - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME -1 -2 ->VALUE - - - - - - -<b>MOLEX 2.54mm KK CONNECTOR</b> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME -1 -2 ->VALUE - - - - - - - ->NAME ->VALUE - - - - ->NAME - - - - - -<b>CONNECTOR</b><p> -wire to board 2.54 mm (.1 inch) pitch header - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Test Pins/Pads</b><p> -Cream on SMD OFF.<br> -new: Attribute TP_SIGNAL_NAME<br> -<author>Created by librarian@cadsoft.de</author> - - -<b>TEST PAD</b> - - - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - - - - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - - ->NAME ->VALUE ->TP_SIGNAL_NAME - - - -<b>TEST PAD</b> - - ->NAME ->VALUE ->TP_SIGNAL_NAME - - - -<b>TEST PAD</b> - - ->NAME ->VALUE ->TP_SIGNAL_NAME - - - -<b>TEST PAD</b> - - ->NAME ->VALUE ->TP_SIGNAL_NAME - - - -<b>TEST PAD</b> - - ->NAME ->VALUE ->TP_SIGNAL_NAME - - - -<b>TEST PAD</b> - - ->NAME ->VALUE ->TP_SIGNAL_NAME - - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - -<b>TEST PAD</b> - ->NAME ->VALUE ->TP_SIGNAL_NAME - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->TP_SIGNAL_NAME - - - - - - -<b>TEST PIN</b> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pcb/receiver-4x.brd b/pcb/receiver-4x.brd deleted file mode 100644 index 6a1bfa2d..00000000 --- a/pcb/receiver-4x.brd +++ /dev/null @@ -1,1567 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ - -LEDscape receiver -Rev B 2014-09-2 -By Matt Mets - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- + -- + -RJ45 signals: -1. D0+ -2. D0- -3. D1+ -4. N/C -5. N/C -6. D1- -7. GND -8. GND - -- + -+ - -+ - -+ D - -+ D - -+ D - -+ D - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Small Outline Package</b> - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<h3>SparkFun Electronics' preferred foot prints</h3> -In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> -We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. -<br><br> -<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>EAGLE Design Rules</b> -<p> -Die Standard-Design-Rules sind so gewählt, dass sie für -die meisten Anwendungen passen. Sollte ihre Platine -besondere Anforderungen haben, treffen Sie die erforderlichen -Einstellungen hier und speichern die Design Rules unter -einem neuen Namen ab. -<b>Laen's PCB Order Design Rules</b> -<p> -Please make sure your boards conform to these design rules. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Since Version 6.2.2 text objects can contain more than one line, -which will not be processed correctly with this version. - - - diff --git a/pcb/receiver-4x.sch b/pcb/receiver-4x.sch deleted file mode 100644 index 87271f88..00000000 --- a/pcb/receiver-4x.sch +++ /dev/null @@ -1,6471 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<h3>SparkFun Electronics' preferred foot prints</h3> -In this library you'll find non-functional items- supply symbols, logos, notations, frame blocks, etc.<br><br> -We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. -<br><br> -<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. - - - - - ->VALUE - - - - - ->VALUE - - - - - -<b>SUPPLY SYMBOL</b> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Small Outline Package</b> - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - -<b>Dual In Line Package</b> - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>Small Outline Package</b> .150 SIOC<p> -Source: http://www.maxim-ic.com/package_drawings/21-0041B.pdf - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->VALUE ->NAME - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -B1 -A1 -B2 -A2 -B3 -A3 -B4 -A4 - - - - - - - - - - - - - - - - - - - - - - - - - ->VALUE ->NAME - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>±15kV ESD-Protected, 10Mbps, 3V/5V, Quad RS-422/RS-485 Receivers</b><p> -Source: http://pdfserv.maxim-ic.com/en/ds/MAX3095-MAX3096.pdf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Header 3</b> -Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08232 with associated crimp pins and housings. - - - - - - - - - - - - - - - - - - - -<h3>SparkFun Electronics' preferred foot prints</h3> -In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> -We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. -<br><br> -<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - -Header for OS4000-T - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - -This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place. -You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line). -This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace" -to hold the component in place. 0.005 has proven to be the perfect amount of "off-center" position when using our standard breakaway headers. -Although looks a little odd when you look at the bare footprint, once you have a header in there, the alteration is very hard to notice. Also, -if you push a header all the way into place, it is covered up entirely on the bottom side. This idea of altering the position of holes to aid alignment -will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins. - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - ->VALUE ->NAME - - - - - - - - - -<b>Header 5</b> -Standard 5-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08230 with associated crimp pins and housings. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -MELF 0.10 W - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -MELF 0.25 W - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -MELF 0.12 W - - - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -MELF 0.10 W - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -MELF 0.25 W - - - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -MELF 0.25 W - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -MELF 0.12 W - - - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -MELF 0.25 W - - - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -type 0204, grid 5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0204, grid 7.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0207, grid 10 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0207, grid 12 mm - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - -<b>RESISTOR</b><p> -type 0207, grid 15mm - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - -<b>RESISTOR</b><p> -type 0207, grid 2.5 mm - - - - - - - ->NAME ->VALUE - - -<b>RESISTOR</b><p> -type 0207, grid 5 mm - - - - - - - ->NAME ->VALUE - - -<b>RESISTOR</b><p> -type 0207, grid 7.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0309, grid 10mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0309, grid 12.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0411, grid 12.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0411, grid 15 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0411, grid 3.81 mm - - - - - - ->NAME ->VALUE - - - -<b>RESISTOR</b><p> -type 0414, grid 15 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0414, grid 5 mm - - - - - - ->NAME ->VALUE - - - -<b>RESISTOR</b><p> -type 0617, grid 17.5 mm - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0617, grid 22.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0617, grid 5 mm - - - - - - ->NAME ->VALUE - - - -<b>RESISTOR</b><p> -type 0922, grid 22.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - -<b>RESISTOR</b><p> -type 0613, grid 5 mm - - - - - - ->NAME ->VALUE - - - -<b>RESISTOR</b><p> -type 0613, grid 15 mm - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0817, grid 22.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -0817 - - - - -<b>RESISTOR</b><p> -type 0817, grid 6.35 mm - - - - - - ->NAME ->VALUE -0817 - - - -<b>RESISTOR</b><p> -type V234, grid 12.5 mm - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type V235, grid 17.78 mm - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type V526-0, grid 2.5 mm - - - - - - - - - - ->NAME ->VALUE - - -<b>Mini MELF 0102 Axial</b> - - - - ->NAME ->VALUE - - - -<b>RESISTOR</b><p> -type 0922, grid 7.5 mm - - - - - - ->NAME ->VALUE -0922 - - - -<b>CECC Size RC2211</b> Reflow Soldering<p> -source Beyschlag - - - - - - ->NAME ->VALUE - - -<b>CECC Size RC2211</b> Wave Soldering<p> -source Beyschlag - - - - - - ->NAME ->VALUE - - -<b>CECC Size RC3715</b> Reflow Soldering<p> -source Beyschlag - - - - - - ->NAME ->VALUE - - -<b>CECC Size RC3715</b> Wave Soldering<p> -source Beyschlag - - - - - - ->NAME ->VALUE - - -<b>CECC Size RC6123</b> Reflow Soldering<p> -source Beyschlag - - - - - - ->NAME ->VALUE - - -<b>CECC Size RC6123</b> Wave Soldering<p> -source Beyschlag - - - - - - ->NAME ->VALUE - - -<b>RESISTOR</b><p> -type RDH, grid 15 mm - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -RDH - - - - -<b>RESISTOR</b><p> -type 0204, grid 2.5 mm - - - - - - ->NAME ->VALUE - - -<b>RESISTOR</b><p> -type 0309, grid 2.5 mm - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 2.4 x 4.4 mm - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 2.5 x 5 mm - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 3 x 5 mm - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 4 x 5 mm - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 5 x 5 mm - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 6 x 5 mm - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm + 5 mm, outline 2.4 x 7 mm - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 + 5 mm, outline 2.5 x 7.5 mm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 + 5 mm, outline 3.5 x 7.5 mm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 + 5 mm, outline 4.5 x 7.5 mm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 + 5 mm, outline 5.5 x 7.5 mm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 2.4 x 4.4 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 2.5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 4.5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 3 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 5.5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 7.5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -Horizontal, grid 5 mm, outline 7.5 x 7.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>CAPACITOR</b><p> -grid 7.5 mm, outline 3.2 x 10.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 7.5 mm, outline 4.2 x 10.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 7.5 mm, outline 5.2 x 10.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 10.2 mm, outline 4.3 x 13.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 10.2 mm, outline 5.4 x 13.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 10.2 mm, outline 6.4 x 13.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 10.2 mm + 15.2 mm, outline 6.2 x 18.4 mm - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 15 mm, outline 5.4 x 18.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 15 mm, outline 6.4 x 18.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 15 mm, outline 7.2 x 18.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 15 mm, outline 8.4 x 18.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 15 mm, outline 9.1 x 18.2 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 22.5 mm, outline 6.2 x 26.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 22.5 mm, outline 7.4 x 26.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 22.5 mm, outline 8.7 x 26.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 22.5 mm, outline 10.8 x 26.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 22.5 mm, outline 11.3 x 26.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 9.3 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 11.3 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 13.4 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 20.5 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 32.5 mm, outline 13.7 x 37.4 mm - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 32.5 mm, outline 16.2 x 37.4 mm - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 32.5 mm, outline 18.2 x 37.4 mm - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 37.5 mm, outline 19.2 x 41.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 37.5 mm, outline 20.3 x 41.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 3.5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 37.5 mm, outline 15.5 x 41.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 7.5 mm, outline 6.3 x 10.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 15.4 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 17.3 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>Ceramic Chip Capacitor KEMET 0204 Reflow solder</b><p> -Metric Code Size 1005 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 0603 Reflow solder</b><p> -Metric Code Size 1608 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 0805 Reflow solder</b><p> -Metric Code Size 2012 - - - - - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 1206 Reflow solder</b><p> -Metric Code Size 3216 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 1210 Reflow solder</b><p> -Metric Code Size 3225 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 1812 Reflow solder</b><p> -Metric Code Size 4532 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 1825 Reflow solder</b><p> -Metric Code Size 4564 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 2220 Reflow solder</b><p> -Metric Code Size 5650 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 2225 Reflow solder</b><p> -Metric Code Size 5664 - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - ->NAME ->VALUE - - - - - - -<B>RESISTOR</B>, American symbol - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<B>CAPACITOR</B>, American symbol - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->Name ->Value -+ -- - - -2mm SMD side-entry connector. tDocu layer indicates the actual physical plastic housing. +/- indicate SparkFun standard batteries and wiring. - - - - - - - - - - - - - ->Name ->Value -+ -- - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - ->Name ->Value - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - ->Name ->Value -+ -- - - -<H3>JST-2-PTH-KIT</h3> -2-Pin JST, through-hole connector<br> -<br> -<b>Warning:</b> This is the KIT version of this package. This package has a smaller diameter top stop mask, which doesn't cover the diameter of the pad. This means only the bottom side of the pads' copper will be exposed. You'll only be able to solder to the bottom side. - - - - - - - - - ->Name ->Value -+ -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place. -You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line). -This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace" -to hold the component in place. 0.005 has proven to be the perfect amount of "off-center" position when using our standard breakaway headers. -Although looks a little odd when you look at the bare footprint, once you have a header in there, the alteration is very hard to notice. Also, -if you push a header all the way into place, it is covered up entirely on the bottom side. This idea of altering the position of holes to aid alignment -will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins. - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->VALUE ->NAME - - - - -<b>Header 2</b> -Standard 2-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08233 with associated crimp pins and housings. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pcb/receiver.brd b/pcb/receiver.brd deleted file mode 100644 index 33643358..00000000 --- a/pcb/receiver.brd +++ /dev/null @@ -1,6490 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- + D -- + D -- + D -- + D -- + D -- + D -- + D -- + D -- + -+ - -- + -- - -- - -RS485 LED driver -Rev A 2013-08-05 -@cibomahto - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Small Outline Package</b> - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - -<h3>SparkFun Electronics' preferred foot prints</h3> -In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> -We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. -<br><br> -<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CHIPLED</b><p> -Source: http://www.osram.convergy.de/ ... LG_R971.pdf - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>EAGLE Design Rules</b> -<p> -Die Standard-Design-Rules sind so gewählt, dass sie für -die meisten Anwendungen passen. Sollte ihre Platine -besondere Anforderungen haben, treffen Sie die erforderlichen -Einstellungen hier und speichern die Design Rules unter -einem neuen Namen ab. -<b>Laen's PCB Order Design Rules</b> -<p> -Please make sure your boards conform to these design rules. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Since Version 6.2.2 text objects can contain more than one line, -which will not be processed correctly with this version. - - - diff --git a/pcb/receiver.sch b/pcb/receiver.sch deleted file mode 100644 index 1b9b7d1d..00000000 --- a/pcb/receiver.sch +++ /dev/null @@ -1,8072 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<h3>SparkFun Electronics' preferred foot prints</h3> -In this library you'll find non-functional items- supply symbols, logos, notations, frame blocks, etc.<br><br> -We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. -<br><br> -<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. - - - - - ->VALUE - - - - - ->VALUE - - - - - -<b>SUPPLY SYMBOL</b> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Small Outline Package</b> - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - -<b>Dual In Line Package</b> - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>Small Outline Package</b> .150 SIOC<p> -Source: http://www.maxim-ic.com/package_drawings/21-0041B.pdf - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->VALUE ->NAME - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -B1 -A1 -B2 -A2 -B3 -A3 -B4 -A4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>±15kV ESD-Protected, 10Mbps, 3V/5V, Quad RS-422/RS-485 Receivers</b><p> -Source: http://pdfserv.maxim-ic.com/en/ds/MAX3095-MAX3096.pdf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<h3>SparkFun Electronics' preferred foot prints</h3> -In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> -We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. -<br><br> -<b>Licensing:</b> CC v3.0 Share-Alike You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - -This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place. -You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line). -This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace" -to hold the component in place. 0.005 has proven to be the perfect amount of "off-center" position when using our standard breakaway headers. -Although looks a little odd when you look at the bare footprint, once you have a header in there, the alteration is very hard to notice. Also, -if you push a header all the way into place, it is covered up entirely on the bottom side. This idea of altering the position of holes to aid alignment -will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins. - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - ->NAME ->VALUE - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - ->Name ->Value -+ -- -S - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - ->Name ->Value - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - ->Value ->Name - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->VALUE ->NAME - - - - - - - -<b>Header 3</b> -Standard 3-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08232 with associated crimp pins and housings. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip - - - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -chip, wave soldering - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -MELF 0.10 W - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -MELF 0.25 W - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -MELF 0.12 W - - - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -MELF 0.10 W - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -MELF 0.25 W - - - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -MELF 0.25 W - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -MELF 0.12 W - - - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -MELF 0.25 W - - - - - - - - - - ->NAME ->VALUE - - - - - -<b>RESISTOR</b><p> -type 0204, grid 5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0204, grid 7.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0207, grid 10 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0207, grid 12 mm - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - -<b>RESISTOR</b><p> -type 0207, grid 15mm - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - -<b>RESISTOR</b><p> -type 0207, grid 2.5 mm - - - - - - - ->NAME ->VALUE - - -<b>RESISTOR</b><p> -type 0207, grid 5 mm - - - - - - - ->NAME ->VALUE - - -<b>RESISTOR</b><p> -type 0207, grid 7.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0309, grid 10mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0309, grid 12.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0411, grid 12.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0411, grid 15 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0411, grid 3.81 mm - - - - - - ->NAME ->VALUE - - - -<b>RESISTOR</b><p> -type 0414, grid 15 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0414, grid 5 mm - - - - - - ->NAME ->VALUE - - - -<b>RESISTOR</b><p> -type 0617, grid 17.5 mm - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0617, grid 22.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0617, grid 5 mm - - - - - - ->NAME ->VALUE - - - -<b>RESISTOR</b><p> -type 0922, grid 22.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - -<b>RESISTOR</b><p> -type 0613, grid 5 mm - - - - - - ->NAME ->VALUE - - - -<b>RESISTOR</b><p> -type 0613, grid 15 mm - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type 0817, grid 22.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -0817 - - - - -<b>RESISTOR</b><p> -type 0817, grid 6.35 mm - - - - - - ->NAME ->VALUE -0817 - - - -<b>RESISTOR</b><p> -type V234, grid 12.5 mm - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type V235, grid 17.78 mm - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>RESISTOR</b><p> -type V526-0, grid 2.5 mm - - - - - - - - - - ->NAME ->VALUE - - -<b>Mini MELF 0102 Axial</b> - - - - ->NAME ->VALUE - - - -<b>RESISTOR</b><p> -type 0922, grid 7.5 mm - - - - - - ->NAME ->VALUE -0922 - - - -<b>CECC Size RC2211</b> Reflow Soldering<p> -source Beyschlag - - - - - - ->NAME ->VALUE - - -<b>CECC Size RC2211</b> Wave Soldering<p> -source Beyschlag - - - - - - ->NAME ->VALUE - - -<b>CECC Size RC3715</b> Reflow Soldering<p> -source Beyschlag - - - - - - ->NAME ->VALUE - - -<b>CECC Size RC3715</b> Wave Soldering<p> -source Beyschlag - - - - - - ->NAME ->VALUE - - -<b>CECC Size RC6123</b> Reflow Soldering<p> -source Beyschlag - - - - - - ->NAME ->VALUE - - -<b>CECC Size RC6123</b> Wave Soldering<p> -source Beyschlag - - - - - - ->NAME ->VALUE - - -<b>RESISTOR</b><p> -type RDH, grid 15 mm - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -RDH - - - - -<b>RESISTOR</b><p> -type 0204, grid 2.5 mm - - - - - - ->NAME ->VALUE - - -<b>RESISTOR</b><p> -type 0309, grid 2.5 mm - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 2.4 x 4.4 mm - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 2.5 x 5 mm - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 3 x 5 mm - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 4 x 5 mm - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 5 x 5 mm - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm, outline 6 x 5 mm - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 mm + 5 mm, outline 2.4 x 7 mm - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 + 5 mm, outline 2.5 x 7.5 mm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 + 5 mm, outline 3.5 x 7.5 mm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 + 5 mm, outline 4.5 x 7.5 mm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 2.5 + 5 mm, outline 5.5 x 7.5 mm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 2.4 x 4.4 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 2.5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 4.5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 3 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 5.5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 7.5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -Horizontal, grid 5 mm, outline 7.5 x 7.5 mm - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>CAPACITOR</b><p> -grid 7.5 mm, outline 3.2 x 10.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 7.5 mm, outline 4.2 x 10.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 7.5 mm, outline 5.2 x 10.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 10.2 mm, outline 4.3 x 13.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 10.2 mm, outline 5.4 x 13.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 10.2 mm, outline 6.4 x 13.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 10.2 mm + 15.2 mm, outline 6.2 x 18.4 mm - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 15 mm, outline 5.4 x 18.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 15 mm, outline 6.4 x 18.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 15 mm, outline 7.2 x 18.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 15 mm, outline 8.4 x 18.3 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 15 mm, outline 9.1 x 18.2 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 22.5 mm, outline 6.2 x 26.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 22.5 mm, outline 7.4 x 26.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 22.5 mm, outline 8.7 x 26.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 22.5 mm, outline 10.8 x 26.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 22.5 mm, outline 11.3 x 26.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 9.3 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 11.3 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 13.4 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 20.5 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 32.5 mm, outline 13.7 x 37.4 mm - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 32.5 mm, outline 16.2 x 37.4 mm - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 32.5 mm, outline 18.2 x 37.4 mm - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 37.5 mm, outline 19.2 x 41.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 37.5 mm, outline 20.3 x 41.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 5 mm, outline 3.5 x 7.5 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 37.5 mm, outline 15.5 x 41.8 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 7.5 mm, outline 6.3 x 10.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 15.4 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>CAPACITOR</b><p> -grid 27.5 mm, outline 17.3 x 31.6 mm - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>Ceramic Chip Capacitor KEMET 0204 Reflow solder</b><p> -Metric Code Size 1005 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 0603 Reflow solder</b><p> -Metric Code Size 1608 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 0805 Reflow solder</b><p> -Metric Code Size 2012 - - - - - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 1206 Reflow solder</b><p> -Metric Code Size 3216 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 1210 Reflow solder</b><p> -Metric Code Size 3225 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 1812 Reflow solder</b><p> -Metric Code Size 4532 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 1825 Reflow solder</b><p> -Metric Code Size 4564 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 2220 Reflow solder</b><p> -Metric Code Size 5650 - - - - ->NAME ->VALUE - - - - -<b>Ceramic Chip Capacitor KEMET 2225 Reflow solder</b><p> -Metric Code Size 5664 - - - - ->NAME ->VALUE - - - - -<b>CHICAGO MINIATURE LAMP, INC.</b><p> -7022X Series SMT LEDs 1206 Package Size - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - -<B>LED</B><p> -5 mm, square, Siemens - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<B>LED</B><p> -2 x 5 mm, rectangle - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - -<B>LED</B><p> -3 mm, round - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<B>LED</B><p> -5 mm, round - - - - - - - - - - - ->NAME ->VALUE - - -<B>LED</B><p> -1 mm, round, Siemens - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<B>LED BLOCK</B><p> -1 LED, Siemens - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -<b>LED HOLDER</b><p> -Siemens - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>LED HOLDER</b><p> -Siemens - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>LED HOLDER</b><p> -Siemens - - - - - - - - - - - - - - - - - -A+ -K- ->NAME ->VALUE - - - - - -<b>LED HOLDER</b><p> -Siemens - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -+ -- - - -<B>IR LED</B><p> -infrared emitting diode, Infineon -TO-18, lead spacing 2.54 mm, cathode marking<p> -Inifineon - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<B>IR LED</B><p> -infrared emitting diode, Infineon -TO-18, lead spacing 2.54 mm, cathode marking<p> -Inifineon - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<B>LED</B><p> -rectangle, 5.7 x 3.2 mm - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<B>IR LED</B><p> -IR transmitter Siemens - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -<b>TOPLED® High-optical Power LED (HOP)</b><p> -Source: http://www.osram.convergy.de/ ... ls_t675.pdf - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -A -C - - - - - - - -<b>BLUE LINETM Hyper Mini TOPLED® Hyper-Bright LED</b><p> -Source: http://www.osram.convergy.de/ ... LB M676.pdf - - - - - - - - - - - - - - -A -C ->NAME ->VALUE - - - - - - - -<b>Super SIDELED® High-Current LED</b><p> -LG A672, LP A672 <br> -Source: http://www.osram.convergy.de/ ... LG_LP_A672.pdf (2004.05.13) - - - - - - - - - - - - - - - - - - - -C -A ->NAME ->VALUE - - - - - - - -<b>SmartLEDTM Hyper-Bright LED</b><p> -Source: http://www.osram.convergy.de/ ... LA_LO_LS_LY L896.pdf - - - - - - - ->NAME ->VALUE - - - - - -<b>Hyper TOPLED® RG Hyper-Bright LED</b><p> -Source: http://www.osram.convergy.de/ ... LA_LO_LS_LY T776.pdf - - - - - - - - - - - - - - - - ->NAME ->VALUE -A -C - - - - - - - - - - -<b>Hyper Micro SIDELED®</b><p> -Source: http://www.osram.convergy.de/ ... LA_LO_LS_LY Y876.pdf - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - -<b>Power TOPLED®</b><p> -Source: http://www.osram.convergy.de/ ... LA_LO_LA_LY E67B.pdf - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -C -A -C -C - - - - - - - - - - - -<b>Hyper CHIPLED Hyper-Bright LED</b><p> -LB Q993<br> -Source: http://www.osram.convergy.de/ ... Lb_q993.pdf - - - - ->NAME ->VALUE - - - - - - - -<b>Hyper CHIPLED Hyper-Bright LED</b><p> -LB R99A<br> -Source: http://www.osram.convergy.de/ ... lb_r99a.pdf - - - - ->NAME ->VALUE -+ - - - - - - - -<b>Mini TOPLED Santana®</b><p> -Source: http://www.osram.convergy.de/ ... LG M470.pdf - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - -<b>CHIPLED</b><p> -Source: http://www.osram.convergy.de/ ... LG_R971.pdf - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - -<b>CHIPLED</b><p> -Source: http://www.osram.convergy.de/ ... LG_LY N971.pdf - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - -<b>CHIPLED</b><p> -Source: http://www.osram.convergy.de/ ... LG_LY Q971.pdf - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - -<b>CHIPLED-0603</b><p> -Recommended Solder Pad useable for SmartLEDTM and Chipled - Package 0603<br> -Package able to withstand TTW-soldering heat<br> -Package suitable for TTW-soldering<br> -Source: http://www.osram.convergy.de/ ... LO_LS_LY L89K.pdf - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - -<b>SmartLED TTW</b><p> -Recommended Solder Pad useable for SmartLEDTM and Chipled - Package 0603<br> -Package able to withstand TTW-soldering heat<br> -Package suitable for TTW-soldering<br> -Source: http://www.osram.convergy.de/ ... LO_LS_LY L89K.pdf - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -A -K - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - -<B>RESISTOR</B>, American symbol - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<B>CAPACITOR</B>, American symbol - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>LED</b><p> -<u>OSRAM</u>:<br> - -- <u>CHIPLED</u><br> -LG R971, LG N971, LY N971, LG Q971, LY Q971, LO R971, LY R971 -LH N974, LH R974<br> -LS Q976, LO Q976, LY Q976<br> -LO Q996<br> - - -- <u>Hyper CHIPLED</u><br> -LW Q18S<br> -LB Q993, LB Q99A, LB R99A<br> - -- <u>SideLED</u><br> -LS A670, LO A670, LY A670, LG A670, LP A670<br> -LB A673, LV A673, LT A673, LW A673<br> -LH A674<br> -LY A675<br> -LS A676, LA A676, LO A676, LY A676, LW A676<br> -LS A679, LY A679, LG A679<br> - -- <u>Hyper Micro SIDELED®</u><br> -LS Y876, LA Y876, LO Y876, LY Y876<br> -LT Y87S<br> - -- <u>SmartLED</u><br> -LW L88C, LW L88S<br> -LB L89C, LB L89S, LG L890<br> -LS L89K, LO L89K, LY L89K<br> -LS L896, LA L896, LO L896, LY L896<br> - -- <u>TOPLED</u><br> -LS T670, LO T670, LY T670, LG T670, LP T670<br> -LSG T670, LSP T670, LSY T670, LOP T670, LYG T670<br> -LG T671, LOG T671, LSG T671<br> -LB T673, LV T673, LT T673, LW T673<br> -LH T674<br> -LS T676, LA T676, LO T676, LY T676, LB T676, LH T676, LSB T676, LW T676<br> -LB T67C, LV T67C, LT T67C, LS T67K, LO T67K, LY T67K, LW E67C<br> -LS E67B, LA E67B, LO E67B, LY E67B, LB E67C, LV E67C, LT E67C<br> -LW T67C<br> -LS T679, LY T679, LG T679<br> -LS T770, LO T770, LY T770, LG T770, LP T770<br> -LB T773, LV T773, LT T773, LW T773<br> -LH T774<br> -LS E675, LA E675, LY E675, LS T675<br> -LS T776, LA T776, LO T776, LY T776, LB T776<br> -LHGB T686<br> -LT T68C, LB T68C<br> - -- <u>Hyper Mini TOPLED®</u><br> -LB M676<br> - -- <u>Mini TOPLED Santana®</u><br> -LG M470<br> -LS M47K, LO M47K, LY M47K<br> - -<p> -Source: http://www.osram.convergy.de/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->Name ->Value -+ -- - - -2mm SMD side-entry connector. tDocu layer indicates the actual physical plastic housing. +/- indicate SparkFun standard batteries and wiring. - - - - - - - - - - - - - ->Name ->Value -+ -- - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - ->Name ->Value - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - ->Name ->Value -+ -- - - -<H3>JST-2-PTH-KIT</h3> -2-Pin JST, through-hole connector<br> -<br> -<b>Warning:</b> This is the KIT version of this package. This package has a smaller diameter top stop mask, which doesn't cover the diameter of the pad. This means only the bottom side of the pads' copper will be exposed. You'll only be able to solder to the bottom side. - - - - - - - - - ->Name ->Value -+ -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -This footprint was designed to help hold the alignment of a through-hole component (i.e. 6-pin header) while soldering it into place. -You may notice that each hole has been shifted either up or down by 0.005 of an inch from it's more standard position (which is a perfectly straight line). -This slight alteration caused the pins (the squares in the middle) to touch the edges of the holes. Because they are alternating, it causes a "brace" -to hold the component in place. 0.005 has proven to be the perfect amount of "off-center" position when using our standard breakaway headers. -Although looks a little odd when you look at the bare footprint, once you have a header in there, the alteration is very hard to notice. Also, -if you push a header all the way into place, it is covered up entirely on the bottom side. This idea of altering the position of holes to aid alignment -will be further integrated into the Sparkfun Library for other footprints. It can help hold any component with 3 or more connection pins. - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->VALUE ->NAME - - - - -<b>Header 2</b> -Standard 2-pin 0.1" header. Use with straight break away headers (SKU : PRT-00116), right angle break away headers (PRT-00553), swiss pins (PRT-00743), machine pins (PRT-00117), and female headers (PRT-00115). Molex polarized connector foot print use with SKU : PRT-08233 with associated crimp pins and housings. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/radials.config b/radials.config deleted file mode 100644 index 8ebecc7a..00000000 --- a/radials.config +++ /dev/null @@ -1,2 +0,0 @@ -ws2812 -135,32 diff --git a/strips.config b/strips.config deleted file mode 100644 index abc53166..00000000 --- a/strips.config +++ /dev/null @@ -1,2 +0,0 @@ -ws2812 -240,32 diff --git a/tall-cylinder.config b/tall-cylinder.config deleted file mode 100644 index 150a7f3f..00000000 --- a/tall-cylinder.config +++ /dev/null @@ -1,65 +0,0 @@ -matrix16 -0,0 L 0,0 -0,1 R 16,0 -0,2 L 32,0 -0,3 R 48,0 -0,4 L 64,0 -0,5 R 80,0 -0,6 L 96,0 -0,7 R 112,0 -3,0 L 128,0 -3,1 R 144,0 -3,2 L 160,0 -3,3 R 176,0 -3,4 L 192,0 -3,5 R 208,0 -3,6 L 224,0 -3,7 R 240,0 -2,7 L 256,0 -2,6 R 272,0 -2,5 L 288,0 -2,4 R 304,0 -2,3 L 320,0 -2,2 R 336,0 -2,1 L 352,0 -2,0 R 368,0 -1,7 L 384,0 -1,6 R 400,0 -1,5 L 416,0 -1,4 R 432,0 -1,3 L 448,0 -1,2 R 464,0 -1,1 L 480,0 -1,0 R 496,0 -4,0 L 0,32 -4,1 R 16,32 -4,2 L 32,32 -4,3 R 48,32 -4,4 L 64,32 -4,5 R 80,32 -4,6 L 96,32 -4,7 R 112,32 -7,0 L 128,32 -7,1 R 144,32 -7,2 L 160,32 -7,3 R 176,32 -7,4 L 192,32 -7,5 R 208,32 -7,6 L 224,32 -7,7 R 240,32 -6,7 L 256,32 -6,6 R 272,32 -6,5 L 288,32 -6,4 R 304,32 -6,3 L 320,32 -6,2 R 336,32 -6,1 L 352,32 -6,0 R 368,32 -5,7 L 384,32 -5,6 R 400,32 -5,5 L 416,32 -5,4 R 432,32 -5,3 L 448,32 -5,2 R 464,32 -5,1 L 480,32 -5,0 R 496,32 From 326f162c53150ba721d77e96c1ae60d94e4f7c41 Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Thu, 19 Mar 2015 22:58:09 -0700 Subject: [PATCH 320/332] Remove a duplicate From 93f2bdca95833ac0f55e00d03d0cff16bd06db87 Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Sat, 21 Mar 2015 22:46:54 -0700 Subject: [PATCH 321/332] Invaders is now semi-playable --- src/ledgames/Makefile | 1 - src/ledgames/invader_sprite.cc | 2 +- src/ledgames/invaders.cc | 50 +++++++++++++++-- src/ledgames/sprite.cc | 100 +++++++++++++++++---------------- src/ledgames/sprite.hh | 2 +- 5 files changed, 100 insertions(+), 55 deletions(-) diff --git a/src/ledgames/Makefile b/src/ledgames/Makefile index 8491cc76..68c96fbb 100755 --- a/src/ledgames/Makefile +++ b/src/ledgames/Makefile @@ -3,7 +3,6 @@ # Build the various demos # # -BIN-y += robin-hood-test BIN-y += breakout BIN-y += black BIN-y += white diff --git a/src/ledgames/invader_sprite.cc b/src/ledgames/invader_sprite.cc index 270e5fe9..4e3c561c 100644 --- a/src/ledgames/invader_sprite.cc +++ b/src/ledgames/invader_sprite.cc @@ -8,5 +8,5 @@ invader_sprite_t::invader_sprite_t() : void invader_sprite_t::move_sprite(void) { sprite_t::move_sprite(); - frame_ = (int)x_ % 2; + frame_ = (int)x_ & 0x01; } diff --git a/src/ledgames/invaders.cc b/src/ledgames/invaders.cc index 35d16225..f903d068 100644 --- a/src/ledgames/invaders.cc +++ b/src/ledgames/invaders.cc @@ -30,6 +30,7 @@ static int number_players; static int current_player; static sprite_t ship_sprite; +static sprite_t ship_missile_sprite; static std::vector invader_sprites[2]; static Mix_Chunk *startup_bong; @@ -47,9 +48,12 @@ enum class game_state_t { }; static game_state_t game_state; +static bool invaders_right; +static bool shot_fired; static void reset_invaders(int for_player) { invader_sprites[for_player].clear(); + invaders_right = true; for (int row_counter = 0; row_counter < 4; row_counter++) { for (int column_counter = 0; column_counter < 6; column_counter++) { invader_sprite_t invader_sprite; @@ -69,6 +73,8 @@ static bool reset_round(void) { return false; } + shot_fired = false; + ship_missile_sprite.set_active(false); game_state = game_state_t::Serving; return true; @@ -93,6 +99,8 @@ static void reset_game(int with_number_players) { reset_round(); + game_state = game_state_t::Playing; + printf("\n\n\nGAME START\n\n\n"); } @@ -115,20 +123,39 @@ void render_game(Screen *screen) { screen->draw_start(); ship_sprite.draw_onto(screen); + ship_missile_sprite.draw_onto(screen); + ship_missile_sprite.move_sprite(); + if (ship_missile_sprite.get_y_position() < 0.0f) { + ship_missile_sprite.set_active(false); + } bool change_direction = false; for (auto &invader_sprite : invader_sprites[current_player]) { invader_sprite.move_sprite(); if (invader_sprite.is_active()) { - if ((invader_sprite.get_x_position() < 0) || (invader_sprite.get_x_position() > 50)) { + if ((invaders_right && (invader_sprite.get_x_position() > 57)) || (!invaders_right && (invader_sprite.get_x_position() < 1))) { change_direction = true; } } } if (change_direction) { - for (auto &invader_sprite : invader_sprites[current_player]) { - invader_sprite.set_speed(-0.05, 0); + if (invaders_right) { + invaders_right = false; + for (auto &invader_sprite : invader_sprites[current_player]) { + invader_sprite.set_speed(-0.05, 0); + if (game_state == game_state_t::Playing) { + invader_sprite.set_position(invader_sprite.get_x_position(), invader_sprite.get_y_position()+1); + } + } + } else { + invaders_right = true; + for (auto &invader_sprite : invader_sprites[current_player]) { + invader_sprite.set_speed(0.05, 0); + if (game_state == game_state_t::Playing) { + invader_sprite.set_position(invader_sprite.get_x_position(), invader_sprite.get_y_position()+1); + } + } } } @@ -174,12 +201,27 @@ void render_game(Screen *screen) { ship_sprite.x_++; } } + + if ((!shot_fired) && (player_controls[current_player]->is_pressed(button_a))) { + ship_missile_sprite.set_active(true); + ship_missile_sprite.set_position(ship_sprite.get_x_position(), 51); + ship_missile_sprite.set_image(196,0,7,7,&sprite_sheet); + ship_missile_sprite.set_speed(0.0f, -2.0f); + shot_fired = true; + } + if (!player_controls[current_player]->is_pressed(button_a)) { + shot_fired = false; + } } if (game_state == game_state_t::Playing) { bool active_invaders = false; for (auto &invader_sprite : invader_sprites[current_player]) { active_invaders |= invader_sprite.is_active(); + if (invader_sprite.test_collision(ship_missile_sprite)) { + invader_sprite.set_active(false); + ship_missile_sprite.set_active(false); + } } if (!active_invaders) { reset_invaders(current_player); @@ -196,7 +238,7 @@ static void init_sdl(void) { int audio_rate = 44100; Uint16 audio_format = AUDIO_S16SYS; int audio_channels = 2; - int audio_buffers = 8192; + int audio_buffers = 16384; if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) != 0) { fprintf(stderr, "Unable to initialize audio: %s\n", Mix_GetError()); diff --git a/src/ledgames/sprite.cc b/src/ledgames/sprite.cc index fdfdc115..2e1b55e1 100644 --- a/src/ledgames/sprite.cc +++ b/src/ledgames/sprite.cc @@ -1,88 +1,92 @@ #include "sprite.hh" sprite_t::sprite_t() : - x_(0), - y_(0), - dx_(0), - dy_(0), - frame_(0), - active_(true) +x_(0), +y_(0), +dx_(0), +dy_(0), +frame_(0), +active_(true) { } sprite_t::~sprite_t() { } -bool sprite_t::is_active(void) { - return active_; +bool sprite_t::is_active(void) const { + return active_; } void sprite_t::set_active(bool active) { - active_ = active; + active_ = active; } void sprite_t::set_position(float x, float y) { - x_ = x; - y_ = y; + x_ = x; + y_ = y; } void sprite_t::set_speed(float dx, float dy) { - dx_ = dx; - dy_ = dy; + dx_ = dx; + dy_ = dy; } void sprite_t::move_sprite(void) { - x_ += dx_; - y_ += dy_; + x_ += dx_; + y_ += dy_; } void sprite_t::set_image(uint8_t width, uint8_t height, uint32_t *pixels, uint8_t anim_frame) { - sprite_data_[anim_frame].resize(width * height); - sprite_data_[anim_frame].assign(pixels, pixels+(width * height)); + sprite_data_[anim_frame].resize(width * height); + sprite_data_[anim_frame].assign(pixels, pixels+(width * height)); - width_ = width; - height_ = height; + width_ = width; + height_ = height; } void sprite_t::set_image(uint16_t x_offset, uint16_t y_offset, uint8_t width, uint8_t height, png_t *png_image, uint8_t anim_frame) { - sprite_data_[anim_frame].resize(width * height); - - width_ = width; - height_ = height; - - for (uint8_t y = 0; y < height; y++) { - png_byte* row = png_image->row(y + y_offset); - for (uint8_t x = 0; x < width; x++) { - uint8_t *sprite_pixel = (uint8_t*)&(sprite_data_[anim_frame][x + (y * width)]); - uint8_t *png_pixel = (uint8_t*)&(row[(x + x_offset) * 4]); - sprite_pixel[0] = png_pixel[2]; - sprite_pixel[1] = png_pixel[1]; - sprite_pixel[2] = png_pixel[0]; - } - } + sprite_data_[anim_frame].resize(width * height); + + width_ = width; + height_ = height; + + for (uint8_t y = 0; y < height; y++) { + png_byte* row = png_image->row(y + y_offset); + for (uint8_t x = 0; x < width; x++) { + uint8_t *sprite_pixel = (uint8_t*)&(sprite_data_[anim_frame][x + (y * width)]); + uint8_t *png_pixel = (uint8_t*)&(row[(x + x_offset) * 4]); + sprite_pixel[0] = png_pixel[2]; + sprite_pixel[1] = png_pixel[1]; + sprite_pixel[2] = png_pixel[0]; + } + } } void sprite_t::draw_onto(Screen *screen) { - if (!active_) return; + if (!active_) return; - for (uint8_t pixel_y = 0; pixel_y < height_; pixel_y++) { - for (uint8_t pixel_x = 0; pixel_x < width_; pixel_x++) { - screen->drawpixel(pixel_x + x_, pixel_y + y_, sprite_data_[frame_][(pixel_y * width_) + pixel_x]); - } - } + for (uint8_t pixel_y = 0; pixel_y < height_; pixel_y++) { + for (uint8_t pixel_x = 0; pixel_x < width_; pixel_x++) { + uint32_t color_value = sprite_data_[frame_][(pixel_y * width_) + pixel_x]; + if (color_value != 0) { + screen->drawpixel(pixel_x + x_, pixel_y + y_, color_value); + } + } + } } bool sprite_t::test_collision(const sprite_t &other_sprite) { - if (!active_) return false; + if (!active_) return false; + if (!other_sprite.is_active()) return false; - uint8_t visible_x = x_; - uint8_t visible_y = y_; - uint8_t other_visible_x = other_sprite.x_; - uint8_t other_visible_y = other_sprite.y_; + uint8_t visible_x = x_; + uint8_t visible_y = y_; + uint8_t other_visible_x = other_sprite.x_; + uint8_t other_visible_y = other_sprite.y_; - return !((visible_x + width_ - 1) < other_visible_x || (visible_y + height_ - 1) < (other_visible_y) || - x_ > (other_visible_x + other_sprite.width_ - 1) || - y_ > (other_visible_y + other_sprite.height_ - 1) ); + return !((visible_x + width_ - 1) < other_visible_x || (visible_y + height_ - 1) < (other_visible_y) || + x_ > (other_visible_x + other_sprite.width_ - 1) || + y_ > (other_visible_y + other_sprite.height_ - 1) ); } float sprite_t::get_x_position(void) { diff --git a/src/ledgames/sprite.hh b/src/ledgames/sprite.hh index 16ecb7cc..ca6df3fc 100644 --- a/src/ledgames/sprite.hh +++ b/src/ledgames/sprite.hh @@ -19,7 +19,7 @@ public: virtual void set_image(uint16_t x_offset, uint16_t y_offset, uint8_t width, uint8_t height, png_t *png_image, uint8_t anim_frame = 0); virtual void draw_onto(Screen *screen); virtual void set_active(bool active); - virtual bool is_active(void); + virtual bool is_active(void) const; virtual bool test_collision(const sprite_t &other_sprite); virtual float get_x_position(void); virtual float get_y_position(void); From ecac2d692669d14dbcc592eace83c5cb0d06b38e Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Sun, 22 Mar 2015 20:14:46 -0700 Subject: [PATCH 322/332] Invaders shoot and player takes damage. Animations. Multiplayer fixes --- src/ledgames/controls.cc | 87 ++++++++------- src/ledgames/controls.hh | 6 ++ src/ledgames/invader_sprite.cc | 31 +++++- src/ledgames/invader_sprite.hh | 3 + src/ledgames/invaders.cc | 192 ++++++++++++++++++++++++--------- src/ledgames/screen.cc | 8 ++ src/ledgames/screen.hh | 1 + 7 files changed, 239 insertions(+), 89 deletions(-) diff --git a/src/ledgames/controls.cc b/src/ledgames/controls.cc index bd5c1075..d6512c18 100644 --- a/src/ledgames/controls.cc +++ b/src/ledgames/controls.cc @@ -18,52 +18,63 @@ #define BUTTON_P2_ACTION_SEC 80 controls_t::controls_t (uint8_t player_number, bool flip_lr) { - pin_info_.resize(button_assignments_count); - if (player_number == 1) { - pin_info_[joystick_up] = new gpio_pin_t(BUTTON_P1_JOYUP); - pin_info_[joystick_down] = new gpio_pin_t(BUTTON_P1_JOYDN); - if (flip_lr) { - pin_info_[joystick_left] = new gpio_pin_t(BUTTON_P1_JOYRIGHT); - pin_info_[joystick_right] = new gpio_pin_t(BUTTON_P1_JOYLEFT); - } else { - pin_info_[joystick_left] = new gpio_pin_t(BUTTON_P1_JOYLEFT); - pin_info_[joystick_right] = new gpio_pin_t(BUTTON_P1_JOYRIGHT); - } - pin_info_[button_a] = new gpio_pin_t(BUTTON_P1_ACTION_PRI); - pin_info_[button_b] = new gpio_pin_t(BUTTON_P1_ACTION_SEC); - } else if (player_number == 2) { - pin_info_[joystick_up] = new gpio_pin_t(BUTTON_P2_JOYUP); - pin_info_[joystick_down] = new gpio_pin_t(BUTTON_P2_JOYDN); - if (flip_lr) { - pin_info_[joystick_left] = new gpio_pin_t(BUTTON_P2_JOYRIGHT); - pin_info_[joystick_right] = new gpio_pin_t(BUTTON_P2_JOYLEFT); - } else { - pin_info_[joystick_left] = new gpio_pin_t(BUTTON_P2_JOYLEFT); - pin_info_[joystick_right] = new gpio_pin_t(BUTTON_P2_JOYRIGHT); - } - pin_info_[button_a] = new gpio_pin_t(BUTTON_P2_ACTION_PRI); - pin_info_[button_b] = new gpio_pin_t(BUTTON_P2_ACTION_SEC); - } else if (player_number == 3) { - pin_info_[joystick_up] = new gpio_pin_t(BUTTON_P1_JOYUP); - pin_info_[joystick_down] = new gpio_pin_t(BUTTON_P1_JOYDN); - pin_info_[joystick_left] = new gpio_pin_t(BUTTON_P1_JOYLEFT); - pin_info_[joystick_right] = new gpio_pin_t(BUTTON_P1_JOYRIGHT); - pin_info_[button_a] = new gpio_pin_t(BUTTON_PLAYERSTART_P1); - pin_info_[button_b] = new gpio_pin_t(BUTTON_PLAYERSTART_P2); - } + player_number_ = player_number; + pin_info_.resize(button_assignments_count); + if (player_number == 1) { + pin_info_[joystick_up] = new gpio_pin_t(BUTTON_P1_JOYUP); + pin_info_[joystick_down] = new gpio_pin_t(BUTTON_P1_JOYDN); + if (flip_lr) { + pin_info_[joystick_left] = new gpio_pin_t(BUTTON_P1_JOYRIGHT); + pin_info_[joystick_right] = new gpio_pin_t(BUTTON_P1_JOYLEFT); + } else { + pin_info_[joystick_left] = new gpio_pin_t(BUTTON_P1_JOYLEFT); + pin_info_[joystick_right] = new gpio_pin_t(BUTTON_P1_JOYRIGHT); + } + pin_info_[button_a] = new gpio_pin_t(BUTTON_P1_ACTION_PRI); + pin_info_[button_b] = new gpio_pin_t(BUTTON_P1_ACTION_SEC); + } else if (player_number == 2) { + pin_info_[joystick_up] = new gpio_pin_t(BUTTON_P2_JOYUP); + pin_info_[joystick_down] = new gpio_pin_t(BUTTON_P2_JOYDN); + if (flip_lr) { + pin_info_[joystick_left] = new gpio_pin_t(BUTTON_P2_JOYRIGHT); + pin_info_[joystick_right] = new gpio_pin_t(BUTTON_P2_JOYLEFT); + } else { + pin_info_[joystick_left] = new gpio_pin_t(BUTTON_P2_JOYLEFT); + pin_info_[joystick_right] = new gpio_pin_t(BUTTON_P2_JOYRIGHT); + } + pin_info_[button_a] = new gpio_pin_t(BUTTON_P2_ACTION_PRI); + pin_info_[button_b] = new gpio_pin_t(BUTTON_P2_ACTION_SEC); + } else if (player_number == 3) { + pin_info_[joystick_up] = new gpio_pin_t(BUTTON_P1_JOYUP); + pin_info_[joystick_down] = new gpio_pin_t(BUTTON_P1_JOYDN); + pin_info_[joystick_left] = new gpio_pin_t(BUTTON_P1_JOYLEFT); + pin_info_[joystick_right] = new gpio_pin_t(BUTTON_P1_JOYRIGHT); + pin_info_[button_a] = new gpio_pin_t(BUTTON_PLAYERSTART_P1); + pin_info_[button_b] = new gpio_pin_t(BUTTON_PLAYERSTART_P2); + } } controls_t::~controls_t () { } void controls_t::refresh_status() { - button_pressed_.clear(); - for (auto pin_info : pin_info_) { - button_pressed_.push_back(pin_info->is_pressed()); - } + button_pressed_.clear(); + for (auto pin_info : pin_info_) { + button_pressed_.push_back(pin_info->is_pressed()); + } + if (player_number_ == 3) { + if (button_pressed_[button_a] && button_pressed_[button_b]) { + exit_pressed_frames_ ++; + if (exit_pressed_frames_ >= 60) { + throw new control_exit_exception(); + } + } else { + exit_pressed_frames_ = 0; + } + } } bool controls_t::is_pressed(button_assignments_t button) { - return button_pressed_[button]; + return button_pressed_[button]; } diff --git a/src/ledgames/controls.hh b/src/ledgames/controls.hh index de4df6fb..143c59d9 100644 --- a/src/ledgames/controls.hh +++ b/src/ledgames/controls.hh @@ -1,9 +1,13 @@ #include +#include #include #include #include "gpio_pin.hh" +class control_exit_exception : public std::exception{ +}; + enum button_assignments_t { joystick_up, joystick_down, @@ -25,5 +29,7 @@ public: private: std::vector pin_info_; std::vectorbutton_pressed_; + uint8_t player_number_; + uint32_t exit_pressed_frames_; }; diff --git a/src/ledgames/invader_sprite.cc b/src/ledgames/invader_sprite.cc index 4e3c561c..1ede0d8d 100644 --- a/src/ledgames/invader_sprite.cc +++ b/src/ledgames/invader_sprite.cc @@ -1,12 +1,37 @@ #include "invader_sprite.hh" invader_sprite_t::invader_sprite_t() : - sprite_t() +sprite_t(), +frames_in_anim(0) { } +void invader_sprite_t::draw_onto(Screen *screen) { + if (frame_ == 2) { + frames_in_anim++; + if (frames_in_anim > 3) { + frames_in_anim = 0; + frame_ = 3; + } + } else if (frame_ == 3) { + frames_in_anim++; + if (frames_in_anim > 3) { + frames_in_anim = 0; + set_active(false); + } + } + sprite_t::draw_onto(screen); +} + void invader_sprite_t::move_sprite(void) { - sprite_t::move_sprite(); + sprite_t::move_sprite(); - frame_ = (int)x_ & 0x01; + if (frame_ < 2) { + frame_ = (int)x_ & 0x01; + } } + +void invader_sprite_t::destroy_sprite(void) { + frame_ = 2; + frames_in_anim = 0; +} \ No newline at end of file diff --git a/src/ledgames/invader_sprite.hh b/src/ledgames/invader_sprite.hh index 0d4c2edb..0217319d 100644 --- a/src/ledgames/invader_sprite.hh +++ b/src/ledgames/invader_sprite.hh @@ -9,7 +9,10 @@ class invader_sprite_t : public sprite_t { public: invader_sprite_t(); + virtual void draw_onto(Screen *screen) override; virtual void move_sprite(void) override; + virtual void destroy_sprite(void); private: + uint32_t frames_in_anim; }; diff --git a/src/ledgames/invaders.cc b/src/ledgames/invaders.cc index f903d068..51a15a5b 100644 --- a/src/ledgames/invaders.cc +++ b/src/ledgames/invaders.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,8 @@ static int current_player; static sprite_t ship_sprite; static sprite_t ship_missile_sprite; static std::vector invader_sprites[2]; +static sprite_t invader_missile_sprite; +static int32_t lowest_invaders[6]; static Mix_Chunk *startup_bong; static Mix_Chunk *wall_blip; @@ -44,38 +47,61 @@ enum class game_state_t { Attract, Serving, Playing, - Resetting, + Touchdown, + NewShip, }; static game_state_t game_state; static bool invaders_right; static bool shot_fired; +static float invader_speed; +static uint32_t frames_in_state; +static uint32_t frames_till_shot; + +static std::default_random_engine generator; +static std::uniform_int_distribution invader_distribution(0,5); static void reset_invaders(int for_player) { invader_sprites[for_player].clear(); invaders_right = true; + invader_speed = 0.05f; for (int row_counter = 0; row_counter < 4; row_counter++) { for (int column_counter = 0; column_counter < 6; column_counter++) { invader_sprite_t invader_sprite; invader_sprite.set_active(true); - invader_sprite.set_speed(0.05, 0.0); + invader_sprite.set_speed(invader_speed, 0.0); invader_sprite.set_position(column_counter * 10, 10 + (row_counter * 8)); invader_sprite.set_image(row_counter * 28,0,7,7,&sprite_sheet, 0); invader_sprite.set_image((row_counter * 28) + 7,0,7,7,&sprite_sheet, 1); + invader_sprite.set_image((row_counter * 28) + 14,0,7,7,&sprite_sheet, 2); + invader_sprite.set_image((row_counter * 28) + 21,0,7,7,&sprite_sheet, 3); invader_sprites[for_player].push_back(invader_sprite); } } + lowest_invaders[0] = 18; + lowest_invaders[1] = 19; + lowest_invaders[2] = 20; + lowest_invaders[3] = 21; + lowest_invaders[4] = 22; + lowest_invaders[5] = 23; } static bool reset_round(void) { - current_player = (current_player + 1) % number_players; - if (player_lives[current_player] == 0) { + uint32_t next_player = (current_player + 1) % number_players; + if (player_lives[next_player] > 0) { + current_player = next_player; + } + if ((player_lives[0] == 0) && (player_lives[1] == 0)) { return false; } - shot_fired = false; + shot_fired = false; ship_missile_sprite.set_active(false); - game_state = game_state_t::Serving; + invader_missile_sprite.set_active(false); + ship_sprite.set_active(true); + game_state = game_state_t::Playing; + + frames_till_shot = 60; return true; } @@ -92,15 +118,17 @@ static void reset_game(int with_number_players) { player_score[1] = 0; player_lives[0] = 3; - player_lives[1] = 3; + if (with_number_players == 2) { + player_lives[1] = 3; + } else { + player_lives[1] = 0; + } number_players = with_number_players; current_player = 1; reset_round(); - game_state = game_state_t::Playing; - printf("\n\n\nGAME START\n\n\n"); } @@ -124,72 +152,94 @@ void render_game(Screen *screen) { ship_sprite.draw_onto(screen); ship_missile_sprite.draw_onto(screen); + invader_missile_sprite.draw_onto(screen); ship_missile_sprite.move_sprite(); + invader_missile_sprite.move_sprite(); if (ship_missile_sprite.get_y_position() < 0.0f) { ship_missile_sprite.set_active(false); } bool change_direction = false; - for (auto &invader_sprite : invader_sprites[current_player]) { - invader_sprite.move_sprite(); - if (invader_sprite.is_active()) { - if ((invaders_right && (invader_sprite.get_x_position() > 57)) || (!invaders_right && (invader_sprite.get_x_position() < 1))) { - change_direction = true; + bool invader_touchdown = false; + if ((game_state == game_state_t::Attract) || (game_state == game_state_t::Playing)) { + for (auto &invader_sprite : invader_sprites[current_player]) { + invader_sprite.move_sprite(); + if (invader_sprite.is_active()) { + if ((invaders_right && (invader_sprite.get_x_position() > 57.5f)) || (!invaders_right && (invader_sprite.get_x_position() < 0.5f))) { + change_direction = true; + } + if (invader_sprite.get_y_position() > 47) { + invader_touchdown = true; + } } } } + + if (invader_touchdown) { + game_state = game_state_t::Touchdown; + frames_in_state = 0; + ship_sprite.set_active(false); + player_lives[current_player] = 0; + for (auto &invader_sprite : invader_sprites[current_player]) { + invader_sprite.set_position(invader_sprite.get_x_position(), invader_sprite.get_y_position()+8); + } + } if (change_direction) { - if (invaders_right) { - invaders_right = false; - for (auto &invader_sprite : invader_sprites[current_player]) { - invader_sprite.set_speed(-0.05, 0); - if (game_state == game_state_t::Playing) { - invader_sprite.set_position(invader_sprite.get_x_position(), invader_sprite.get_y_position()+1); - } - } - } else { - invaders_right = true; - for (auto &invader_sprite : invader_sprites[current_player]) { - invader_sprite.set_speed(0.05, 0); - if (game_state == game_state_t::Playing) { - invader_sprite.set_position(invader_sprite.get_x_position(), invader_sprite.get_y_position()+1); - } - } - } + invaders_right = !invaders_right; } for (auto &invader_sprite : invader_sprites[current_player]) { invader_sprite.draw_onto(screen); } + + frames_till_shot--; + if (frames_till_shot == 0) { + invader_missile_sprite.set_active(true); + int32_t invader_column = -1; + do { + invader_column = lowest_invaders[invader_distribution(generator)]; + } while (invader_column < 0); + sprite_t invader_sprite = invader_sprites[current_player][invader_column]; + invader_missile_sprite.set_position(invader_sprite.get_x_position(), invader_sprite.get_y_position()); + invader_missile_sprite.set_image(196,0,7,7,&sprite_sheet); + invader_missile_sprite.set_speed(0.0f, 2.0f); + frames_till_shot=30; + } if (game_state == game_state_t::Attract) { screen->draw_text(32,2,0x00808080,"GAME OVER!"); screen->draw_text(40,2,0x00808080,"PRESS PLYR"); screen->draw_text(48,2,0x00808080," 1 OR 2 "); - } else { + } else if ((game_state == game_state_t::Playing) || (game_state == game_state_t::NewShip)) { char score[7]; char lives[1]; sprintf(score, "%06d", player_score[current_player]); screen->draw_text(0,2,0x00808080,score); sprintf(lives, "%01d", player_lives[current_player]); screen->draw_text(0,48,0x00808080,lives); - + } else if (game_state == game_state_t::Touchdown) { + char score[7]; + char lives[1]; + sprintf(score, "%06d", player_score[current_player]); + screen->draw_text(0,2,0x00808080,score); + sprintf(lives, "%01d", player_lives[current_player]); + screen->draw_text(0,48,0x00808080,lives); + screen->draw_text(32,2,0x00808080,"GAME OVER!"); } screen->draw_end(); player_controls[current_player]->refresh_status(); + player_controls[2]->refresh_status(); if (game_state == game_state_t::Attract) { - player_controls[2]->refresh_status(); if (player_controls[2]->is_pressed(button_a)) { reset_game(1); } else if (player_controls[2]->is_pressed(button_b)) { reset_game(2); } - return; - } else { + } else if (game_state == game_state_t::Playing) { if (player_controls[current_player]->is_pressed(joystick_left)) { if (ship_sprite.x_ > 0) { ship_sprite.x_--; @@ -214,19 +264,62 @@ void render_game(Screen *screen) { } } - if (game_state == game_state_t::Playing) { - bool active_invaders = false; + if ((game_state == game_state_t::Attract) || (game_state == game_state_t::Playing)) { + int active_invaders = 0; + int32_t invader_idx = 0; for (auto &invader_sprite : invader_sprites[current_player]) { - active_invaders |= invader_sprite.is_active(); - if (invader_sprite.test_collision(ship_missile_sprite)) { - invader_sprite.set_active(false); + active_invaders += (invader_sprite.is_active() ? 1 : 0); + if (invader_sprite.test_collision(ship_missile_sprite)) { + invader_sprite.destroy_sprite(); ship_missile_sprite.set_active(false); + for (uint8_t idx_ctr = 0; idx_ctr < 6; idx_ctr++) { + if (lowest_invaders[idx_ctr] == invader_idx) { + // Player just shot the lowest invader in a column. + lowest_invaders[idx_ctr] -= 6; + } + } } + invader_idx++; } - if (!active_invaders) { + invader_speed = 0.05f + ((24 - active_invaders) * 0.08f); + if (active_invaders == 0) { reset_invaders(current_player); } + + if (ship_sprite.test_collision(invader_missile_sprite)) { + game_state = game_state_t::NewShip; + ship_sprite.set_active(false); + player_lives[current_player]--; + frames_in_state = 0; + } } + + for (auto &invader_sprite : invader_sprites[current_player]) { + invader_sprite.set_speed(invader_speed * (invaders_right ? 1 : -1), 0); + if (change_direction) { + if (game_state == game_state_t::Playing) { + invader_sprite.set_position(invader_sprite.get_x_position(), invader_sprite.get_y_position()+1); + } + } + } + + if (game_state == game_state_t::Touchdown) { + frames_in_state++; + if (frames_in_state == 120) { + if (!reset_round()) { + init_attract(); + } + } + } + + if (game_state == game_state_t::NewShip) { + frames_in_state++; + if (frames_in_state == 120) { + if (!reset_round()) { + init_attract(); + } + } + } } static void init_sdl(void) { @@ -300,15 +393,18 @@ const char ** argv block_blip[1] = Mix_LoadWAV("/root/blip4.wav"); block_blip[2] = Mix_LoadWAV("/root/blip5.wav"); - while (1) - { - render_game(screen); + try { + while (1) + { + render_game(screen); - usleep(20000); + usleep(20000); + } + } + catch (control_exit_exception* ex) { + delete screen; } - - ledscape_close(leds); return EXIT_SUCCESS; } diff --git a/src/ledgames/screen.cc b/src/ledgames/screen.cc index 5792a5c3..8996c1c6 100644 --- a/src/ledgames/screen.cc +++ b/src/ledgames/screen.cc @@ -17,6 +17,14 @@ flip_(false) sleep(1); } +Screen::~Screen() +{ + set_background_color(0x00000000); + draw_start(); + draw_end(); + sleep(1); +} + void Screen::drawpixel(uint32_t x, uint32_t y, uint32_t color) { if ((x > 63) || (y > 63)) { return; diff --git a/src/ledgames/screen.hh b/src/ledgames/screen.hh index 69e4bc4e..1c42bce9 100644 --- a/src/ledgames/screen.hh +++ b/src/ledgames/screen.hh @@ -7,6 +7,7 @@ class Screen { public: Screen(ledscape_t * const leds, uint32_t *pixels); + ~Screen(); void drawpixel(uint32_t x, uint32_t y, uint32_t color); void set_background_color(uint32_t color); From 32f86dd948939861429d02ca98ae297dae1dbf0a Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Sat, 28 Mar 2015 21:15:23 -0700 Subject: [PATCH 323/332] Support blue/green software flip Move the player 1 right direction to a new pin --- src/ledgames/controls.cc | 2 +- src/ledgames/invaders.cc | 2 +- src/ledscape/ledscape.c | 5 +++++ src/ledscape/ledscape.h | 2 ++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ledgames/controls.cc b/src/ledgames/controls.cc index d6512c18..dc0d7504 100644 --- a/src/ledgames/controls.cc +++ b/src/ledgames/controls.cc @@ -7,7 +7,7 @@ #define BUTTON_P1_JOYUP 79 #define BUTTON_P1_JOYDN 73 #define BUTTON_P1_JOYLEFT 74 -#define BUTTON_P1_JOYRIGHT 75 +#define BUTTON_P1_JOYRIGHT 89 #define BUTTON_P1_ACTION_PRI 76 #define BUTTON_P1_ACTION_SEC 77 #define BUTTON_P2_JOYUP 8 diff --git a/src/ledgames/invaders.cc b/src/ledgames/invaders.cc index 51a15a5b..1d912820 100644 --- a/src/ledgames/invaders.cc +++ b/src/ledgames/invaders.cc @@ -281,7 +281,7 @@ void render_game(Screen *screen) { } invader_idx++; } - invader_speed = 0.05f + ((24 - active_invaders) * 0.08f); + invader_speed = 0.05f + ((24 - active_invaders) * 0.07f); if (active_invaders == 0) { reset_invaders(current_player); } diff --git a/src/ledscape/ledscape.c b/src/ledscape/ledscape.c index 02e6e31c..90fec067 100644 --- a/src/ledscape/ledscape.c +++ b/src/ledscape/ledscape.c @@ -288,8 +288,13 @@ ledscape_matrix_panel_copy( uint8_t * const pix = &out[x*row_stride + (y/(config->panel_height/2))*3 + (y%(config->panel_height/2))*row_len]; pix[0] = (col >> 16) & 0xFF; // red +#if LEDSCAPE_MATRIX_GB_INVERT + pix[1] = (col >> 0) & 0xFF; // green + pix[2] = (col >> 8) & 0xFF; // blue +#else pix[1] = (col >> 8) & 0xFF; // green pix[2] = (col >> 0) & 0xFF; // blue +#endif //printf("%d,%d => %p %p %08x\n", x, y, pix, col_ptr, col); } } diff --git a/src/ledscape/ledscape.h b/src/ledscape/ledscape.h index 71cf7198..843e5f55 100644 --- a/src/ledscape/ledscape.h +++ b/src/ledscape/ledscape.h @@ -30,6 +30,8 @@ typedef struct { #define LEDSCAPE_MATRIX_OUTPUTS 1 // number of outputs on the cape #define LEDSCAPE_MATRIX_PANELS 4 // number of panels chained per output +#define LEDSCAPE_MATRIX_GB_INVERT 1 // Flips green and blue colors, as this is different panel to panel + typedef struct { int type; int width; From f2d66bf5eb86dbf92420c6f5eca5059be3eb2670 Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Sun, 29 Mar 2015 04:19:09 +0000 Subject: [PATCH 324/332] Add resources for games --- src/ledgames/rsrc/Invaders.png | Bin 0 -> 2087 bytes src/ledgames/rsrc/blip2.wav | Bin 0 -> 89232 bytes src/ledgames/rsrc/blip3.wav | Bin 0 -> 89216 bytes src/ledgames/rsrc/blip4.wav | Bin 0 -> 89252 bytes src/ledgames/rsrc/blip5.wav | Bin 0 -> 89300 bytes src/ledgames/rsrc/startup.wav | Bin 0 -> 89148 bytes 6 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/ledgames/rsrc/Invaders.png create mode 100644 src/ledgames/rsrc/blip2.wav create mode 100644 src/ledgames/rsrc/blip3.wav create mode 100644 src/ledgames/rsrc/blip4.wav create mode 100644 src/ledgames/rsrc/blip5.wav create mode 100644 src/ledgames/rsrc/startup.wav diff --git a/src/ledgames/rsrc/Invaders.png b/src/ledgames/rsrc/Invaders.png new file mode 100644 index 0000000000000000000000000000000000000000..7bfbd34965fc406232482067f5919ad06d65e3ef GIT binary patch literal 2087 zcmV+?2-x?DP)4Tx062|}Ro!pfR1`mnZ(O7nKcKOW4i$^9Ra0BJ8yc;~21%2p=|UR0&DbiW z$#rfTQ`a`O(`{9s_5yDV_yd5l2Of}kLK+Oj_Ok5(v`JGz71bo9J#^YYXp{DWs&KBa zQ@dTpxRI}aIp=pi@6k0t$5)!;m`NF6-tt{FpOKHBn3g+MAqmexC-gw4rh87hTrL7G z#)U`L!(So6-Zux@>;H3gR;i~0B%VTSS3P|m@o9jRsXML@Al^p#@G0Lx-0?i(9WEw_ zSYddU<1E8793KxjQ|c&UmW!mTC>k>?{om1c9S zUx<6_jj_!T&^M{wWM#>IBbOSf*xP<^F{$j$aOQ5Y{cT zROCL1M7^NKKL z&(yA}mSw#iM0^;IB{ZO5!wl{^Sg-*ysE~&Yz8!E;Qv(A`lu*=Clo*MpVGd>OdF6n^ zam1Jntk;<}MrqIC5$=Q>n{*R}?8oOIDUw5En2dl--Xw34!z7E+5pr-OgyQ-soSab)C%saskMla`aQLVzg0+MZf20tJU&K{hZoBrUc+U4e9&3o zw|KmGEe4#xz17wBu{f`SS_4i66?j31EjY7n{zGfhONK~c+td!TS#B}JoR}5UAd7p& z5phTyXSkK0xCeD3xaYP^o&J~#Xp9xFb0C;HHml5fA<%h1eR|qw7wxF+oNL9T1Aits?sKNIwvGaN)^WO$I^cUV)HzL_| z1K?{9p!>B*)`xfEv!4N6IG{J&h49W#Bz^(#YWw%`e_a{8n{G9m5AeR~_yl0%<7V@p zNklX+6n;YxiG~5=;KC?`aYJ0F z>^*=d@B$_#E|BQfg}897NTP{}7w`lgz`eRLtcHNbg$}_PfEHr)vY?~_m^8Mvt{qkZx^xCAf zh2l^)8xtiz1FN@-IWKn_+rb77L`(yxUi9#DP3f_RxzcU*-JidM_ubZx+?qchFgI0N6_44R z4qvV|Twn?{y?y*|bKZV(=;wBJ2O)a);V7*0U}@a<51$vM0C8Zr#~^bY6zB+3m1YCN zn0u_p+~L%uEcP!zl8xqfnb}AjLGCN*oaDi)k8^?X@>D zw{j=g8E<}kEekj91`QZNZ z{J881lhdpp>%;L@OWA1gS(J$tlwVH&!zR+Z+yBNe#aN#J`_<+*3< zf>K;5t_|JFr!;&X|Jl1e|97e%ygPkDuN-Ueq^b*9Y2JDLiBux%28qK_^-$}H1w&_< zM~{lNIUL|@wH~|S;RlaudBs+PhilBk0Z?xYD;MK=?O1PT)RWruqiC_`+4-2K4#(j@ zpkmbqs@?7Tz1fl30=NI09j}{TIexxkgaVay+uJ}{y)GVep($M!t7w0@15W)~hehjn z;LX+4uXUKMo8_LomSIJZTABXZY7l0S2*SPQjAwSRMqwS4__{19`bi0aO|tw{{_~N2b!*j{-kzpfRc%?bXa8Z@l2a5#Qw&vOCq*US$50%Voa)|X zSeNebXa48)Ki|Ord;|aU4gCM`4QzF`I*Z&z?ksPXH;fs^%%*44)2M0GjBrLcCzun= z_GkNZygA-@7vPL{#@J)*Kg2)8ebPSZxO`l`s$5mx$ZzDA(o5-y_(Z%T+!6lf|K^Wy zN4VYWZnmUf(k~Dc2x^73!p2l%suSIb9>NS^Cb5&)joe1=Fn^f8EL;{|iZ8`G#vNn4 zK3?yw_14PhW%LF{1EZVS%^YWqv$osY?SGtqoagRy_XG2Rc|*UUk5WgemEp>8OfV*B z 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 literal 0 HcmV?d00001 diff --git a/src/ledgames/rsrc/blip3.wav b/src/ledgames/rsrc/blip3.wav new file mode 100644 index 0000000000000000000000000000000000000000..e10fa081f485f94705c46e12ac73fe6f2a9ffea6 GIT binary patch literal 89216 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 P-CkYSpS|Dj?BDwbR;#L9 literal 0 HcmV?d00001 diff --git a/src/ledgames/rsrc/blip5.wav b/src/ledgames/rsrc/blip5.wav new file mode 100644 index 0000000000000000000000000000000000000000..71c4b1f0a76f85ffa3f957e053aacfae77e89547 GIT binary patch literal 89300 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�?py9#aMAtS`?qh(jQ8^R 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 literal 0 HcmV?d00001 From 26f4edff4eface47950ef3c3b1436c68c01c4a60 Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Sat, 28 Mar 2015 21:24:21 -0700 Subject: [PATCH 325/332] Automatically place resources --- Makefile | 1 + src/ledgames/rsrc/Makefile | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 src/ledgames/rsrc/Makefile diff --git a/Makefile b/Makefile index 7ef3c475..3a57bfd2 100755 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ SUBDIR-y += src/mta SUBDIR-y += src/net SUBDIR-y += src/script SUBDIR-y += src/ledgames +SUBDIR-y += src/ledgames/rsrc all: for dir in $(SUBDIR-y); do \ diff --git a/src/ledgames/rsrc/Makefile b/src/ledgames/rsrc/Makefile new file mode 100644 index 00000000..a5a25539 --- /dev/null +++ b/src/ledgames/rsrc/Makefile @@ -0,0 +1,13 @@ +BINDIR = ../../../bin/ + +FILES = blip2.wav \ + blip3.wav \ + blip4.wav \ + blip5.wav \ + startup.wav \ + Invaders.png + +all: copy + +copy: + cp -f $(FILES) $(BINDIR) From 635f00f35cabe8e270200a879c7a1f6412e4801c Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Sat, 28 Mar 2015 22:20:01 -0700 Subject: [PATCH 326/332] Animated ship and ship destruction --- src/ledgames/Makefile | 2 +- src/ledgames/invaders.cc | 19 +++++++++------ src/ledgames/ship_sprite.cc | 48 +++++++++++++++++++++++++++++++++++++ src/ledgames/ship_sprite.hh | 18 ++++++++++++++ 4 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 src/ledgames/ship_sprite.cc create mode 100644 src/ledgames/ship_sprite.hh diff --git a/src/ledgames/Makefile b/src/ledgames/Makefile index 68c96fbb..3a732ab6 100755 --- a/src/ledgames/Makefile +++ b/src/ledgames/Makefile @@ -14,7 +14,7 @@ breakout.srcs += bricks.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_spri black.srcs += black.c white.srcs += white.c pong.srcs += pong.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_sprite.cc -invaders.srcs += invaders.cc gpio_pin.cc controls.cc screen.cc sprite.cc invader_sprite.cc png.cc +invaders.srcs += invaders.cc gpio_pin.cc controls.cc screen.cc sprite.cc invader_sprite.cc ship_sprite.cc png.cc include ../../Makefile.common diff --git a/src/ledgames/invaders.cc b/src/ledgames/invaders.cc index 1d912820..690ad8a5 100644 --- a/src/ledgames/invaders.cc +++ b/src/ledgames/invaders.cc @@ -22,6 +22,7 @@ #include "screen.hh" #include "sprite.hh" #include "invader_sprite.hh" +#include "ship_sprite.hh" #include "png.hh" static controls_t *player_controls[3]; @@ -30,7 +31,7 @@ static int player_lives[2]; static int number_players; static int current_player; -static sprite_t ship_sprite; +static ship_sprite_t ship_sprite; static sprite_t ship_missile_sprite; static std::vector invader_sprites[2]; static sprite_t invader_missile_sprite; @@ -60,6 +61,7 @@ static uint32_t frames_till_shot; static std::default_random_engine generator; static std::uniform_int_distribution invader_distribution(0,5); +static std::uniform_int_distribution shot_distribution(45,75); static void reset_invaders(int for_player) { invader_sprites[for_player].clear(); @@ -109,7 +111,10 @@ static bool reset_round(void) { static void reset_game(int with_number_players) { ship_sprite.set_active(true); ship_sprite.set_position(28, 55); - ship_sprite.set_image(168,0,7,7,&sprite_sheet); + ship_sprite.set_image(168,0,7,7,&sprite_sheet, 0); + ship_sprite.set_image(168+7,0,7,7,&sprite_sheet, 1); + ship_sprite.set_image(168+14,0,7,7,&sprite_sheet, 2); + ship_sprite.set_image(168+28,0,7,7,&sprite_sheet, 3); reset_invaders(0); reset_invaders(1); @@ -203,8 +208,8 @@ void render_game(Screen *screen) { sprite_t invader_sprite = invader_sprites[current_player][invader_column]; invader_missile_sprite.set_position(invader_sprite.get_x_position(), invader_sprite.get_y_position()); invader_missile_sprite.set_image(196,0,7,7,&sprite_sheet); - invader_missile_sprite.set_speed(0.0f, 2.0f); - frames_till_shot=30; + invader_missile_sprite.set_speed(0.0f, 1.0f); + frames_till_shot=shot_distribution(generator); } if (game_state == game_state_t::Attract) { @@ -288,7 +293,7 @@ void render_game(Screen *screen) { if (ship_sprite.test_collision(invader_missile_sprite)) { game_state = game_state_t::NewShip; - ship_sprite.set_active(false); + ship_sprite.destroy_sprite(); player_lives[current_player]--; frames_in_state = 0; } @@ -338,7 +343,7 @@ static void init_sdl(void) { exit(1); } - startup_bong = Mix_LoadWAV("/root/startup.wav"); + startup_bong = Mix_LoadWAV("bin/startup.wav"); if (startup_bong == NULL) { fprintf(stderr, "Unable to load startup.wav: %s\n", Mix_GetError()); exit(1); @@ -372,7 +377,7 @@ const char ** argv ledscape_t * const leds = ledscape_init(config, 0); - sprite_sheet.read_file("/root/Invaders.png"); + sprite_sheet.read_file("bin/Invaders.png"); player_controls[0] = new controls_t(1); player_controls[1] = new controls_t(2); diff --git a/src/ledgames/ship_sprite.cc b/src/ledgames/ship_sprite.cc new file mode 100644 index 00000000..1a252eee --- /dev/null +++ b/src/ledgames/ship_sprite.cc @@ -0,0 +1,48 @@ +#include "ship_sprite.hh" + +ship_sprite_t::ship_sprite_t() : +sprite_t(), +frames_in_anim(0) +{ +} + +void ship_sprite_t::draw_onto(Screen *screen) { + if (frame_ == 0) { + frames_in_anim++; + if (frames_in_anim > 3) { + frames_in_anim = 0; + frame_ = 1; + } + } else if (frame_ == 1) { + frames_in_anim++; + if (frames_in_anim > 3) { + frames_in_anim = 0; + frame_ = 0; + } + } else if (frame_ == 2) { + frames_in_anim++; + if (frames_in_anim > 3) { + frames_in_anim = 0; + frame_ = 3; + } + } else if (frame_ == 3) { + frames_in_anim++; + if (frames_in_anim > 3) { + frames_in_anim = 0; + explode_anims++; + if (explode_anims > 10) { + set_active(false); + frame_ = 0; + } else { + frame_ = 2; + } + } + } + sprite_t::draw_onto(screen); +} + +void ship_sprite_t::destroy_sprite(void) { + frame_ = 2; + frames_in_anim = 0; + explode_anims = 0; +} \ No newline at end of file diff --git a/src/ledgames/ship_sprite.hh b/src/ledgames/ship_sprite.hh new file mode 100644 index 00000000..7a5ae358 --- /dev/null +++ b/src/ledgames/ship_sprite.hh @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#include "sprite.hh" + +class ship_sprite_t : public sprite_t { +public: + ship_sprite_t(); + + virtual void draw_onto(Screen *screen) override; + virtual void destroy_sprite(void); + +private: + uint32_t frames_in_anim; + uint32_t explode_anims; +}; From c7700c0eba51bff1fb303d04bc124caa8e7727d6 Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Sun, 29 Mar 2015 05:42:24 +0000 Subject: [PATCH 327/332] Remove more code not used for the games --- Makefile | 4 - src/demos/Makefile | 19 - src/demos/companion-cube.raw | Bin 4096 -> 0 bytes src/demos/cube-image.c | 68 -- src/demos/cube-life.c | 504 ------------ src/demos/fire.c | 253 ------- src/demos/identify.c | 98 --- src/demos/life.c | 267 ------- src/demos/lightcycles.c | 379 ---------- src/demos/matrix-test.c | 269 ------- src/ledgames/rsrc/Makefile | 5 + src/mta/Makefile | 12 - src/mta/mta-font.c | 1304 -------------------------------- src/mta/mta-sign.c | 158 ---- src/net/Makefile | 15 - src/net/matrix-tcp-rx.c | 351 --------- src/net/matrix-udp-rx.c | 275 ------- src/net/opc-rx.c | 158 ---- src/perlin/Makefile | 28 - src/perlin/gammalut.h | 46 -- src/perlin/globals.h | 30 - src/perlin/knobs/knobs.ino | 32 - src/perlin/pattern.cpp | 109 --- src/perlin/pattern.h | 59 -- src/perlin/perlin-ledscape.cpp | 188 ----- src/perlin/pf2.cpp | 339 --------- src/perlin/pf2.h | 135 ---- 27 files changed, 5 insertions(+), 5100 deletions(-) delete mode 100755 src/demos/Makefile delete mode 100644 src/demos/companion-cube.raw delete mode 100644 src/demos/cube-image.c delete mode 100644 src/demos/cube-life.c delete mode 100644 src/demos/fire.c delete mode 100644 src/demos/identify.c delete mode 100644 src/demos/life.c delete mode 100644 src/demos/lightcycles.c delete mode 100644 src/demos/matrix-test.c delete mode 100755 src/mta/Makefile delete mode 100644 src/mta/mta-font.c delete mode 100644 src/mta/mta-sign.c delete mode 100755 src/net/Makefile delete mode 100644 src/net/matrix-tcp-rx.c delete mode 100644 src/net/matrix-udp-rx.c delete mode 100644 src/net/opc-rx.c delete mode 100644 src/perlin/Makefile delete mode 100644 src/perlin/gammalut.h delete mode 100644 src/perlin/globals.h delete mode 100644 src/perlin/knobs/knobs.ino delete mode 100644 src/perlin/pattern.cpp delete mode 100644 src/perlin/pattern.h delete mode 100644 src/perlin/perlin-ledscape.cpp delete mode 100644 src/perlin/pf2.cpp delete mode 100644 src/perlin/pf2.h diff --git a/Makefile b/Makefile index 3a57bfd2..27d1dc0e 100755 --- a/Makefile +++ b/Makefile @@ -5,10 +5,6 @@ SUBDIR-y += dts SUBDIR-y += src/ledscape -SUBDIR-y += src/demos -SUBDIR-y += src/perlin -SUBDIR-y += src/mta -SUBDIR-y += src/net SUBDIR-y += src/script SUBDIR-y += src/ledgames SUBDIR-y += src/ledgames/rsrc diff --git a/src/demos/Makefile b/src/demos/Makefile deleted file mode 100755 index 5d23ac93..00000000 --- a/src/demos/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -######### -# -# Build the various demos -# -# -BIN-y += fire -BIN-y += life -BIN-y += cube-life -BIN-y += matrix-test -BIN-y += identify - -fire.srcs += fire.c -life.srcs += life.c -identify.srcs += identify.c -cube-life.srcs += cube-life.c -matrix-test.srcs += matrix-test.c - -include ../../Makefile.common - diff --git a/src/demos/companion-cube.raw b/src/demos/companion-cube.raw deleted file mode 100644 index 1adcd80e54986d08ee61169cc2f5b9752e55807d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmb7Hc~I0>5}t#>VVD^%jRr4ZxQUf0o4^21}|of4rJEzvF$~Uw41qzel$! z@$go~OV@+;ay;(PlIoN|g+k&K*Q=mmUw=EAjYFl~@mN9~b}md7W-BW=KmVk|;M?W1yU|)1i>(`{Ln4tNV5TRQ zMoz$(@q@5nv^U=Oo{mx8Hi!!L#-gyXkjfmXFk)XnpN8W(OOcZrjNm!$P*L1vPwN?%} z?I+v0BIFgqx0Jv}YX+@WCZ184OJHs;MZgRf zu%CQhgk4)^L+5BMe6zHa60Q`Mgu_ci|D`Gk-n1qBLB5dCUTZ1)`}lo!1Ico%f!=wzIQ<+)M&1^2vxRu*nW9;y|L5V1mXK z^R3B$ii?#--p59Mmfz(w>}-`tO$ox0gJC$|oIc_>xlFD&^g(N z_n1#3w&0$8l2aVy6z2g}68JlLA=>qAC~b*vg$z9Z5|5KB2ct1 z5{GsMV{`m8`1?6PsgzOdIZytufzRUFnLb5FIT?wQgd^!uVzEzry(WJd{=R7@Mvl-3{!DG) zJ?HSIbyLw;vK-$xe1?n7iAdf!4O>2$id|dhVEh<+@r?03=G?-DBc%E zD-xyq7NYb(6iN@$+P@GbbiF7o68fBF$l4tOCr2wNs1}W9@h{h=r<)yid@&ozpH3r9 znFVKZ z7rV9wKutNRqS{bDs~e*~j3uYV*sTq_aHe59CXFA~hchEz6TIz73zncTJq#_eiMT#3 z3pf07aBf91O33%Z>`*jpT8p29(r}%wpI(!I{DYxn?=sRsFA;a`vs~b~ax5K3TB5on z0q0JBgQxfENYCprf6gfJENctbH`kaSu>A!xCqlMu}-4aNA%EWmZ`sFhfR10r-*`nvyJm6sy zX+b5rZsfzwb08#yCwrzXT;Bt%fc^GzlO3!|w3Z zgE_fP_(xNh;27b@`1&JIGZ~?DCTn%bpeYElnSj=ct%P4E=7-Mfd2n*IfrN7XIZu=) zDq96Ib}Yb=oCxTXV$khUN9P;3e$fWzpMAeKvI#9Qn^8zLQI@_K&Th7S&!xDUQ9ZQQ zZz0{Q7x70|1!n)n9Wv4=YwlyzOIXj%sYVh>*Q&FYBLDCLG=KC7y2-yD$}`3@+Q56x zzdNs0p*e0N3bH~_p0OAQw#|pFwE}9D6k4@hoT(&j^l-Mqe}CdRsz&rfbd_W7J06gb zerqX5x&FES_`koO6Y1Jg5eKgMn&cS#>Qh9qXe1j9dC2>#Gcr)IbGgukqP>x*rTTk6 zdTgKiV=ZM(8b$fve&rD1>*4G?7>ZlnYs5LU%5P z?-D+<-&}{xcM0iFNm`W9=Iqo^3>j=8-Z$#GL4OQ=dDt*3xDa;eTo;4|x?shk(Qp`{ z?W6y~UgB#cUC&Al5gO0F6(5X1L2fX94Bd^Z{uwC9S%4DKV!p?Hp*(9bCXO2_^uwsX zjLp8-4^d(H!qJGB=SJAhXscO=)~dgurD7F6T;*fni+bjB4W>A74`)5+9>Kg;WJaSj zo$NReNqHWP;`9iVA6hK#vELKN*+WWNV#MaNj6HBA#pKknl{kI;LxIgR@{^7lv{ZkJ z;{Bm`{k6fO2XWsvwSnWN)|eqI$P>Gh14vsIqC9&s%5sQr!alHl9>v>RaLzr$6r1<# zgS+cM6zmP5xiXIOuG%o4^Ndfk56_#G*-L2FoI|)~qVK(UhKll-`?%UtPP%4+DAJbI zRNp#xmB@3x#~k;0k8+NCkV+-T_RX^>kCx%iwE}@@oQcKUNm}^bi6oR!Z`-)mPuR=7 z*OUkDW86zLRG+M=V=Y_}sHXXg{8iJ8%J+=9#@rd~pjnab$FF{i;ueWZXLj_Nzf9+T zo=@wFW5tZ}S==bIpL3~~$mo2-{7dsE+eP(ljF%zaQjyCFnuFJTFiH4zrZ$1} z{^j2Sh8grY?*DcSbtSR%d<4y{bMeNgR|Mw+h*!>Gwu3c-=U?s>Ap;HbFYA@jM&^xU zG1T4?i68l)GHW5etKa-=_U-?hjBQ{JcsBf@F$on}(NtGqShZ{{UL9f~;>a3duAn?1 zdwgsdpZKS}(wurL)hfr@*47Lmb3I7AgHTtv0$0D^BRDtZy1%_KCweI#ZvQJ6-&V%c zY`78$>->aIJUe)}T0^0cP#@D#FQJ+x{@rw1%5UnmW` -#include -#include -#include -#include -#include -#include -#include -#include "ledscape.h" - - -int -main(void) -{ - const int width = 128; - const int height = 128; - ledscape_t * const leds = ledscape_init(width, height); - printf("init done\n"); - time_t last_time = time(NULL); - unsigned last_i = 0; - - uint32_t bits[32][32]; - memset(bits, 0, sizeof(bits)); - ssize_t rc = read(0, bits, sizeof(bits)); - if (rc != sizeof(bits)) - { - fprintf(stderr, "only read %zu bytes\n", rc); - return -1; - } - - uint32_t * const p = calloc(4, width*height); - - for (int x = 0 ; x < 32 ; x++) - { - for (int y = 0 ; y < 32 ; y++) - { - uint32_t c = bits[x][y]; - uint32_t r = (c >> 16) & 0xFF; - uint32_t g = (c >> 8) & 0xFF; - uint32_t b = (c >> 0) & 0xFF; - r = r; - g = g; - b = b; - c = (r << 0) | (g << 8) | (b << 16); - printf("%d,%d %08x %d,%d,%d\n", x, y, c, r, g, b); - p[width*((31-y)+0) + x] = c; - p[width*((31-y)+0) + x + 32] = c; - p[width*((31-x)+32) + (31-y)] = c; - p[width*((31-x)+32) + (31-y) + 32] = c; - p[width*((31-x)+64) + (31-y)] = c; - p[width*((31-x)+64) + (31-y) + 32] = c; - } - } - - - while (1) - { - ledscape_draw(leds, p); - usleep(20000); - } - - //ledscape_close(leds); - - return EXIT_SUCCESS; -} diff --git a/src/demos/cube-life.c b/src/demos/cube-life.c deleted file mode 100644 index 94a9ec7d..00000000 --- a/src/demos/cube-life.c +++ /dev/null @@ -1,504 +0,0 @@ -/** \file - * Play the game of life on the matrix cube. - * - * \todo this is broken until the matrix.p can handle different heights - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "ledscape.h" - - -/* LED mappings: - - +--------+ - | | - | Yellow | - |o 3 ^| - +-------|+ - | 2 || - | Green | - |o 0x32 | - +--------+--------+ - |o 0 |o 1 | - | red | purple | - |0x0 --> | - +--------+--------+--------+ - | 5 <-- 4 | - | Teal | Blue | - | o| 0x64 o| - +--------+--------+ - */ - -#define WIDTH 32 -typedef struct game game_t; -typedef struct { - game_t * board; - int edge; -} edge_t; - -struct game -{ - unsigned px, py; - - edge_t top; - edge_t bottom; - edge_t left; - edge_t right; - - uint8_t board[WIDTH][WIDTH]; -}; - - -static game_t boards[6] = {}; - -static void -randomize( - game_t * const b, - int chance -) -{ - for (int y = 0 ; y < WIDTH ; y++) - { - for (int x = 0 ; x < WIDTH ; x++) - { -#if 1 - unsigned live = (rand() % 128 < chance); - b->board[y][x] = live ? 3 : 0; -#else - b->board[y][x] = 0; -#endif - } - } - -} - - -static void -make_glider( - game_t * const b -) -{ - // X - // X - // XXX - int px = (rand() % 8) + 10; - int py = (rand() % 8) + 20; - b->board[py+0][px+0] = 0; - b->board[py+0][px+1] = 3; - b->board[py+0][px+2] = 0; - - b->board[py+1][px+0] = 0; - b->board[py+1][px+1] = 0; - b->board[py+1][px+2] = 3; - - b->board[py+2][px+0] = 3; - b->board[py+2][px+1] = 3; - b->board[py+2][px+2] = 3; -} - - -static uint8_t * -_get_edge( - edge_t * const e, - int pos -) -{ - game_t * const b = e->board; - const int edge = e->edge; - const int neg_pos = WIDTH - pos - 1; - - if (edge == 1) - return &b->board[0][pos]; - if (edge == 2) - return &b->board[pos][WIDTH-1]; - if (edge == 3) - return &b->board[WIDTH-1][pos]; - if (edge == 4) - return &b->board[pos][0]; - - if (edge == -1) - return &b->board[0][neg_pos]; - if (edge == -2) - return &b->board[neg_pos][WIDTH-1]; - if (edge == -3) - return &b->board[WIDTH-1][neg_pos]; - if (edge == -4) - return &b->board[neg_pos][0]; - -printf("bad %d,%d\n", edge, pos); - return NULL; -} - - -static uint8_t -get_edge( - edge_t * const e, - int pos -) -{ - uint8_t * const u = _get_edge(e, pos); - if (u) - return (*u) & 1; - return 0; -} - - -static unsigned -get_space( - game_t * const b, - int x, - int y -) -{ - if (x >= 0 && y >= 0 && x < WIDTH && y < WIDTH) - return b->board[y][x] & 1; - - // don't deal with diagonal connections - if (x < 0 && y < 0) - return 0; - if (x >= WIDTH && y >= WIDTH) - return 0; - - // Check for the four cardinal ones - if (y < 0) - return get_edge(&b->top, x); - if (y >= WIDTH) - return get_edge(&b->bottom, x); - if (x < 0) - return get_edge(&b->left, y); - if (x >= WIDTH) - return get_edge(&b->right, y); - - // huh? -printf("bad %d,%d\n", x, y); - return 9; -} - - -static void -play_game( - game_t * const b -) -{ - for (int y = 0 ; y < WIDTH ; y++) - { - for (int x = 0 ; x < WIDTH ; x++) - { - uint8_t sum = 0; - - sum += get_space(b, x-1, y-1); - sum += get_space(b, x-1, y ); - sum += get_space(b, x-1, y+1); - - sum += get_space(b, x , y-1); - sum += get_space(b, x , y+1); - - sum += get_space(b, x+1, y-1); - sum += get_space(b, x+1, y ); - sum += get_space(b, x+1, y+1); - - -/* -Any live cell with fewer than two live neighbours dies, -as if caused by under-population. -Any live cell with two or three live neighbours lives -on to the next generation. -Any live cell with more than three live neighbours dies, -as if by overcrowding. -Any dead cell with exactly three live neighbours becomes a live cell, -as if by reproduction. -*/ - if (b->board[y][x] & 1) - { - // currently live - if (sum == 2 || sum == 3) - b->board[y][x] |= 2; - else - b->board[y][x] &= ~2; - } else { - // currently dead - if (sum == 3) - b->board[y][x] |= 2; - else - b->board[y][x] &= ~2; - } - } - } -} - - -static void -identify( - uint8_t * const out, - int x, - int y -) -{ - uint32_t b = 0; - - if (x < 32) - { - if (y < 32) - b = 0xFF0000; - else - if (y < 64) - b = 0x0000FF; - else - if (y < 96) - b = 0x00FF00; - else - b = 0x411111; - } else - if (x < 64) - { - if (y < 32) - b = 0xFF00FF; - else - if (y < 64) - b = 0x00FFFF; - else - if (y < 96) - b = 0xFFFF00; - else - b = 0x114111; - } else { - b = 0x111141; - } - - out[0] = (b >> 16) & 0xFF; - out[1] = (b >> 8) & 0xFF; - out[2] = (b >> 0) & 0xFF; -} - -static void -copy_to_fb( - uint32_t * const p, - const unsigned width, - const unsigned height, - game_t * const board -) -{ - for (int y = 0 ; y < WIDTH ; y++) - { - for (int x = 0 ; x < WIDTH ; x++) - { - uint32_t * const pix_ptr = &p[width*(y+board->py) + x + board->px]; - uint32_t pix = *pix_ptr; - unsigned r = (pix >> 0) & 0xFF; - unsigned g = (pix >> 8) & 0xFF; - unsigned b = (pix >> 16) & 0xFF; - - // copy the new value to the current value - uint8_t * const sq = &board->board[y][x]; - *sq = (*sq & 2) | (*sq >> 1); - - unsigned live = *sq & 1; - if (live) - { - r += 80; - g += 5; - b += 30; - if (r > 0xFF) - r = 0xFF; - if (g > 0xFF) - g = 0xFF; - if (b > 0xFF) - b = 0xFF; - } else { -#if 1 -#define SMOOTH_R 3 -#define SMOOTH_G 127 -#define SMOOTH_B 63 -#else -#define SMOOTH_R 1 -#define SMOOTH_G 1 -#define SMOOTH_B 1 -#endif - r = (r * SMOOTH_R) / (SMOOTH_R+1); - g = (g * SMOOTH_G) / (SMOOTH_G+1); - b = (b * SMOOTH_B) / (SMOOTH_B+1); - } - - if (0 && x == 0 && y == 0) - identify(pix_ptr, board->px, board->py); - else - *pix_ptr = (r << 0) | (g << 8) | (b << 16); - } - } -} - - -static void -check_edge( - game_t * const boards, - int i, - edge_t *edge, - int this_edge -) -{ - game_t * b = &boards[i]; - game_t * n = edge->board; - int e = edge->edge; - - // verify that the back link from the remote board is to this - // edge on this board. - if (e == 1 && n->top.board == b && n->top.edge == this_edge) - return; - if (e == 2 && n->right.board == b && n->right.edge == this_edge) - return; - if (e == 3 && n->bottom.board == b && n->bottom.edge == this_edge) - return; - if (e == 4 && n->left.board == b && n->left.edge == this_edge) - return; - - if (e == -1 && n->top.board == b && n->top.edge == -this_edge) - return; - if (e == -2 && n->right.board == b && n->right.edge == -this_edge) - return; - if (e == -3 && n->bottom.board == b && n->bottom.edge == -this_edge) - return; - if (e == -4 && n->left.board == b && n->left.edge == -this_edge) - return; - - fprintf(stderr, "%d edge %d bad back link?\n", i, this_edge); - exit(-1); -} - - - -int -main(void) -{ - const int width = 128; - const int height = 128; - ledscape_config_t * const config = &ledscape_matrix_default; - config->matrix_config.panel_height = 32; - - ledscape_t * const leds = ledscape_init(config, 0); - printf("init done\n"); - time_t last_time = time(NULL); - unsigned last_i = 0; - - unsigned i = 0; - uint32_t * const p = calloc(width*height,4); - - game_t * const red = &boards[0]; - game_t * const purple = &boards[1]; - game_t * const green = &boards[2]; - game_t * const yellow = &boards[3]; - game_t * const blue = &boards[4]; - game_t * const teal = &boards[5]; - - // red - red->px = 0; - red->py = 0; - red->top = (edge_t) { green, 4 }; - red->right = (edge_t) { purple, 4 }; - red->bottom = (edge_t) { blue, -3 }; - red->left = (edge_t) { teal, -3 }; - - // purple - purple->px = WIDTH; - purple->py = 0; - purple->top = (edge_t) { green, 3 }; - purple->right = (edge_t) { yellow, 3 }; - purple->bottom = (edge_t) { blue, -4 }; - purple->left = (edge_t) { red, 2 }; - - // green - green->px = 0; - green->py = 2*WIDTH; - green->top = (edge_t) { teal, -2 }; - green->right = (edge_t) { yellow, 4 }; - green->bottom = (edge_t) { purple, 1 }; - green->left = (edge_t) { red, 1 }; - - // yellow - yellow->px = WIDTH; - yellow->py = 2*WIDTH; - yellow->top = (edge_t) { teal, -1 }; - yellow->right = (edge_t) { blue, -1 }; - yellow->bottom = (edge_t) { purple, 2 }; - yellow->left = (edge_t) { green, 2 }; - - // blue - blue->px = 0; - blue->py = WIDTH; - blue->top = (edge_t) { yellow, -2 }; - blue->right = (edge_t) { teal, 4 }; - blue->bottom = (edge_t) { red, -3 }; - blue->left = (edge_t) { purple, -3 }; - - // teal - teal->px = WIDTH; - teal->py = WIDTH; - teal->top = (edge_t) { yellow, -1 }; - teal->right = (edge_t) { green, -1 }; - teal->bottom = (edge_t) { red, -4 }; - teal->left = (edge_t) { blue, 2 }; - - for (int i = 0 ; i < 6 ; i++) - { - game_t * b = &boards[i]; - check_edge(boards, i, &boards[i].top, 1); - check_edge(boards, i, &boards[i].right, 2); - check_edge(boards, i, &boards[i].bottom, 3); - check_edge(boards, i, &boards[i].left, 4); - } - - srand(getpid()); - -if (1){ - int which = 5; - game_t * const b = &boards[which]; - - b->board[0][4] = 3; - *_get_edge(&b->top, 4) = 3; - - b->board[6][WIDTH-1] = 3; - *_get_edge(&b->right, 6) = 3; - - b->board[WIDTH-1][8] = 3; - *_get_edge(&b->bottom, 8) = 3; - - b->board[8][0] = 3; - *_get_edge(&b->left, 8) = 3; -} - - - while (1) - { - if ((i & 0x3FF) == 0) - { - printf("randomize\n"); - for (int i = 0 ; i < 6 ; i++) - { - randomize(&boards[i], 20); - //make_glider(&boards[i]); - } - //make_glider(&boards[rand() % 6]); - } - - if (i++ % 4 == 0) - { - for (int i = 0 ; i < 6 ; i++) - play_game(&boards[i]); - } - - for (int i = 0 ; i < 6 ; i++) - copy_to_fb(p, width, height, &boards[i]); - - ledscape_draw(leds, p); - usleep(10000); - } - - ledscape_close(leds); - - return EXIT_SUCCESS; -} diff --git a/src/demos/fire.c b/src/demos/fire.c deleted file mode 100644 index ee4b2689..00000000 --- a/src/demos/fire.c +++ /dev/null @@ -1,253 +0,0 @@ -/** \file - * Draw fire patterns, derived from the pyramid Fire code. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "ledscape.h" - -// sideways pyramid; 256 height, but 128 wide -#define WIDTH 64 -#define HEIGHT 64 - - -// Borrowed by OctoWS2811 rainbow test -static unsigned int -h2rgb( - unsigned int v1, - unsigned int v2, - unsigned int hue -) -{ - if (hue < 60) - return v1 * 60 + (v2 - v1) * hue; - if (hue < 180) - return v2 * 60; - if (hue < 240) - return v1 * 60 + (v2 - v1) * (240 - hue); - - return v1 * 60; -} - - -// Convert HSL (Hue, Saturation, Lightness) to RGB (Red, Green, Blue) -// -// hue: 0 to 359 - position on the color wheel, 0=red, 60=orange, -// 120=yellow, 180=green, 240=blue, 300=violet -// -// saturation: 0 to 100 - how bright or dull the color, 100=full, 0=gray -// -// lightness: 0 to 100 - how light the color is, 100=white, 50=color, 0=black -// -static uint32_t -hsv2rgb( - unsigned int hue, - unsigned int saturation, - unsigned int lightness -) -{ - unsigned int red, green, blue; - unsigned int var1, var2; - - if (hue > 359) - hue = hue % 360; - if (saturation > 100) - saturation = 100; - if (lightness > 100) - lightness = 100; - - // algorithm from: http://www.easyrgb.com/index.php?X=MATH&H=19#text19 - if (saturation == 0) { - red = green = blue = lightness * 255 / 100; - } else { - if (lightness < 50) { - var2 = lightness * (100 + saturation); - } else { - var2 = ((lightness + saturation) * 100) - (saturation * lightness); - } - var1 = lightness * 200 - var2; - red = h2rgb(var1, var2, (hue < 240) ? hue + 120 : hue - 240) * 255 / 600000; - green = h2rgb(var1, var2, hue) * 255 / 600000; - blue = h2rgb(var1, var2, (hue >= 120) ? hue - 120 : hue + 240) * 255 / 600000; - } - return (red << 16) | (green << 8) | (blue << 0); -} - - -// This will contain the pixels used to calculate the fire effect -static uint8_t fire[WIDTH][HEIGHT]; - - // Flame colors -static uint32_t palette[255]; -static float angle; -static uint32_t calc1[WIDTH], calc2[HEIGHT], calc3[WIDTH], calc4[WIDTH], calc5[HEIGHT]; - -static void -fire_draw( - uint32_t * const frame -) -{ - static int rotate_offset = 0; - - memset(frame, 0, WIDTH*HEIGHT*sizeof(*frame)); - - angle = angle + 0.05; - - // Randomize the bottom row of the fire buffer - for (int x = 0; x < WIDTH; x++) - { - fire[x][HEIGHT-1] = random() % 190; - } - - int counter = 0; - // Do the fire calculations for every pixel, from top to bottom - for (int x = 0; x < WIDTH; x++) { // up to 128, leds_height - for (int y = 0; y < HEIGHT; y++) { // up to 256, leds_width - // Add pixel values around current pixel - - fire[x][y] = - ((fire[calc3[x]][calc2[y]] - + fire[calc1[x]][calc2[y]] - + fire[calc4[x]][calc2[y]] - + fire[calc1[x]][calc5[y]]) << 5) / (128+(abs(x-WIDTH/2))/4); // 129; - - // Output everything to screen using our palette colors - const uint32_t c = palette[fire[x][y]]; - //frame[counter] = fire[x][y]; - - // Extract the red value using right shift and bit mask - // equivalent of red(pgTemp.pixels[x+y*WIDTH]) - // Only map 3D cube 'lit' pixels onto fire array needed for next frame - if (((c >> 0) & 0xFF) == 128) - fire[x][y] = 128; - - // skip the bottom few rows - /* -#if 1 - if (y > HEIGHT - leds_width) - frame[y - (HEIGHT - leds_width) + x*leds_width] = c; -#else - if (x > HEIGHT - leds_width) - frame[y - (HEIGHT - leds_width) + x*leds_width] = c; -#endif -*/ - frame[WIDTH*y + (x + rotate_offset / 16) % WIDTH] = c; - //frame[counter++] = c; - } - } - - rotate_offset++; -} - - -static void -sparkles( - uint32_t * const frame, - int num_sparkles -) -{ - for(int i = 0 ; i < num_sparkles ; i++) - frame[rand() % (WIDTH*HEIGHT)] = 0xFFFFFF; -} - -static int constrain( - int x, - int min, - int max -) -{ - if (x < min) - return min; - if (x > max) - return max; - return x; -} - -static void -init_pallete(void) -{ - for (int x = 0; x < 255; x++) { - //Hue goes from 0 to 85: red to yellow - //Saturation is always the maximum: 255 - //Lightness is 0..255 for x=0..128, and 255 for x=128..255 - palette[x] = hsv2rgb(x/2, 100, constrain(x, 0, 40)); - } - - // Precalculate which pixel values to add during animation loop - // this speeds up the effect by 10fps - for (int x = 0; x < WIDTH; x++) { - calc1[x] = x % WIDTH; - calc3[x] = (x - 1 + WIDTH) % WIDTH; - calc4[x] = (x + 1) % WIDTH; - } - - for (int y = 0; y < HEIGHT; y++) { - calc2[y] = (y + 1) % HEIGHT; - calc5[y] = (y + 2) % HEIGHT; - } -} - - -int -main( - int argc, - const char ** argv -) -{ - ledscape_matrix_config_t * config = &ledscape_matrix_default; - - if (argc > 1) - { - config = ledscape_config(argv[1]); - if (!config) - return EXIT_FAILURE; - } - - config->width = WIDTH; - config->height = HEIGHT; - ledscape_t * const leds = ledscape_init(config, 0); - - printf("init done\n"); - time_t last_time = time(NULL); - unsigned last_i = 0; - - unsigned i = 0; - init_pallete(); - uint32_t * const p = calloc(WIDTH*HEIGHT,4); - - while (1) - { - // Alternate frame buffers on each draw command - - time_t now = time(NULL); - const uint32_t delta = now - last_time; - - fire_draw(p); - sparkles(p, delta); - - ledscape_draw(leds, p); - usleep(50000); - - // wait for the previous frame to finish; - //const uint32_t response = ledscape_wait(leds); - const uint32_t response = 0; - if (delta > 30) - { - printf("%d fps. starting %d previous %"PRIx32"\n", - (i - last_i) / delta, i, response); - last_i = i; - last_time = now; - memset(fire, 0, sizeof(fire)); - } - - } - - ledscape_close(leds); - - return EXIT_SUCCESS; -} diff --git a/src/demos/identify.c b/src/demos/identify.c deleted file mode 100644 index ef89d240..00000000 --- a/src/demos/identify.c +++ /dev/null @@ -1,98 +0,0 @@ -/** \file - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "ledscape.h" - - -int -main( - int argc, - char ** argv -) -{ - const int width = 256; - const int height = 128; - - ledscape_config_t * config = &ledscape_matrix_default; - if (argc > 1) - { - config = ledscape_config(argv[1]); - if (!config) - return EXIT_FAILURE; - } - - if (config->type == LEDSCAPE_MATRIX) - { - config->matrix_config.width = width; - config->matrix_config.height = height; - } - - ledscape_t * const leds = ledscape_init(config, 0); - - //printf("init done %d,%d\n", width, height); - time_t last_time = time(NULL); - unsigned last_i = 0; - - unsigned i = 0; - uint32_t * const p = calloc(width*height,4); - int scroll_x = 128; - memset(p, 0x10, width*height*4); - - for (int i = 0 ; i < 8 ; i++) - { - for (int j = 0 ; j < 8 ; j++) - { - ledscape_printf( - &p[8+j*32 + width*i*16], - width, - 0xFF0000, // red - "%d-%d", - i, - j - ); - ledscape_printf( - &p[1+j*32 + width*i*16], - width, - 0x00FF00, // green - "^" - ); - ledscape_printf( - &p[1+j*32 + width*(i*16+8)], - width, - 0x0000FF, // blue - "|" - ); - p[j*32+width*i*16] = 0xFFFF00; - } - } - - while (1) - { - ledscape_draw(leds, p); - usleep(20000); - - // wait for the previous frame to finish; - //const uint32_t response = ledscape_wait(leds); - const uint32_t response = 0; - time_t now = time(NULL); - if (now != last_time) - { - printf("%d fps. starting %d previous %"PRIx32"\n", - i - last_i, i, response); - last_i = i; - last_time = now; - } - - } - - ledscape_close(leds); - - return EXIT_SUCCESS; -} diff --git a/src/demos/life.c b/src/demos/life.c deleted file mode 100644 index 762bef3e..00000000 --- a/src/demos/life.c +++ /dev/null @@ -1,267 +0,0 @@ -/** \file - * Play the game of life on the normal pyramid - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "ledscape.h" - -#define LIFE_R 0xFF -#define LIFE_G 0x35 -#define LIFE_B 0x90 -#define SMOOTH_R 127 -#define SMOOTH_G 20 -#define SMOOTH_B 10 -#define DELTA_R 10 -#define DELTA_G 30 -#define DELTA_B 80 - -#define WIDTH 512 -#define HEIGHT 64 - -typedef struct -{ - uint8_t board[HEIGHT][WIDTH]; -} game_t; - -static game_t board; - - -static void -randomize( - game_t * const b, - int chance -) -{ - for (int y = 0 ; y < HEIGHT ; y++) - { - for (int x = 0 ; x < WIDTH ; x++) - { -#if 1 - unsigned live = (rand() % 128 < chance); - b->board[y][x] = live ? 3 : 0; -#else - b->board[y][x] = 0; -#endif - } - } - -} - - -static void -make_glider( - game_t * const b -) -{ - // X - // X - // XXX - int px = (rand() % 8) + 10; - int py = (rand() % 8) + 20; - b->board[py+0][px+0] = 0; - b->board[py+0][px+1] = 3; - b->board[py+0][px+2] = 0; - - b->board[py+1][px+0] = 0; - b->board[py+1][px+1] = 0; - b->board[py+1][px+2] = 3; - - b->board[py+2][px+0] = 3; - b->board[py+2][px+1] = 3; - b->board[py+2][px+2] = 3; -} - - - -static unsigned -get_space( - game_t * const b, - int x, - int y -) -{ - if (x >= 0 && y >= 0 && x < WIDTH && y < HEIGHT) - return b->board[y][x] & 1; - - if (y < 0 || y >= HEIGHT) - return 0; - - // map the x to a cylinder - if (x < 0) - return b->board[y][WIDTH - x] & 1; - if (x >= WIDTH) - return b->board[y][x - WIDTH] & 1; - - return 0; -} - - -static void -play_game( - game_t * const b -) -{ - for (int y = 0 ; y < HEIGHT ; y++) - { - for (int x = 0 ; x < WIDTH ; x++) - { - uint8_t sum = 0; - - sum += get_space(b, x-1, y-1); - sum += get_space(b, x-1, y ); - sum += get_space(b, x-1, y+1); - - sum += get_space(b, x , y-1); - sum += get_space(b, x , y+1); - - sum += get_space(b, x+1, y-1); - sum += get_space(b, x+1, y ); - sum += get_space(b, x+1, y+1); - - -/* -Any live cell with fewer than two live neighbours dies, -as if caused by under-population. -Any live cell with two or three live neighbours lives -on to the next generation. -Any live cell with more than three live neighbours dies, -as if by overcrowding. -Any dead cell with exactly three live neighbours becomes a live cell, -as if by reproduction. -*/ - if (b->board[y][x] & 1) - { - // currently live - if (sum == 2 || sum == 3) - b->board[y][x] |= 2; - else - b->board[y][x] &= ~2; - } else { - // currently dead - if (sum == 3) - b->board[y][x] |= 2; - else - b->board[y][x] &= ~2; - } - } - } -} - - - -static void -copy_to_fb( - uint32_t * const p, - const unsigned width, - const unsigned height, - game_t * const board -) -{ - (void) height; - - for (int y = 0 ; y < HEIGHT ; y++) - { - for (int x = 0 ; x < WIDTH ; x++) - { - uint32_t * const pix_ptr = &p[width*y + x]; - uint32_t pix = *pix_ptr; - unsigned r = (pix >> 0) & 0xFF; - unsigned g = (pix >> 8) & 0xFF; - unsigned b = (pix >> 16) & 0xFF; - - // copy the new value to the current value - uint8_t * const sq = &board->board[y][x]; - *sq = (*sq & 2) | (*sq >> 1); - - unsigned live = *sq & 1; - if (live) - { - r += DELTA_R; - g += DELTA_G; - b += DELTA_B; - if (r > LIFE_R) - r = LIFE_R; - if (g > LIFE_G) - g = LIFE_G; - if (b > LIFE_B) - b = LIFE_B; - } else { - r = (r * SMOOTH_R) / (SMOOTH_R+1); - g = (g * SMOOTH_G) / (SMOOTH_G+1); - b = (b * SMOOTH_B) / (SMOOTH_B+1); - } - - if (r > 255) r = 255; - if (g > 255) g = 255; - if (b > 255) b = 255; - if (r < 0) r = 0; - if (g < 0) g = 0; - if (b < 0) b = 0; - - *pix_ptr = ((r << 16) | (g << 8) | (b << 0)); - } - } -} - - - -int -main( - int argc, - const char ** argv -) -{ - ledscape_config_t * config = &ledscape_matrix_default; - if (argc > 1) - { - config = ledscape_config(argv[1]); - if (!config) - return EXIT_FAILURE; - } - - if (config->type == LEDSCAPE_MATRIX) - { - config->matrix_config.width = WIDTH; - config->matrix_config.height = HEIGHT; - } - - ledscape_t * const leds = ledscape_init(config, 0); - printf("init done\n"); - time_t last_time = time(NULL); - unsigned last_i = 0; - - unsigned i = 0; - uint32_t * const p = calloc(WIDTH*HEIGHT,4); - - srand(getpid()); - - while (1) - { - if ((i & 0x7FF) == 0) - { - printf("randomize\n"); - randomize(&board, 20); - //make_glider(&boards[i]); - } - - if (i++ % 4 == 0) - { - play_game(&board); - } - - copy_to_fb(p, WIDTH, HEIGHT, &board); - - ledscape_draw(leds, p); - usleep(1000); - } - - ledscape_close(leds); - - return EXIT_SUCCESS; -} diff --git a/src/demos/lightcycles.c b/src/demos/lightcycles.c deleted file mode 100644 index a396d92f..00000000 --- a/src/demos/lightcycles.c +++ /dev/null @@ -1,379 +0,0 @@ -/** \file - * Lightcycles style game on the cylindrical megascroller. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define WIDTH 512 -#define HEIGHT 64 -#define MAX_PLAYERS 4 - -uint32_t board[HEIGHT][WIDTH]; - -typedef struct { - int x; - int y; - int dir; - uint32_t color; - int alive; -} player_t; - -player_t players[MAX_PLAYERS]; - - -int -player_update( - player_t * const player -) -{ - if (!player->alive) - return 0; - - switch (player->dir) - { - case 0: - player->x = (player->x + 1 + WIDTH) % WIDTH; - break; - case 1: - player->y = (player->y + 1 + HEIGHT) % HEIGHT; - break; - case 2: - player->x = (player->x - 1 + WIDTH) % WIDTH; - break; - case 3: - player->y = (player->y - 1 + HEIGHT) % HEIGHT; - break; - default: - player->dir = 0; - break; - } - - // check for collision - if (board[player->y][player->x] != 0) - { - // dead! - printf("player %08x died at %d,%d\n", - player->color, player->x, player->y); - board[player->y][player->x] = 0xFFFFFF; - player->alive = 0; - } else { - // ok! - board[player->y][player->x] = player->color; - } - - return player->alive; -} - - -static const uint32_t palette[] = -{ - 0xFF0000, - 0x00FF00, - 0x0000FF, - 0xFF00FF, - 0xFFFF00, -}; - - - -static void -fill( - uint32_t color -) -{ - for (int y = 0 ; y < HEIGHT ; y++) - for (int x = 0 ; x < WIDTH ; x++) - board[y][x] = color; -} - - -void -new_game( - int num_players -) -{ - fill(0); - - for (int i = 0 ; i < MAX_PLAYERS ; i++) - { - player_t * const player = &players[i]; - player->alive = i < num_players ? 1 : 0; - player->x = 0; // rand() % WIDTH; - player->y = rand() % HEIGHT; - player->dir = 0; //(rand() % 2) ? 0 : 2; - player->color = palette[i]; - } -} - -static int -tcp_socket( - const int port -) -{ - const int sock = socket(AF_INET, SOCK_STREAM, 0); - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_port = htons(port), - .sin_addr.s_addr = INADDR_ANY, - }; - - if (sock < 0) - return -1; - if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr)) < 0) - return -1; - - int max_size = 65536; - setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &max_size, sizeof(max_size)); - - - return sock; -} - - -static -void rgb32_to_rgb24_and_decay( - uint8_t * const out, - uint32_t * const in, - const int width, - const int height -) -{ - for (int y = 0 ; y < height ; y++) - { - for (int x = 0 ; x < width ; x++) - { - uint8_t * const pix = out + 3*(x + y*width); - uint32_t * const in_pix = &in[x + y*width]; - const uint32_t c = *in_pix; - - uint8_t r = pix[0] = (c >> 16) & 0xFF; - uint8_t g = pix[1] = (c >> 8) & 0xFF; - uint8_t b = pix[2] = (c >> 0) & 0xFF; - - if (r) r--; - if (g) g--; - if (b) b--; - - *in_pix = (r << 16) | (g << 8) | (b << 0); - } - } -} - - -static void -send_game( - const int sock -) -{ - // copy the game from RGBx to RGB and split into two packets - uint8_t pkt[65536]; - - pkt[0] = 0; - rgb32_to_rgb24_and_decay(&pkt[1], &board[0][0], WIDTH, HEIGHT/2); - if (send(sock, pkt, 1 + (WIDTH*HEIGHT/2) * 3, 0) < 0) - { - perror("send"); - exit(EXIT_FAILURE); - } - - pkt[0] = 1; - rgb32_to_rgb24_and_decay(&pkt[1], &board[HEIGHT/2][0], WIDTH, HEIGHT/2); - send(sock, pkt, 1 + (WIDTH*HEIGHT/2) * 3, 0); -} - - -static struct termios ttystate, ttysave; - -static void -tty_raw(void) -{ - //get the terminal state - tcgetattr(STDIN_FILENO, &ttystate); - ttysave = ttystate; - - //turn off canonical mode and echo - ttystate.c_lflag &= ~(ICANON | ECHO); - //minimum of number input read. - ttystate.c_cc[VMIN] = 1; - tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); -} - -static void -tty_reset(void) -{ - ttystate.c_lflag |= ICANON | ECHO; - tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); -} - - -// don't allow a turn backwards into yourself -static void -set_dir( - player_t * const player, - int new_dir -) -{ - if (new_dir == 0 && player->dir == 2) - return; - if (new_dir == 1 && player->dir == 3) - return; - if (new_dir == 2 && player->dir == 0) - return; - if (new_dir == 3 && player->dir == 1) - return; - - player->dir = new_dir; -} - - -static void -bomb( - player_t * const player -) -{ - // nothing yet - (void) player; -} - - - -static void * -read_thread( - void * arg -) -{ - (void) arg; - tty_raw(); - atexit(tty_reset); - - while (1) - { - char c; - ssize_t rc = read(STDIN_FILENO, &c, 1); - if (rc < 0) - { - if (rc == EINTR || rc == EAGAIN) - continue; - perror("stdin"); - break; - } - if (rc == 0) - continue; - - switch (c) - { - case 'h': set_dir(&players[0], 2); break; - case 'j': set_dir(&players[0], 1); break; - case 'k': set_dir(&players[0], 3); break; - case 'l': set_dir(&players[0], 0); break; - case ';': bomb(&players[0]); break; - - case 'a': set_dir(&players[1], 2); break; - case 's': set_dir(&players[1], 1); break; - case 'w': set_dir(&players[1], 3); break; - case 'd': set_dir(&players[1], 0); break; - case 'f': bomb(&players[1]); break; - - default: break; - } - } - - return NULL; -} - - -int main(void) -{ - int port = 9999; - const char * host = "192.168.1.119"; - - const int sock = tcp_socket(0); - struct sockaddr_in dest = { - .sin_family = AF_INET, - .sin_port = htons(port), - .sin_addr = { inet_addr(host) }, - }; - if (connect(sock, (void*) &dest, sizeof(dest)) < 0) - { - perror(host); - return EXIT_FAILURE; - } - - pthread_t thread_id; - if (pthread_create(&thread_id, NULL, read_thread, NULL) < 0) - { - perror("pthread"); - return EXIT_FAILURE; - } - - - int num_players = 2; - - while (1) - { - printf("new game!\n"); - new_game(num_players); - - while (1) - { - send_game(sock); - - int alive_count = 0; - for (int i = 0 ; i < num_players ; i++) - alive_count += player_update(&players[i]); - - if (alive_count == 1) - break; - usleep(5000); - } - - // one player won! figure out who - player_t * winner = NULL; - for (int i = 0 ; i < num_players ; i++) - { - player_t * const player = &players[i]; - if (!player->alive) - continue; - winner = player; - break; - } - - if (winner == NULL) - { - printf("no one won\n"); - continue; - } - - printf("%08x won\n", winner->color); - - // flash the screen - for (int i = 0 ; i < 3 ; i++) - { - fill(winner->color); - send_game(sock); - usleep(250000); - - fill(0); - send_game(sock); - usleep(250000); - - fill(winner->color); - send_game(sock); - usleep(250000); - - fill(0); - send_game(sock); - usleep(500000); - } - } -} diff --git a/src/demos/matrix-test.c b/src/demos/matrix-test.c deleted file mode 100644 index 7ac0bb7c..00000000 --- a/src/demos/matrix-test.c +++ /dev/null @@ -1,269 +0,0 @@ -/** \file - * Test the matrix LCD PRU firmware with a multi-hue rainbow. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "ledscape.h" - - -// Borrowed by OctoWS2811 rainbow test -static unsigned int -h2rgb( - unsigned int v1, - unsigned int v2, - unsigned int hue -) -{ - if (hue < 60) - return v1 * 60 + (v2 - v1) * hue; - if (hue < 180) - return v2 * 60; - if (hue < 240) - return v1 * 60 + (v2 - v1) * (240 - hue); - - return v1 * 60; -} - - -// Convert HSL (Hue, Saturation, Lightness) to RGB (Red, Green, Blue) -// -// hue: 0 to 359 - position on the color wheel, 0=red, 60=orange, -// 120=yellow, 180=green, 240=blue, 300=violet -// -// saturation: 0 to 100 - how bright or dull the color, 100=full, 0=gray -// -// lightness: 0 to 100 - how light the color is, 100=white, 50=color, 0=black -// -static uint32_t -makeColor( - unsigned int hue, - unsigned int saturation, - unsigned int lightness -) -{ - unsigned int red, green, blue; - unsigned int var1, var2; - - if (hue > 359) - hue = hue % 360; - if (saturation > 100) - saturation = 100; - if (lightness > 100) - lightness = 100; - - // algorithm from: http://www.easyrgb.com/index.php?X=MATH&H=19#text19 - if (saturation == 0) { - red = green = blue = lightness * 255 / 100; - } else { - if (lightness < 50) { - var2 = lightness * (100 + saturation); - } else { - var2 = ((lightness + saturation) * 100) - (saturation * lightness); - } - var1 = lightness * 200 - var2; - red = h2rgb(var1, var2, (hue < 240) ? hue + 120 : hue - 240) * 255 / 600000; - green = h2rgb(var1, var2, hue) * 255 / 600000; - blue = h2rgb(var1, var2, (hue >= 120) ? hue - 120 : hue + 240) * 255 / 600000; - } - return (red << 16) | (green << 8) | blue; -} - - - -static uint32_t rainbowColors[180]; - - -// phaseShift is the shift between each row. phaseShift=0 -// causes all rows to show the same colors moving together. -// phaseShift=180 causes each row to be the opposite colors -// as the previous. -// -// cycleTime is the number of milliseconds to shift through -// the entire 360 degrees of the color wheel: -// Red -> Orange -> Yellow -> Green -> Blue -> Violet -> Red -// -static void -rainbow( - uint32_t * const pixels, - unsigned width, - unsigned height, - unsigned phaseShift, - unsigned cycle -) -{ - const unsigned color = cycle % 180; - const unsigned dim = 128; - - static unsigned count = 0; - - count += 1; - - for (unsigned x=0; x < width; x++) { - for (unsigned y=0; y < height; y++) { - const int index = (color + x + y*phaseShift/4) % 180; - const uint32_t in = rainbowColors[index]; - uint8_t * const out = &pixels[x + y*width]; -#if 1 - out[0] = ((in >> 0) & 0xFF) * dim / 128; // * y / 16; - out[1] = ((in >> 8) & 0xFF) * dim / 128; // * y / 16; - out[2] = ((in >> 16) & 0xFF) * dim / 128; // * y / 16; -#else - if(y==((count >> 3) & 0x1F) && x<20) { - out[0] = 0xff; - out[1] = 0xff; - out[2] = 0x00; - } - else { - out[0] = 0x00; - out[1] = 0x00; - out[2] = 0xff; - } -#endif - } - } -} - - -static void -gradient( - uint32_t * const pixels, - unsigned width, - unsigned height, - unsigned phaseShift, - unsigned cycle -) -{ - cycle >>= 3; - for (unsigned x=0; x < width; x++) { - for (unsigned y=0; y < height; y++) { - uint8_t * const out = &pixels[x + y*width]; -#if 0 - //out[0] = ((x+cycle) % 32) * 8; - //out[1] = ((y+cycle) % 16) * 16; - uint8_t b = 0xFF; - out[1] = b * ((((x + y + cycle) >> 5) ) & 1); -#else - uint32_t b = 0; - - if (x % 32 < (x/32 + 4) && y % 32 < (y/32+1)) - { - b = 0xFFFFFF; - } else - if (x < 32) - { - if (y < 32) - b = 0xFF0000; - else - if (y < 64) - b = 0x0000FF; - else - if (y < 96) - b = 0x00FF00; - else - b = 0x411111; - } else - if (x < 64) - { - if (y < 32) - b = 0xFF00FF; - else - if (y < 64) - b = 0x00FFFF; - else - if (y < 96) - b = 0xFFFF00; - else - b = 0x114111; - } else { - b = 0x111141; - } - - out[0] = (b >> 16) & 0xFF; - out[1] = (b >> 8) & 0xFF; - out[2] = (b >> 0) & 0xFF; - //*out = b; -#endif - } - } -} - - -int -main( - int argc, - const char ** argv -) -{ -// int width = 240; // 256; -// int height = 64; //128; - int width = 135; - int height = 32; - - ledscape_config_t * config = &ledscape_matrix_default; - if (argc > 1) - { - config = ledscape_config(argv[1]); - if (!config) - return EXIT_FAILURE; - } - - if (config->type == LEDSCAPE_MATRIX) - { - config->matrix_config.width = width; - config->matrix_config.height = height; - } - - ledscape_t * const leds = ledscape_init(config, 0); - - - printf("init done\n"); - time_t last_time = time(NULL); - unsigned last_i = 0; - - // pre-compute the 180 rainbow colors - for (int i=0; i<180; i++) - { - int hue = i * 2; - int saturation = 100; - int lightness = 50; - rainbowColors[i] = makeColor(hue, saturation, lightness); - } - - unsigned i = 0; - uint32_t * const p = calloc(width*height,4); - - while (1) - { - if (1) - rainbow(p, width, height, 10, i++); - else - gradient(p, width, height, 10, i++); - - ledscape_draw(leds, p); - - usleep(20000); - - // wait for the previous frame to finish; - //const uint32_t response = ledscape_wait(leds); - const uint32_t response = 0; - time_t now = time(NULL); - if (now != last_time) - { - printf("%d fps. starting %d previous %"PRIx32"\n", - i - last_i, i, response); - last_i = i; - last_time = now; - } - - } - - ledscape_close(leds); - - return EXIT_SUCCESS; -} diff --git a/src/ledgames/rsrc/Makefile b/src/ledgames/rsrc/Makefile index a5a25539..34ed7e29 100644 --- a/src/ledgames/rsrc/Makefile +++ b/src/ledgames/rsrc/Makefile @@ -11,3 +11,8 @@ all: copy copy: cp -f $(FILES) $(BINDIR) + +clean: + rm -rf $(BINDIR)*.wav + rm -rf $(BINDIR)Invaders.png + diff --git a/src/mta/Makefile b/src/mta/Makefile deleted file mode 100755 index 09cae2c8..00000000 --- a/src/mta/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -######### -# -# Build the MTA sign demo -# -# -BIN-y += mta-sign - -mta-sign.srcs += mta-sign.c -mta-sign.srcs += mta-font.c - -include ../../Makefile.common - diff --git a/src/mta/mta-font.c b/src/mta/mta-font.c deleted file mode 100644 index e73227cd..00000000 --- a/src/mta/mta-font.c +++ /dev/null @@ -1,1304 +0,0 @@ -/** ile - * Generated font from json file output by - * http://www.pentacom.jp/pentacom/bitfontmaker2/ - */ -#include - -const uint16_t font[][16] = { -['!'] = { - 0x0780, - 0x1fe0, - 0x3ff0, - 0x7cf8, - 0x7c78, - 0xfcfc, - 0xfcfc, - 0xfcfc, - 0x7cf8, - 0x7cf8, - 0x3ff0, - 0x1fe0, - 0x0780, - 0x0000, - 0x0000, - 0x0000, -}, -['#'] = { - 0x0780, - 0x1fe0, - 0x3ff0, - 0x7878, - 0x7338, - 0xf3fc, - 0xf8fc, - 0xf3fc, - 0x7338, - 0x7878, - 0x3ff0, - 0x1fe0, - 0x0780, - 0x0000, - 0x0000, - 0x0000, -}, -['$'] = { - 0x0780, - 0x1fe0, - 0x3ff0, - 0x79f8, - 0x78f8, - 0xf97c, - 0xf9bc, - 0xf03c, - 0x79f8, - 0x79f8, - 0x3ff0, - 0x1fe0, - 0x0780, - 0x0000, - 0x0000, - 0x0000, -}, -['%'] = { - 0x0780, - 0x1fe0, - 0x3ff0, - 0x7038, - 0x7f38, - 0xff3c, - 0xf03c, - 0xf3fc, - 0x7338, - 0x7878, - 0x3ff0, - 0x1fe0, - 0x0780, - 0x0000, - 0x0000, - 0x0000, -}, -['*'] = { - 0x0100, - 0x0380, - 0x07c0, - 0x0c60, - 0x1b30, - 0x3f38, - 0x7c3c, - 0x3938, - 0x1930, - 0x0c60, - 0x07c0, - 0x0380, - 0x0100, - 0x0000, - 0x0000, - 0x0000, -}, -[','] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x000c, - 0x000c, - 0x0008, - 0x0004, - 0x0000, - 0x0000, -}, -['-'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x007c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['.'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x000c, - 0x000c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['/'] = { - 0x0000, - 0x0000, - 0x0000, - 0x01f8, - 0x01f0, - 0x01e0, - 0x01f0, - 0x01b8, - 0x011c, - 0x000c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['0'] = { - 0x0000, - 0x0078, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x0078, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['1'] = { - 0x0000, - 0x00e0, - 0x00f0, - 0x00d8, - 0x00cc, - 0x00c0, - 0x00c0, - 0x00c0, - 0x00c0, - 0x00c0, - 0x00c0, - 0x00c0, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['2'] = { - 0x0000, - 0x0078, - 0x00fc, - 0x00cc, - 0x00c0, - 0x00c0, - 0x0060, - 0x0070, - 0x0038, - 0x001c, - 0x00fc, - 0x00fc, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['3'] = { - 0x0000, - 0x0078, - 0x00fc, - 0x00cc, - 0x00c0, - 0x0070, - 0x0070, - 0x00c0, - 0x00c0, - 0x00cc, - 0x00fc, - 0x0078, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['4'] = { - 0x0000, - 0x0080, - 0x00c0, - 0x00e0, - 0x00f0, - 0x00d8, - 0x00cc, - 0x00fc, - 0x00fc, - 0x00c0, - 0x00c0, - 0x00c0, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['5'] = { - 0x0000, - 0x00fc, - 0x00fc, - 0x000c, - 0x000c, - 0x007c, - 0x00fc, - 0x00c0, - 0x00c0, - 0x00c0, - 0x00fc, - 0x007c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['6'] = { - 0x0000, - 0x0078, - 0x00fc, - 0x00cc, - 0x000c, - 0x007c, - 0x00fc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00fc, - 0x0078, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['7'] = { - 0x0000, - 0x00fc, - 0x00fc, - 0x00c0, - 0x0060, - 0x0060, - 0x0030, - 0x0030, - 0x0018, - 0x0018, - 0x000c, - 0x000c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['8'] = { - 0x0000, - 0x0078, - 0x00fc, - 0x00cc, - 0x00cc, - 0x0078, - 0x0078, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00fc, - 0x0078, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['9'] = { - 0x0000, - 0x0078, - 0x00fc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00fc, - 0x00f8, - 0x00c0, - 0x00cc, - 0x00fc, - 0x0078, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['<'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0020, - 0x0030, - 0x03f8, - 0x03fc, - 0x03f8, - 0x0030, - 0x0020, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['>'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0040, - 0x00c0, - 0x01fc, - 0x03fc, - 0x01fc, - 0x00c0, - 0x0040, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['@'] = { - 0x0780, - 0x1fe0, - 0x3ff0, - 0x7878, - 0x7338, - 0xf3fc, - 0xf9fc, - 0xfcfc, - 0x7e78, - 0x7038, - 0x3ff0, - 0x1fe0, - 0x0780, - 0x0000, - 0x0000, - 0x0000, -}, -['A'] = { - 0x0000, - 0x00e0, - 0x00e0, - 0x00e0, - 0x01b0, - 0x01b0, - 0x01b0, - 0x0318, - 0x03f8, - 0x03f8, - 0x060c, - 0x060c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['B'] = { - 0x0000, - 0x007c, - 0x00fc, - 0x00cc, - 0x00cc, - 0x007c, - 0x007c, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00fc, - 0x007c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['C'] = { - 0x0000, - 0x00f0, - 0x01f8, - 0x0398, - 0x010c, - 0x000c, - 0x000c, - 0x000c, - 0x010c, - 0x0398, - 0x01f8, - 0x00f0, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['D'] = { - 0x0000, - 0x007c, - 0x00fc, - 0x01cc, - 0x018c, - 0x018c, - 0x018c, - 0x018c, - 0x018c, - 0x01cc, - 0x00fc, - 0x007c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['E'] = { - 0x0000, - 0x01fc, - 0x01fc, - 0x000c, - 0x000c, - 0x01fc, - 0x01fc, - 0x000c, - 0x000c, - 0x000c, - 0x01fc, - 0x01fc, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['F'] = { - 0x0000, - 0x00fc, - 0x00fc, - 0x000c, - 0x000c, - 0x007c, - 0x007c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['G'] = { - 0x0000, - 0x00f0, - 0x01f8, - 0x0398, - 0x010c, - 0x000c, - 0x000c, - 0x03cc, - 0x03cc, - 0x0198, - 0x01f8, - 0x00f0, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['H'] = { - 0x0000, - 0x018c, - 0x018c, - 0x018c, - 0x018c, - 0x01fc, - 0x01fc, - 0x018c, - 0x018c, - 0x018c, - 0x018c, - 0x018c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['I'] = { - 0x0000, - 0x00fc, - 0x00fc, - 0x0030, - 0x0030, - 0x0030, - 0x0030, - 0x0030, - 0x0030, - 0x0030, - 0x00fc, - 0x00fc, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['L'] = { - 0x0000, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x03fc, - 0x03fc, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['M'] = { - 0x0000, - 0x060c, - 0x071c, - 0x07bc, - 0x07fc, - 0x06ec, - 0x064c, - 0x060c, - 0x060c, - 0x060c, - 0x060c, - 0x060c, - 0x0000, - 0x0000, - 0x0000, - 0x0001, -}, -['N'] = { - 0x0000, - 0x018c, - 0x019c, - 0x01bc, - 0x01fc, - 0x01ec, - 0x01cc, - 0x018c, - 0x018c, - 0x018c, - 0x018c, - 0x018c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['O'] = { - 0x0000, - 0x00f0, - 0x01f8, - 0x0198, - 0x030c, - 0x030c, - 0x030c, - 0x030c, - 0x030c, - 0x0198, - 0x01f8, - 0x00f0, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['P'] = { - 0x0000, - 0x007c, - 0x00fc, - 0x00cc, - 0x00cc, - 0x00fc, - 0x007c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['Q'] = { - 0x0000, - 0x00f8, - 0x01fc, - 0x018c, - 0x018c, - 0x018c, - 0x018c, - 0x018c, - 0x01ac, - 0x00cc, - 0x01fc, - 0x0378, - 0x0200, - 0x0000, - 0x0000, - 0x0001, -}, -['R'] = { - 0x0000, - 0x00fc, - 0x01fc, - 0x018c, - 0x018c, - 0x01fc, - 0x00fc, - 0x00cc, - 0x018c, - 0x018c, - 0x018c, - 0x018c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['S'] = { - 0x0000, - 0x00f8, - 0x01fc, - 0x018c, - 0x018c, - 0x003c, - 0x00f8, - 0x01c0, - 0x018c, - 0x018c, - 0x01fc, - 0x00f8, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['T'] = { - 0x0000, - 0x03fc, - 0x03fc, - 0x0060, - 0x0060, - 0x0060, - 0x0060, - 0x0060, - 0x0060, - 0x0060, - 0x0060, - 0x0060, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['U'] = { - 0x0000, - 0x0318, - 0x0318, - 0x0318, - 0x0318, - 0x0318, - 0x0318, - 0x0318, - 0x0318, - 0x0318, - 0x03f8, - 0x01f0, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['V'] = { - 0x0000, - 0x060c, - 0x060c, - 0x0318, - 0x0318, - 0x0318, - 0x01b0, - 0x01b0, - 0x01b0, - 0x00e0, - 0x00e0, - 0x00e0, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['W'] = { - 0x0000, - 0x030c, - 0x030c, - 0x030c, - 0x030c, - 0x030c, - 0x030c, - 0x036c, - 0x03fc, - 0x03fc, - 0x039c, - 0x030c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['X'] = { - 0x0000, - 0x030c, - 0x030c, - 0x0198, - 0x0198, - 0x00f0, - 0x0060, - 0x00f0, - 0x0198, - 0x0198, - 0x030c, - 0x030c, - 0x0000, - 0x0000, - 0x0000, - 0x0001, -}, -['Y'] = { - 0x0000, - 0x030c, - 0x030c, - 0x0198, - 0x0198, - 0x00f0, - 0x00f0, - 0x0060, - 0x0060, - 0x0060, - 0x0060, - 0x0060, - 0x0000, - 0x0000, - 0x0000, - 0x0001, -}, -['Z'] = { - 0x0000, - 0x01fc, - 0x01fc, - 0x00c0, - 0x0060, - 0x0060, - 0x0030, - 0x0030, - 0x0018, - 0x0018, - 0x01fc, - 0x01fc, - 0x0000, - 0x0000, - 0x0000, - 0x0001, -}, -['\\'] = { - 0x0000, - 0x0000, - 0x0000, - 0x00fc, - 0x007c, - 0x003c, - 0x007c, - 0x00ec, - 0x01c4, - 0x0180, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['^'] = { - 0x0780, - 0x1fe0, - 0x3ff0, - 0x7878, - 0x7f38, - 0xff3c, - 0xf83c, - 0xf33c, - 0x7338, - 0x7878, - 0x3ff0, - 0x1fe0, - 0x0780, - 0x0000, - 0x0000, - 0x0000, -}, -['a'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0078, - 0x00fc, - 0x00cc, - 0x00f0, - 0x00fc, - 0x00cc, - 0x00fc, - 0x00d8, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['b'] = { - 0x0000, - 0x000c, - 0x000c, - 0x000c, - 0x007c, - 0x00fc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00fc, - 0x007c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['c'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0070, - 0x00f8, - 0x00cc, - 0x000c, - 0x000c, - 0x00cc, - 0x00f8, - 0x0070, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['d'] = { - 0x0000, - 0x00c0, - 0x00c0, - 0x00c0, - 0x00f8, - 0x00fc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00fc, - 0x00f8, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['e'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0078, - 0x00fc, - 0x00cc, - 0x00fc, - 0x000c, - 0x00cc, - 0x00fc, - 0x0078, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['f'] = { - 0x0000, - 0x0030, - 0x0038, - 0x0018, - 0x003c, - 0x003c, - 0x0018, - 0x0018, - 0x0018, - 0x0018, - 0x0018, - 0x0018, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['g'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x00d8, - 0x00fc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00fc, - 0x00d8, - 0x00c0, - 0x00cc, - 0x0078, - 0x0000, -}, -['h'] = { - 0x0000, - 0x000c, - 0x000c, - 0x000c, - 0x006c, - 0x00fc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['i'] = { - 0x0000, - 0x0018, - 0x0018, - 0x0000, - 0x0018, - 0x0018, - 0x0018, - 0x0018, - 0x0018, - 0x0018, - 0x003c, - 0x003c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['k'] = { - 0x0000, - 0x000c, - 0x000c, - 0x000c, - 0x00cc, - 0x006c, - 0x003c, - 0x007c, - 0x006c, - 0x006c, - 0x00cc, - 0x00cc, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['l'] = { - 0x0000, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['m'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x077c, - 0x0ffc, - 0x0ccc, - 0x0ccc, - 0x0ccc, - 0x0ccc, - 0x0ccc, - 0x0ccc, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['n'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x007c, - 0x00fc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['o'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0078, - 0x00fc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00fc, - 0x0078, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['p'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x003c, - 0x007c, - 0x006c, - 0x006c, - 0x006c, - 0x006c, - 0x007c, - 0x003c, - 0x000c, - 0x000c, - 0x000c, - 0x0000, -}, -['r'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0038, - 0x007c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x000c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['s'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0078, - 0x00fc, - 0x000c, - 0x007c, - 0x00f8, - 0x00c0, - 0x00fc, - 0x007c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['t'] = { - 0x0000, - 0x0018, - 0x0018, - 0x003c, - 0x003c, - 0x0018, - 0x0018, - 0x0018, - 0x0018, - 0x0018, - 0x0038, - 0x0038, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['u'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00cc, - 0x00fc, - 0x00f8, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['v'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x030c, - 0x030c, - 0x030c, - 0x0198, - 0x01f8, - 0x00f0, - 0x0060, - 0x0060, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['w'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x180c, - 0x180c, - 0x19cc, - 0x19cc, - 0x0b68, - 0x0f78, - 0x0e38, - 0x0e38, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['x'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x018c, - 0x018c, - 0x00d8, - 0x0070, - 0x0070, - 0x00d8, - 0x018c, - 0x018c, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -['y'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x030c, - 0x030c, - 0x0198, - 0x0198, - 0x00f0, - 0x00f0, - 0x0060, - 0x0060, - 0x0078, - 0x0038, - 0x0000, - 0x0000, -}, -['z'] = { - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x00fc, - 0x00fc, - 0x00e0, - 0x0070, - 0x0038, - 0x001c, - 0x00fc, - 0x00fc, - 0x0000, - 0x0000, - 0x0000, - 0x0000, -}, -}; diff --git a/src/mta/mta-sign.c b/src/mta/mta-sign.c deleted file mode 100644 index 180d685c..00000000 --- a/src/mta/mta-sign.c +++ /dev/null @@ -1,158 +0,0 @@ -/** \file - * Test the matrix LCD PRU firmware with a multi-hue rainbow. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "ledscape.h" - -const int width = 256; -const int height = 128; - -extern const uint16_t font[][16]; - -static int -font_write( - uint32_t * const buf, - const uint32_t color, - const int x0, - const int y0, - const char * s -) -{ - int x = x0; - int y = y0; - - while (1) - { - char c = *s++; - if (!c) - break; - - if (c == '\n') - { - x = x0; - y += 16 * width; - continue; - } - - const uint16_t * ch = font[(uint8_t) c]; - int max_width = 0; - - if (c == ' ' || c == '.') - max_width = 3; - else - for (int h = 0 ; h < 16 ; h++) - { - int width = 0; - uint16_t row = ch[h] >> 2; - while (row) - { - row >>= 1; - width++; - } - - if (width > max_width) - max_width = width; - } - - // add space after the character - max_width++; - - for (int h = 0 ; h < 16 ; h++) - { - uint16_t row = ch[h] >> 2; - for (int j = 0 ; j < max_width ; j++, row >>= 1) - { - uint32_t pixel_color = (row & 1) ? color : 0; - int ox = x + j; -/* - if (x + j >= width || x + j < 0) - continue; -*/ - if (ox >= width) - continue; - - // wrap in x - if (ox < 0) - ox += width; - - if (y + h >= height || y + h < 0) - continue; - - uint8_t * pix = (uint8_t*) &buf[(y+h)*width + ox]; - pix[0] = pixel_color >> 16; - pix[1] = pixel_color >> 8; - pix[2] = pixel_color >> 0; - } - } - - x += max_width; - } - - return x; -} - - -int -main( - int argc, - char ** argv -) -{ - ledscape_config_t * config = &ledscape_matrix_default; - if (argc > 1) - { - config = ledscape_config(argv[1]); - if (!config) - return EXIT_FAILURE; - } - - ledscape_t * const leds = ledscape_init(config, 0); - - printf("init done\n"); - time_t last_time = time(NULL); - unsigned last_i = 0; - - unsigned i = 0; - uint32_t * const p = calloc(width*height, 4); - int scroll_x = width; - - while (1) - { - font_write(p, 0x00FF00, 0, 0, "1.! NYCResistor-Atlantic Pacific"); - font_write(p, 0xFF0000, 11, 0, "!"); - font_write(p, 0x00FF00, 224, 0, "8min"); - - int end_x = font_write(p, 0xFF4000, scroll_x, 16, argc > 2 ? argv[2] : ""); - if (end_x <= 0) - scroll_x = width; - else - scroll_x--; - - ledscape_draw(leds, p); - usleep(20000); - - // wait for the previous frame to finish; - //const uint32_t response = ledscape_wait(leds); - const uint32_t response = 0; - time_t now = time(NULL); - if (now != last_time) - { - printf("%d fps. starting %d previous %"PRIx32"\n", - i - last_i, i, response); - last_i = i; - last_time = now; - } - - } - - ledscape_close(leds); - - return EXIT_SUCCESS; -} diff --git a/src/net/Makefile b/src/net/Makefile deleted file mode 100755 index 0d661e20..00000000 --- a/src/net/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -######### -# -# Build the various network receiving tools -# -# -BIN-y += matrix-udp-rx -BIN-y += matrix-tcp-rx -BIN-y += opc-rx - -matrix-udp-rx.srcs += matrix-udp-rx.c -matrix-tcp-rx.srcs += matrix-tcp-rx.c -opc-rx.srcs += opc-rx.c - -include ../../Makefile.common - diff --git a/src/net/matrix-tcp-rx.c b/src/net/matrix-tcp-rx.c deleted file mode 100644 index f0a0da30..00000000 --- a/src/net/matrix-tcp-rx.c +++ /dev/null @@ -1,351 +0,0 @@ -/** \file - * TCP image packet receiver. - * - * Based on the HackRockCity LED Display code: - * https://github.com/agwn/pyramidTransmitter/blob/master/LEDDisplay.pde - * - * Designed to render into the LED matrix. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "util.h" -#include "ledscape.h" - -static int verbose; - -static int -tcp_socket( - const int port -) -{ - const int sock = socket(AF_INET, SOCK_STREAM, 0); - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_port = htons(port), - .sin_addr.s_addr = INADDR_ANY, - }; - - if (sock < 0) - return -1; - if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr)) < 0) - return -1; - if (listen(sock, 5) , 0) - return -1; - - int yes = 1; - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) - return -1; - - return sock; -} - - -static int -wait_socket( - int fd, - int msec_timeout -) -{ - struct timeval tv = { msec_timeout / 1000, msec_timeout % 1000 }; - fd_set fds; - FD_ZERO(&fds); - FD_SET(fd, &fds); - return select(fd+1, &fds, NULL, NULL, &tv); -} - - -static ssize_t -recv_all( - const int sock, - void * const buf_out, - size_t len -) -{ - uint8_t * buf = buf_out; - size_t off = 0; - - while (off < len) - { - const ssize_t rlen = recv(sock, buf+off, len-off, 0); - if (rlen < 0) - return rlen; - if (rlen == 0) - break; - off += rlen; - } - - return off; -} - - -static struct option long_options[] = -{ - /* These options set a flag. */ - {"verbose", no_argument, 0, 1}, - {"port", required_argument, 0, 'p'}, - {"width", required_argument, 0, 'W'}, - {"height", required_argument, 0, 'H'}, - {"config", required_argument, 0, 'c'}, - {"timeout", required_argument, 0, 't'}, - {"message", required_argument, 0, 'm'}, - {"noinit", no_argument, 0, 'n'}, - {0, 0, 0, 0} -}; - - -static void usage(void) -{ - fprintf(stderr, "usage not yet written\n"); - exit(EXIT_FAILURE); -} - - -const unsigned int packets_per_frame = 2; - -int -main( - int argc, - char ** argv -) -{ - /* getopt_long stores the option index here. */ - int option_index = 0; - int port = 9999; - const char * config_file = NULL; - const char * startup_message = ""; - int timeout = 60; - unsigned width = 512; - unsigned height = 64; - int no_init = 0; - - while (1) - { - const int c = getopt_long( - argc, - argv, - "vp:c:t:W:H:m:n", - long_options, - &option_index - ); - - if (c == -1) - break; - switch (c) - { - case 'v': - verbose++; - break; - case 'n': - no_init++; - break; - case 'c': - config_file = optarg; - break; - case 't': - timeout = atoi(optarg); - break; - case 'W': - width = atoi(optarg); - break; - case 'H': - height = atoi(optarg); - break; - case 'm': - startup_message = optarg; - break; - default: - usage(); - return -1; - } - } - - const int sock = tcp_socket(port); - if (sock < 0) - die("socket port %d failed: %s\n", port, strerror(errno)); - - const size_t image_size = width * height * 3; - const size_t buf_size = (width*height*4)/packets_per_frame + 1; - - // largest possible UDP packet - uint8_t *buf = malloc(buf_size); -#if 0 - if (sizeof(buf) < image_size + 1) - die("%u x %u too large for UDP\n", width, height); -#endif - - fprintf(stderr, "%u x %u, TCP port %u\n", width, height, port); - - ledscape_config_t * config = &ledscape_matrix_default; - if (config_file) - { - config = ledscape_config(config_file); - if (!config) - return EXIT_FAILURE; - } - - if (config->type == LEDSCAPE_MATRIX) - { - config->matrix_config.width = width; - config->matrix_config.height = height; - } - - ledscape_t * const leds = ledscape_init(config, no_init); - if (!leds) - return EXIT_FAILURE; - - const unsigned report_interval = 10; - unsigned last_report = 0; - unsigned long delta_sum = 0; - unsigned frames = 0; - - uint32_t * const fb = calloc(width*height,4); - ledscape_printf(fb, width, 0xFF0000, "%s", startup_message); - ledscape_printf(fb+16*width, width, 0x00FF00, "%dx%d UDP port %d", width, height, port); - ledscape_draw(leds, fb); - - while (1) - { - int rc = wait_socket(sock, timeout*1000); - if (rc < 0) - { - // something failed - memset(fb, 0, width*height*4); - ledscape_printf(fb, width, 0xFF0000, "read failed?"); - ledscape_draw(leds, fb); - exit(EXIT_FAILURE); - } - - if (rc == 0) - { - // go into timeout mode - memset(fb, 0, width*height*4); - ledscape_printf(fb, width, 0xFF0000, "timeout"); - ledscape_draw(leds, fb); - continue; - } - - const int new_sock = accept(sock, NULL, NULL); - if (new_sock < 0) - { - perror("accept"); - continue; - } - - while (1) - { - int rc = wait_socket(new_sock, timeout*1000); - if (rc < 0) - break; - if (rc == 0) - continue; - - const size_t packet_size = 1 + 3*512*32; - const ssize_t rlen = recv_all(new_sock, buf, packet_size); - if (rlen < 0) - die("recv failed: %s\n", strerror(errno)); - if ((size_t) rlen != packet_size) - break; - - warn_once("received %zu bytes\n", rlen); - - /* - if (buf[0] == 2) - { - // image type - printf("image type: %.*s\n", - (int) rlen - 1, - &buf[1] - ); - continue; - } - - if (buf[0] != 1) - { - // What is it? - warn_once("Unknown image type '%c' (%02x)\n", - buf[0], - buf[0] - ); - continue; - } - */ - const unsigned frame_part = buf[0]; - if (frame_part != 0 && frame_part != 1) - { - printf("bad type %d\n", frame_part); - continue; - } - - if ((size_t) rlen != image_size + 1) - { - warn_once("WARNING: Received packet %zu bytes, expected %zu\n", - rlen, - image_size + 1 - ); - } - - struct timeval start_tv, stop_tv, delta_tv; - gettimeofday(&start_tv, NULL); - - const unsigned frame_num = 0; - - // copy the 3-byte values into the 4-byte framebuffer - // and turn onto the side - for (unsigned x = 0 ; x < width ; x++) // 256 - { - for (unsigned y = 0 ; y < 32 ; y++) // 64 - { - uint32_t * out = (void*) &fb[(y+32*frame_part)*width + x]; - const uint8_t * const in = &buf[1 + 3*(y*width + x)]; - uint32_t r = in[0]; - uint32_t g = in[1]; - uint32_t b = in[2]; - *out = (r << 16) | (g << 8) | (b << 0); - } - } - - // only draw after the second frame - if (frame_part == 1) - ledscape_draw(leds, fb); - - gettimeofday(&stop_tv, NULL); - timersub(&stop_tv, &start_tv, &delta_tv); - - frames++; - delta_sum += delta_tv.tv_usec; - if (stop_tv.tv_sec - last_report < report_interval) - continue; - last_report = stop_tv.tv_sec; - - const unsigned delta_avg = delta_sum / frames; - printf("%6u usec avg, max %.2f fps, actual %.2f fps (over %u frames)\n", - delta_avg, - report_interval * 1.0e6 / delta_avg, - frames * 1.0 / report_interval, - frames - ); - - frames = delta_sum = 0; - } - - // this socket was closed - fprintf(stderr, "socket closed, waiting for new conncetion\n"); - close(new_sock); - } - - return 0; -} diff --git a/src/net/matrix-udp-rx.c b/src/net/matrix-udp-rx.c deleted file mode 100644 index be73095f..00000000 --- a/src/net/matrix-udp-rx.c +++ /dev/null @@ -1,275 +0,0 @@ -/** \file - * UDP image packet receiver. - * - * Based on the HackRockCity LED Display code: - * https://github.com/agwn/pyramidTransmitter/blob/master/LEDDisplay.pde - * - * Designed to render into the LED matrix. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "util.h" -#include "ledscape.h" - -static int verbose; - -static int -udp_socket( - const int port -) -{ - const int sock = socket(AF_INET, SOCK_DGRAM, 0); - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_port = htons(port), - .sin_addr.s_addr = INADDR_ANY, - }; - - if (sock < 0) - return -1; - if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr)) < 0) - return -1; - - return sock; -} - - -static int -wait_socket( - int fd, - int msec_timeout -) -{ - struct timeval tv = { msec_timeout / 1000, msec_timeout % 1000 }; - fd_set fds; - FD_ZERO(&fds); - FD_SET(fd, &fds); - return select(fd+1, &fds, NULL, NULL, &tv); -} - - -static struct option long_options[] = -{ - /* These options set a flag. */ - {"verbose", no_argument, 0, 1}, - {"port", required_argument, 0, 'p'}, - {"width", required_argument, 0, 'W'}, - {"height", required_argument, 0, 'H'}, - {"config", required_argument, 0, 'c'}, - {"timeout", required_argument, 0, 't'}, - {"message", required_argument, 0, 'm'}, - {"noinit", no_argument, 0, 'n'}, - {0, 0, 0, 0} -}; - - -static void usage(void) -{ - fprintf(stderr, "usage not yet written\n"); - exit(EXIT_FAILURE); -} - - -int -main( - int argc, - char ** argv -) -{ - /* getopt_long stores the option index here. */ - int option_index = 0; - int port = 9999; - const char * config_file = NULL; - const char * startup_message = ""; - int timeout = 60; - unsigned width = 512; - unsigned height = 64; - int no_init = 0; - - while (1) - { - const int c = getopt_long( - argc, - argv, - "vp:c:t:W:H:m:n", - long_options, - &option_index - ); - - if (c == -1) - break; - switch (c) - { - case 'v': - verbose++; - break; - case 'n': - no_init++; - break; - case 'c': - config_file = optarg; - break; - case 't': - timeout = atoi(optarg); - break; - case 'W': - width = atoi(optarg); - break; - case 'H': - height = atoi(optarg); - if(height%2) { - die("Height must be even!\n"); - } - break; - case 'm': - startup_message = optarg; - break; - default: - usage(); - return -1; - } - } - - const int sock = udp_socket(port); - if (sock < 0) - die("socket port %d failed: %s\n", port, strerror(errno)); - - const size_t image_size = width * height * 3; - const size_t frame_size = 1 + image_size/2; - - // largest possible UDP packet - // 1 header byte + width*height/2 for a half frame - uint8_t *buf = calloc(frame_size,1); - - fprintf(stderr, "%u x %u, UDP port %u\n", width, height, port); - - ledscape_config_t * config = &ledscape_matrix_default; - - if (config_file) - { - config = ledscape_config(config_file); - if (!config) - return EXIT_FAILURE; - } - - if (config->type == LEDSCAPE_MATRIX) - { - config->matrix_config.width = width; - config->matrix_config.height = height; - } - - ledscape_t * const leds = ledscape_init(config, no_init); - if (!leds) - return EXIT_FAILURE; - - const unsigned report_interval = 10; - unsigned last_report = 0; - unsigned long delta_sum = 0; - unsigned frames = 0; - - uint32_t * const fb = calloc(width*height,4); - - ledscape_printf(fb, width, 0xFF0000, "%s", startup_message); - ledscape_printf(fb+16*width, width, 0x00FF00, "%dx%d UDP port %d", width, height, port); - ledscape_draw(leds, fb); - ledscape_draw(leds, fb); // TODO: Why do we have to do this twice? - - while (1) - { - int rc = wait_socket(sock, timeout*1000); - if (rc < 0) - { - // something failed - memset(fb, 0, width*height*4); - ledscape_printf(fb, width, 0xFF0000, "read failed?"); - ledscape_draw(leds, fb); - exit(EXIT_FAILURE); - } - - if (rc == 0) - { - // go into timeout mode - memset(fb, 0, width*height*4); - ledscape_printf(fb, width, 0xFF0000, "timeout"); - ledscape_draw(leds, fb); - continue; - } - - const ssize_t rlen = recv(sock, buf, frame_size, 0); - if (rlen < 0) - die("recv failed: %s\n", strerror(errno)); - warn_once("received %zu bytes\n", rlen); - - const unsigned frame_part = buf[0]; - if (frame_part != 0 && frame_part != 1) - { - printf("bad type %d\n", frame_part); - continue; - } - - if ((size_t) rlen != frame_size) - { - printf("WARNING: Received packet %zu bytes, expected %zu\n", - rlen, - frame_size - ); - } - - struct timeval start_tv, stop_tv, delta_tv; - gettimeofday(&start_tv, NULL); - - // copy the 3-byte values into the 4-byte framebuffer - for (unsigned x = 0 ; x < width ; x++) // 256 - { - for (unsigned y = 0 ; y < height ; y++) // 64 - { - uint32_t * out = &fb[(height*frame_part + y)*width + x]; - const uint8_t * in = &buf[1 + 3*(y*width + x)]; - - uint8_t r = in[0]; - uint8_t g = in[1]; - uint8_t b = in[2]; - *out = (r << 16) | (g << 8) | (b << 0); - } - } - - // only draw after the second frame - if (frame_part == 1) - ledscape_draw(leds, fb); - - gettimeofday(&stop_tv, NULL); - timersub(&stop_tv, &start_tv, &delta_tv); - - frames++; - delta_sum += delta_tv.tv_usec; - if (stop_tv.tv_sec - last_report < report_interval) - continue; - last_report = stop_tv.tv_sec; - - const unsigned delta_avg = delta_sum / frames; - printf("%6u usec avg, max %.2f fps, actual %.2f fps (over %u frames)\n", - delta_avg, - report_interval * 1.0e6 / delta_avg, - frames * 1.0 / report_interval, - frames - ); - - frames = delta_sum = 0; - } - - return 0; -} diff --git a/src/net/opc-rx.c b/src/net/opc-rx.c deleted file mode 100644 index 5896003b..00000000 --- a/src/net/opc-rx.c +++ /dev/null @@ -1,158 +0,0 @@ -/** \file - * OPC image packet receiver. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "util.h" -#include "ledscape.h" - -typedef struct -{ - uint8_t channel; - uint8_t command; - uint8_t len_hi; - uint8_t len_lo; -} opc_cmd_t; - -static int -tcp_socket( - const int port -) -{ - const int sock = socket(AF_INET, SOCK_STREAM, 0); - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_port = htons(port), - .sin_addr.s_addr = INADDR_ANY, - }; - - if (sock < 0) - return -1; - if (bind(sock, (const struct sockaddr*) &addr, sizeof(addr)) < 0) - return -1; - if (listen(sock, 5) == -1) - return -1; - - return sock; -} - - -int -main( - int argc, - char ** argv -) -{ - const int port = 7890; - const int sock = tcp_socket(port); - if (sock < 0) - die("socket port %d failed: %s\n", port, strerror(errno)); - - const unsigned width = 32; - const unsigned height = 16; - const size_t image_size = width * height * 3; - - // largest possible UDP packet - uint8_t buf[65536]; - if (sizeof(buf) < image_size + 1) - die("%u x %u too large for UDP\n", width, height); - - fprintf(stderr, "%u x %u, TCP port %u\n", width, height, port); - - ledscape_config_t * config = &ledscape_matrix_default; - ledscape_t * const leds = ledscape_init(config, 0); - - const unsigned report_interval = 10; - unsigned last_report = 0; - unsigned long delta_sum = 0; - unsigned frames = 0; - - uint32_t * const fb = calloc(width*height,4); - - int fd; - while ((fd = accept(sock, NULL, NULL)) >= 0) - { - while(1) - { - opc_cmd_t cmd; - ssize_t rlen = read(fd, &cmd, sizeof(cmd)); - if (rlen < 0) - die("recv failed: %s\n", strerror(errno)); - if (rlen == 0) - { - close(fd); - break; - } - - const size_t cmd_len = cmd.len_hi << 8 | cmd.len_lo; - warn("received %zu bytes: %d %zu\n", rlen, cmd.command, cmd_len); - - size_t offset = 0; - while (offset < cmd_len) - { - rlen = read(fd, buf + offset, cmd_len - offset); - if (rlen < 0) - die("recv failed: %s\n", strerror(errno)); - if (rlen == 0) - break; - offset += rlen; - } - - if (cmd.command != 0) - continue; - - struct timeval start_tv, stop_tv, delta_tv; - gettimeofday(&start_tv, NULL); - - const unsigned frame_num = 0; - - for (unsigned y = 0 ; y < height ; y++) - { - for (unsigned x = 0 ; x < width ; x++) - { - uint8_t * const out = (void*) &fb[x + y*width]; - const uint8_t * const in = &buf[3*(x + y*width)]; - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - } - } - - ledscape_draw(leds, fb); - - gettimeofday(&stop_tv, NULL); - timersub(&stop_tv, &start_tv, &delta_tv); - - frames++; - delta_sum += delta_tv.tv_usec; - if (stop_tv.tv_sec - last_report < report_interval) - continue; - last_report = stop_tv.tv_sec; - - const unsigned delta_avg = delta_sum / frames; - printf("%6u usec avg, max %.2f fps, actual %.2f fps (over %u frames)\n", - delta_avg, - report_interval * 1.0e6 / delta_avg, - frames * 1.0 / report_interval, - frames - ); - - frames = delta_sum = 0; - } - } - - return 0; -} diff --git a/src/perlin/Makefile b/src/perlin/Makefile deleted file mode 100644 index 24fc037f..00000000 --- a/src/perlin/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -#============================================================================================== -# LED Matrix Animated Pattern Generator -# Copyright 2014 by Glen Akins. -# All rights reserved. -# -# Set editor width to 96 and tab stop to 4. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#============================================================================================== - -BIN-y += perlin -perlin.srcs += \ - perlin-ledscape.cpp \ - pf2.cpp \ - pattern.cpp \ - -include ../../Makefile.common diff --git a/src/perlin/gammalut.h b/src/perlin/gammalut.h deleted file mode 100644 index 79a6346a..00000000 --- a/src/perlin/gammalut.h +++ /dev/null @@ -1,46 +0,0 @@ -//============================================================================================= -// LED Matrix Animated Pattern Generator -// Adafruit LED Panel Gamma Lookup Table -// Modified by Glen Akins, Feb 2014 -// Table renamed to prevent conflicts with names of functions in math.h. -//============================================================================================= - -#ifndef __gammalut_h_ -#define __gammalut_h_ - -static const uint8_t gammaLut[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01, - 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, - 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, - 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, - 0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02, - 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, - 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, - 0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x03, - 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03, - 0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x04, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04, - 0x04,0x04,0x04,0x04,0x04,0x04,0x05,0x05, - 0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05, - 0x05,0x05,0x05,0x06,0x06,0x06,0x06,0x06, - 0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x07, - 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, - 0x07,0x07,0x08,0x08,0x08,0x08,0x08,0x08, - 0x08,0x08,0x08,0x08,0x09,0x09,0x09,0x09, - 0x09,0x09,0x09,0x09,0x09,0x0a,0x0a,0x0a, - 0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0b,0x0b, - 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0c,0x0c, - 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0d,0x0d, - 0x0d,0x0d,0x0d,0x0d,0x0d,0x0e,0x0e,0x0e, - 0x0e,0x0e,0x0e,0x0e,0x0f,0x0f,0x0f,0x0f -}; - -#endif diff --git a/src/perlin/globals.h b/src/perlin/globals.h deleted file mode 100644 index df6a574b..00000000 --- a/src/perlin/globals.h +++ /dev/null @@ -1,30 +0,0 @@ -//============================================================================================= -// LED Matrix Animated Pattern Generator -// Copyright 2014 by Glen Akins. -// All rights reserved. -// -// Set editor width to 96 and tab stop to 4. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -//============================================================================================= - -#ifndef __globals_h_ -#define __globals_h_ - -#define DISPLAY_WIDTH 512 -#define DISPLAY_HEIGHT 64 - -extern uint32_t gLevels[DISPLAY_HEIGHT][DISPLAY_WIDTH]; - -#endif diff --git a/src/perlin/knobs/knobs.ino b/src/perlin/knobs/knobs.ino deleted file mode 100644 index 280fcaf0..00000000 --- a/src/perlin/knobs/knobs.ino +++ /dev/null @@ -1,32 +0,0 @@ -/** \file - * Teensy 2.0 firmware to read four analog knobs and print - * their values periodically. - */ - -#define LED_PIN 11 - -void setup(void) -{ - Serial.begin(9600); - pinMode(LED_PIN, OUTPUT); -} - -void loop(void) -{ - digitalWrite(LED_PIN, HIGH); - uint16_t p1 = analogRead(A3); - uint16_t p2 = analogRead(A2); - uint16_t p3 = analogRead(A5); - uint16_t p4 = analogRead(A4); - digitalWrite(LED_PIN, LOW); - - Serial.print(p1); - Serial.print(' '); - Serial.print(p2); - Serial.print(' '); - Serial.print(p3); - Serial.print(' '); - Serial.println(p4); - - delay(100); -} diff --git a/src/perlin/pattern.cpp b/src/perlin/pattern.cpp deleted file mode 100644 index 935ecff8..00000000 --- a/src/perlin/pattern.cpp +++ /dev/null @@ -1,109 +0,0 @@ -//============================================================================================= -// LED Matrix Animated Pattern Generator -// Copyright 2014 by Glen Akins. -// All rights reserved. -// -// Set editor width to 96 and tab stop to 4. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -//============================================================================================= - -#include -#include -#include - -#include "globals.h" -#include "gammalut.h" -#include "pattern.h" - -#define MAKE_COLOR(r,g,b) \ - (((r) << 16) | ((g) << 8) | ((b) << 0)) - -//--------------------------------------------------------------------------------------------- -// convert a hue from 0 to 95 to its 12-bit RGB color -// -// hue: 0 = red, 32 = blue, 64 = green -// - -uint32_t Pattern::translateHue (int32_t hue) -{ - uint8_t hi, lo; - uint32_t r, g, b; - - hi = hue >> 4; - lo = ((hue & 0xf) << 4) | (hue & 0xf); - -#if 1 - switch (hi) { - case 0: r = 0xff; g = 0; b = lo; break; - case 1: r = 0xff-lo, g = 0, b = 0xff; break; - case 2: r = 0, g = lo, b = 0xff; break; - case 3: r = 0, g = 0xff, b = 0xff-lo; break; - case 4: r = lo, g = 0xff, b = 0; break; - case 5: r = 0xff, g = 0xff-lo, b = 0; break; - } -//printf("hue=%d=%d,%d: %d,%d,%d\n", hue, hi, lo, r, g, b); - //r = gammaLut[r] << 3; - //g = gammaLut[g] << 3; - //b = gammaLut[b] << 3; - r /= 2; - b /= 2; - g /= 2; -#else - b = hue; - r = 0; - g = 0; -#endif - - - uint32_t color = MAKE_COLOR (r,g,b); - //printf("color=%08x\n", color); -return color; -} - - -//--------------------------------------------------------------------------------------------- -// convert a hue from 0 to 95 and a brightnewss from 0 to 1.0 to its 12-bit RGB color -// -// hue: 0 = red, 32 = blue, 64 = green -// value: 0 = off, 1.0 = 100% -// - -uint32_t Pattern::translateHueValue (int32_t hue, float value) -{ - uint8_t hi, lo; - uint8_t r, g, b; - - hi = hue >> 4; - lo = ((hue & 0xf) << 4) | (hue & 0xf); - - switch (hi) { - case 0: r = 0xff; g = 0; b = lo; break; - case 1: r = 0xff-lo, g = 0, b = 0xff; break; - case 2: r = 0, g = lo, b = 0xff; break; - case 3: r = 0, g = 0xff, b = 0xff-lo; break; - case 4: r = lo, g = 0xff, b = 0; break; - case 5: r = 0xff, g = 0xff-lo, b = 0; break; - } - - r = ((float)r + 0.5) * value; - g = ((float)g + 0.5) * value; - b = ((float)b + 0.5) * value; - - //r = gammaLut[r] << 4; - //g = gammaLut[g] << 4; - //b = gammaLut[b] << 4; - - return MAKE_COLOR (r,g,b); -} diff --git a/src/perlin/pattern.h b/src/perlin/pattern.h deleted file mode 100644 index 522ba44a..00000000 --- a/src/perlin/pattern.h +++ /dev/null @@ -1,59 +0,0 @@ -//============================================================================================= -// LED Matrix Animated Pattern Generator -// Copyright 2014 by Glen Akins. -// All rights reserved. -// -// Set editor width to 96 and tab stop to 4. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -//============================================================================================= - -#ifndef __pattern_h_ -#define __pattern_h_ - -extern const uint8_t gammaLut[]; - -class Pattern -{ - public: - - // constructor - Pattern (const int32_t width, const int32_t height) : - m_width(width), m_height(height) { } - - // destructor - ~Pattern (void) { } - - // reset to first frame in animation - virtual void init (void) = 0; - - // calculate next frame in the animation - virtual bool next (void) = 0; - - // get width and height - void getDimensions (int32_t &width, int32_t &height) { - width = m_width; height = m_height; - } - - uint32_t translateHue (int32_t hue); - uint32_t translateHueValue (int32_t hue, float value); - - protected: - const int32_t m_width; - const int32_t m_height; - - private: -}; - -#endif diff --git a/src/perlin/perlin-ledscape.cpp b/src/perlin/perlin-ledscape.cpp deleted file mode 100644 index 312c0dfd..00000000 --- a/src/perlin/perlin-ledscape.cpp +++ /dev/null @@ -1,188 +0,0 @@ -//============================================================================================= -// LED Matrix Animated Pattern Generator -// Copyright 2014 by Glen Akins. -// Updated to work with LEDscape by Trammell Hudson -// All rights reserved. -// -// Set editor width to 96 and tab stop to 4. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -//============================================================================================= - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; - -#include "globals.h" -#include "pattern.h" -#include "pf2.h" -#include "ledscape.h" - -static ledscape_t * leds; - -// global levels to write to FPGA -uint32_t gLevels[DISPLAY_HEIGHT][DISPLAY_WIDTH]; - -// global object to create animated pattern -Perlin *gPattern = NULL; - -// prototypes -void Quit (int sig); -void BlankDisplay (void); -void WriteLevels (void); -void timer_handler (int signum); - - -static void * -read_thread( - void * arg -) -{ - char line[128]; - float new_size; - printf("read thread waiting\n"); - int old_p0 = -1; - int old_p1 = -1; - int old_p2 = -1; - int old_p3 = -1; - - while (1) - { - if (fgets(line, sizeof(line), stdin) == NULL) - break; - //printf("read '%s'\n", line); - int p0, p1, p2, p3; - int rc = sscanf(line, "%d %d %d %d", &p0, p1, p2, p3); - if (rc != 4) - { - printf("scanf failed: %d: '%s'\n", rc, line); - continue; - } - - if (p0 != old_p0) - gPattern->setScale(p0 / 1024.0); - old_p0 = p0; - } - - fprintf(stderr, "read thread exiting\n"); - return NULL; -} - -int main (int argc, char *argv[]) -{ - struct sigaction sa; - struct itimerval timer; - - // trap ctrl-c to call quit function - signal (SIGINT, Quit); - - ledscape_config_t * config = &ledscape_matrix_default; - if (argc > 1) - { - config = ledscape_config(argv[1]); - if (!config) - return EXIT_FAILURE; - } - - float hue_options = 0.005; - if (argc > 2) - hue_options = atof(argv[2]); - - config->matrix_config.width = DISPLAY_WIDTH; - config->matrix_config.height = DISPLAY_HEIGHT; - leds = ledscape_init(config, 0); - - ledscape_printf((uint32_t*)(uintptr_t)gLevels, DISPLAY_WIDTH, 0xFF0000, "Perlin noise by Glen Akins"); - ledscape_draw(leds, gLevels); - - // initialize levels to all off - BlankDisplay (); - - // create a new pattern object -- perlin noise, mode 2 long repeating - gPattern = new Perlin( - DISPLAY_WIDTH, - DISPLAY_HEIGHT, - 2, // mode - 1.0/64.0, // size of blobs: smaller value == larger blob - 1/64.0, // speed - 256.0, - hue_options - ); - - // spin off a thread to read size, speed and other settings - pthread_t read_id; - if (pthread_create(&read_id, NULL, read_thread, NULL) < 0) - return EXIT_FAILURE; - - // create a new pattern object -- perlin noise, mode 1 short repeat - // gPattern = new Perlin (DISPLAY_WIDTH, DISPLAY_HEIGHT, 1, 8.0/64.0, 0.0125, 1.0, 0.2); - - // reset to first frame - gPattern->init (); - - while (1) { - WriteLevels (); - - // calculate next frame in animation - gPattern->next (); - usleep(1000); - } - - // delete pattern object - delete gPattern; - - return 0; -} - - -void Quit (int sig) -{ - exit (-1); -} - - -void BlankDisplay (void) -{ - // initialize levels to all off - for (int32_t row = 0; row < DISPLAY_HEIGHT; row++) { - for (int32_t col = 0; col < DISPLAY_WIDTH; col++) { - gLevels[row][col] = 0x0000; - } - } - - // send levels to board - WriteLevels (); -} - - -void WriteLevels (void) -{ - ledscape_draw(leds, gLevels); -} - diff --git a/src/perlin/pf2.cpp b/src/perlin/pf2.cpp deleted file mode 100644 index 7bdb2e6c..00000000 --- a/src/perlin/pf2.cpp +++ /dev/null @@ -1,339 +0,0 @@ -//============================================================================================= -// LED Matrix Animated Pattern Generator -// Copyright 2014 by Glen Akins. -// All rights reserved. -// -// Set editor width to 96 and tab stop to 4. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Major inspiration for the use of Perlin noise to generate pseudorandom RGB patterns comes -// from the TI RGB LED coffee table project and the following resources: -// -// TI RGB LED Coffee Table: -// -// http://e2e.ti.com/group/microcontrollerprojects/m/msp430microcontrollerprojects/447779.aspx -// https://github.com/bear24rw/rgb_table/tree/master/code/table_drivers/pytable -// -// Casey Duncan's Python C Noise Library: -// -// https://github.com/caseman/noise -// -// Ken Perlin's Original Source Code: -// -// http://www.mrl.nyu.edu/~perlin/doc/oscar.html -// -// Excellent explanation of Perlin noise and seamless looping and tiling here: -// -// http://webstaff.itn.liu.se/~stegu/TNM022-2005/perlinnoiselinks/perlin-noise-math-faq.html -// -//============================================================================================= - -#include -#include -#include -#include -#include - -#include "globals.h" -#include "pattern.h" -#include "pf2.h" - - -//--------------------------------------------------------------------------------------------- -// constructors -// - -Perlin::Perlin -( - const int32_t width, const int32_t height, const int32_t mode -) : - Pattern (width, height), - m_mode (mode), m_xy_scale(8.0/64.0*256.0), - m_z_step(0.0125), m_z_depth(512.0), - m_hue_options(0.005) -{ -} - - -Perlin::Perlin ( - const int32_t width, const int32_t height, - const int32_t mode, const float xy_scale, - const float z_step, const float z_depth, - const float hue_options -) : - Pattern (width, height), - m_mode (mode), m_xy_scale(xy_scale*256.0), - m_z_step(z_step), m_z_depth(z_depth), - m_hue_options(hue_options) -{ -} - - -//--------------------------------------------------------------------------------------------- -// destructor -// - -Perlin::~Perlin (void) -{ -} - - -//--------------------------------------------------------------------------------------------- -// init -- reset to first frame in animation -// - -void Perlin::init (void) -{ - // reset to z=0 plane - m_z_state = 0.0; - - // reset to red, only used for modes two and three - m_hue_state = 0.0; - - // reset normalization min and max - m_min = 1; - m_max = 1; -} - - -//--------------------------------------------------------------------------------------------- -// next -- calculate next frame in animation -// - -bool Perlin::next (void) -{ - int32_t x, y; - uint16_t sx, sy; - int32_t n1, n2; - float n; - int32_t hue; - - int16_t sz1 = (float)m_z_state * 256.0; - int16_t sz2 = (float)(m_z_state - m_z_depth) * 256.0; - - // row - for (y = 0; y < m_height; y++) { - - // scale y - sy = y * m_xy_scale; - - // column - for (x = 0; x < m_width; x++) { - - // scale x - sx = x * m_xy_scale; - - // generate noise at plane z_state - n1 = this->noise (sx, sy, sz1); - - // generate noise at plane z_state - z_depth - n2 = this->noise (sx, sy, sz2); - - // combine noises to make a seamless transition from plane - // at z = z_depth back to plane at z = 0 - n = ((m_z_depth - m_z_state) * (float)n1 + (m_z_state) * (float)n2) / m_z_depth; - - // normalize combined noises to a number between 0 and 1 - if (n > m_max) m_max = n; - if (n < m_min) m_min = n; - n = n + fabs (m_min); // make noise a positive value - n = n / (m_max + fabs (m_min)); // scale noise to between 0 and 1 - - // set hue and/or brightness based on mode - switch (m_mode) { - - // base hue fixed, varies based on noise - case 1: - hue = (m_hue_options + n)*96.0 + 0.5; - hue = hue % 96; - gLevels[y][x] = this->translateHue (hue); - break; - - // hue rotates at constant velocity, varies based on noise - case 2: - hue = (m_hue_state + n)*96.0 + 0.5; - hue = hue % 96; - gLevels[y][x] = this->translateHue (hue); - break; - - // hue rotates at constant velocity, brightness varies based on noise - case 3: - hue = (m_hue_state)*96.0 + 0.5; - hue = hue % 96; - gLevels[y][x] = this->translateHueValue (hue, n); - break; - - // undefined mode, blank display - default: - gLevels[x][y] = 0; - break; - - } - } - } - - // update state variables - m_z_state = fmod (m_z_state + m_z_step, m_z_depth); - m_hue_state = fmod (m_hue_state + m_hue_options, 1.0); - - return true; -} - - -//--------------------------------------------------------------------------------------------- -// noise -// - -#define lerp1(t, a, b) (((a)<<12) + (t) * ((b) - (a))) - -static const int8_t GRAD3[16][3] = { - {1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0}, - {1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1}, - {0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}, - {1,0,-1},{-1,0,-1},{0,-1,1},{0,1,1}}; - -static const uint8_t PERM[512] = { - 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, - 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, - 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, - 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, - 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, - 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, - 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, - 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, - 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, - 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, - 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, - 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, - 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, - 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, - 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, - 141, 128, 195, 78, 66, 215, 61, 156, 180, 151, 160, 137, 91, 90, 15, 131, - 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, - 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, - 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, - 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, - 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, - 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, - 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, - 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, - 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, - 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, - 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, - 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, - 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, - 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, - 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, - 180}; - -static const uint16_t easing_function_lut[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 3, 4, 6, 7, - 9, 10, 12, 14, 17, 19, 22, 25, 29, 32, 36, 40, 45, 49, 54, 60, - 65, 71, 77, 84, 91, 98, 105, 113, 121, 130, 139, 148, 158, 167, 178, 188, - 199, 211, 222, 234, 247, 259, 273, 286, 300, 314, 329, 344, 359, 374, 390, 407, - 424, 441, 458, 476, 494, 512, 531, 550, 570, 589, 609, 630, 651, 672, 693, 715, - 737, 759, 782, 805, 828, 851, 875, 899, 923, 948, 973, 998, 1023, 1049, 1074, 1100, - 1127, 1153, 1180, 1207, 1234, 1261, 1289, 1316, 1344, 1372, 1400, 1429, 1457, 1486, 1515, - 1543, 1572, 1602, 1631, 1660, 1690, 1719, 1749, 1778, 1808, 1838, 1868, 1898, 1928, 1958, - 1988, 2018, 2048, 2077, 2107, 2137, 2167, 2197, 2227, 2257, 2287, 2317, 2346, 2376, 2405, - 2435, 2464, 2493, 2523, 2552, 2580, 2609, 2638, 2666, 2695, 2723, 2751, 2779, 2806, 2834, - 2861, 2888, 2915, 2942, 2968, 2995, 3021, 3046, 3072, 3097, 3122, 3147, 3172, 3196, 3220, - 3244, 3267, 3290, 3313, 3336, 3358, 3380, 3402, 3423, 3444, 3465, 3486, 3506, 3525, 3545, - 3564, 3583, 3601, 3619, 3637, 3654, 3672, 3688, 3705, 3721, 3736, 3751, 3766, 3781, 3795, - 3809, 3822, 3836, 3848, 3861, 3873, 3884, 3896, 3907, 3917, 3928, 3937, 3947, 3956, 3965, - 3974, 3982, 3990, 3997, 4004, 4011, 4018, 4024, 4030, 4035, 4041, 4046, 4050, 4055, 4059, - 4063, 4066, 4070, 4073, 4076, 4078, 4081, 4083, 4085, 4086, 4088, 4089, 4091, 4092, 4092, - 4093, 4094, 4094, 4095, 4095, 4095, 4095, 4095, 4095, 4095 -}; - -static inline int16_t grad3(const uint8_t h, const int16_t x, const int16_t y, const int16_t z) -{ - return x * GRAD3[h][0] + y * GRAD3[h][1] + z * GRAD3[h][2]; -} - -int32_t Perlin::noise (uint16_t x, uint16_t y, uint16_t z) -{ - uint8_t i0, j0, k0; // integer part of (x, y, z) - uint8_t i1, j1, k1; // integer part plus one of (x, y, z) - uint8_t xx, yy, zz; // fractional part of (x, y, z) - uint16_t fx, fy, fz; // easing function result, add 4 LS bits - - // drop fractional part of each input - i0 = x >> 8; - j0 = y >> 8; - k0 = z >> 8; - - // integer part plus one, wrapped between 0x00 and 0xff - i1 = i0 + 1; - j1 = j0 + 1; - k1 = k0 + 1; - - // fractional part of each input - xx = x & 0xff; - yy = y & 0xff; - zz = z & 0xff; - - // apply easing function - fx = easing_function_lut[xx]; - fy = easing_function_lut[yy]; - fz = easing_function_lut[zz]; - - uint8_t A, AA, AB, B, BA, BB; - uint8_t CA, CB, CC, CD, CE, CF, CG, CH; - - // apply permutation functions - A = PERM[i0]; - AA = PERM[A + j0]; - AB = PERM[A + j1]; - B = PERM[i1]; - BA = PERM[B + j0]; - BB = PERM[B + j1]; - CA = PERM[AA + k0] & 0xf; - CB = PERM[BA + k0] & 0xf; - CC = PERM[AB + k0] & 0xf; - CD = PERM[BB + k0] & 0xf; - CE = PERM[AA + k1] & 0xf; - CF = PERM[BA + k1] & 0xf; - CG = PERM[AB + k1] & 0xf; - CH = PERM[BB + k1] & 0xf; - - // subtract 1.0 from xx, yy, zz - int16_t xxm1 = xx - 256; - int16_t yym1 = yy - 256; - int16_t zzm1 = zz - 256; - - // result is -2 to exactly +2 - int16_t g1 = grad3 (CA, xx, yy, zz ); - int16_t g2 = grad3 (CB, xxm1, yy, zz ); - int16_t g3 = grad3 (CC, xx, yym1, zz ); - int16_t g4 = grad3 (CD, xxm1, yym1, zz ); - int16_t g5 = grad3 (CE, xx, yy, zzm1); - int16_t g6 = grad3 (CF, xxm1, yy, zzm1); - int16_t g7 = grad3 (CG, xx, yym1, zzm1); - int16_t g8 = grad3 (CH, xxm1, yym1, zzm1); - - // linear interpolations - int32_t l1 = lerp1(fx, g1, g2) >> 6; - int32_t l2 = lerp1(fx, g3, g4) >> 6; - int32_t l3 = lerp1(fx, g5, g6) >> 6; - int32_t l4 = lerp1(fx, g7, g8) >> 6; - - int32_t l5 = lerp1(fy, l1, l2) >> 12; - int32_t l6 = lerp1(fy, l3, l4) >> 12; - - int32_t l7 = lerp1(fz, l5, l6) >> 12; - - return l7; -} diff --git a/src/perlin/pf2.h b/src/perlin/pf2.h deleted file mode 100644 index d83c8b4a..00000000 --- a/src/perlin/pf2.h +++ /dev/null @@ -1,135 +0,0 @@ -//============================================================================================= -// LED Matrix Animated Pattern Generator -// Copyright 2014 by Glen Akins. -// All rights reserved. -// -// Set editor width to 96 and tab stop to 4. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Major inspiration for the use of Perlin noise to generate pseudorandom RGB patterns comes -// from the TI RGB LED coffee table project and the following resources: -// -// TI RGB LED Coffee Table: -// -// http://e2e.ti.com/group/microcontrollerprojects/m/msp430microcontrollerprojects/447779.aspx -// https://github.com/bear24rw/rgb_table/tree/master/code/table_drivers/pytable -// -// Casey Duncan's Python C Noise Library: -// -// https://github.com/caseman/noise -// -// Ken Perlin's Original Source Code: -// -// http://www.mrl.nyu.edu/~perlin/doc/oscar.html -// -// Excellent explanation of Perlin noise and seamless looping and tiling here: -// -// http://webstaff.itn.liu.se/~stegu/TNM022-2005/perlinnoiselinks/perlin-noise-math-faq.html -// -//============================================================================================= - -#ifndef __pf2_h_ -#define __pf2_h_ - -class Perlin : public Pattern -{ - public: - - // constructor - Perlin (const int32_t width, const int32_t height, int32_t mode); - - // constructor - // m_hue_option is hue offset from 0.0 to 1.0 for mode 1, hue step for modes 2 and 3 - Perlin (const int32_t width, const int32_t height, - const int32_t mode, const float xy_scale, - const float z_step, const float z_depth, const float hue_options); - - // destructor - ~Perlin (void); - - // reset to first frame in animation - void init (void); - - // calculate next frame in the animation - bool next (void); - - // get / set scale - float getScale (void) { - return m_xy_scale / 256.0; - } - void setScale (float xy_scale) { - m_xy_scale = xy_scale * 256.0; - } - - // get / set z step - float getZStep (void) { - return m_z_step; - } - void setZStep (float z_step) { - m_z_step = z_step; - } - - // get / set z depth - float getZDepth (void) { - return m_z_depth; - } - void setZDepth (float z_depth) { - m_z_depth = z_depth; - m_z_state = 0; - } - - // get / set hue options - float getHueOptions (void) { - return m_hue_options; - } - void setHueOptions (float hue_options) { - m_hue_options = hue_options; - } - - private: - - // 3d perlin noise function - int32_t noise (uint16_t x, uint16_t y, uint16_t z); - - // mode: - // 1 = fixed background hue - // 2 = hue rotates and varies with noise - // 3 = hue rotates, noise varies brightness - const int32_t m_mode; - - // x and y scale of noise - int32_t m_xy_scale; - - // step in the z direction between displayed x-y planes - float m_z_step; - - // depth in the z direction before the pattern repeats - float m_z_depth; - - // background hue for mode 1, from 0.0 to 1.0 - // hue step size for modes 2 and 3 - float m_hue_options; - - // current z coordinate, mod z depth - float m_z_state; - - // current hue, mod 1.0 - float m_hue_state; - - // current minimum and maximum noise values for normalization - float m_min, m_max; -}; - -#endif From 22c4391ae66856091ef756a25d46408e262f208e Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Sun, 29 Mar 2015 22:02:26 -0700 Subject: [PATCH 328/332] Invaders have scores when shot. Renamed some things. Updated graphics Created menu system --- src/ledgames/Makefile | 11 +- src/ledgames/black.c | 44 +++--- src/ledgames/bricks.cc | 31 +++-- src/ledgames/invader_sprite.cc | 22 +-- src/ledgames/invader_sprite.hh | 7 +- src/ledgames/invaders.cc | 4 +- src/ledgames/menu.cc | 199 +++++++++++++++++++++++++++ src/ledgames/{pong.cc => paddles.cc} | 29 ++-- src/ledgames/rsrc/Invaders.png | Bin 2087 -> 2085 bytes src/ledgames/rsrc/Makefile | 3 +- src/ledgames/rsrc/Menus.png | Bin 0 -> 2187 bytes src/script/Makefile | 3 +- src/script/run-ledscape | 2 +- src/script/run-menu | 24 ++++ 14 files changed, 307 insertions(+), 72 deletions(-) create mode 100644 src/ledgames/menu.cc rename src/ledgames/{pong.cc => paddles.cc} (96%) create mode 100644 src/ledgames/rsrc/Menus.png create mode 100755 src/script/run-menu diff --git a/src/ledgames/Makefile b/src/ledgames/Makefile index 3a732ab6..9e0e9c05 100755 --- a/src/ledgames/Makefile +++ b/src/ledgames/Makefile @@ -3,18 +3,19 @@ # Build the various demos # # -BIN-y += breakout +BIN-y += bricks BIN-y += black BIN-y += white -BIN-y += pong +BIN-y += paddles BIN-y += invaders +BIN-y += menu -robin-hood-test.srcs += robin-hood-test.c -breakout.srcs += bricks.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_sprite.cc +bricks.srcs += bricks.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_sprite.cc black.srcs += black.c white.srcs += white.c -pong.srcs += pong.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_sprite.cc +paddles.srcs += paddles.cc gpio_pin.cc controls.cc screen.cc sprite.cc ball_sprite.cc invaders.srcs += invaders.cc gpio_pin.cc controls.cc screen.cc sprite.cc invader_sprite.cc ship_sprite.cc png.cc +menu.srcs += menu.cc gpio_pin.cc controls.cc screen.cc sprite.cc png.cc include ../../Makefile.common diff --git a/src/ledgames/black.c b/src/ledgames/black.c index fe9adf6a..32546851 100644 --- a/src/ledgames/black.c +++ b/src/ledgames/black.c @@ -1,6 +1,6 @@ /** \file - * Test the matrix LCD PRU firmware with a multi-hue rainbow. - */ +* Test the matrix LCD PRU firmware with a multi-hue rainbow. +*/ #include #include #include @@ -25,10 +25,10 @@ void render_game(uint32_t *pixels) { } int -main( - int argc, - const char ** argv -) + main( + int argc, +const char ** argv + ) { int width = 64; int height = 64; @@ -56,26 +56,26 @@ main( unsigned i = 0; uint32_t * const p = calloc(width*height,4); - render_game(p); + render_game(p); - i++; - ledscape_draw(leds, p); + i++; + ledscape_draw(leds, p); - usleep(20000); - - // wait for the previous frame to finish; - //const uint32_t response = ledscape_wait(leds); - const uint32_t response = 0; - time_t now = time(NULL); - if (now != last_time) - { - printf("%d fps. starting %d previous %"PRIx32"\n", - i - last_i, i, response); - last_i = i; - last_time = now; - } + usleep(20000); + // wait for the previous frame to finish; + //const uint32_t response = ledscape_wait(leds); + const uint32_t response = 0; + time_t now = time(NULL); + if (now != last_time) + { + printf("%d fps. starting %d previous %"PRIx32"\n", + i - last_i, i, response); + last_i = i; + last_time = now; + } + printf("init done\n"); ledscape_close(leds); return EXIT_SUCCESS; diff --git a/src/ledgames/bricks.cc b/src/ledgames/bricks.cc index d9a3ff8a..20a79ac9 100644 --- a/src/ledgames/bricks.cc +++ b/src/ledgames/bricks.cc @@ -168,9 +168,9 @@ void render_game(Screen *screen) { screen->draw_end(); player_controls[current_player]->refresh_status(); + player_controls[2]->refresh_status(); if (game_state == game_state_t::Attract) { - player_controls[2]->refresh_status(); if (player_controls[2]->is_pressed(button_a)) { reset_game(1); } else if (player_controls[2]->is_pressed(button_b)) { @@ -261,7 +261,7 @@ static void init_sdl(void) { exit(1); } - startup_bong = Mix_LoadWAV("/root/startup.wav"); + startup_bong = Mix_LoadWAV("bin/startup.wav"); if (startup_bong == NULL) { fprintf(stderr, "Unable to load startup.wav: %s\n", Mix_GetError()); exit(1); @@ -308,21 +308,24 @@ main( init_sdl(); - wall_blip = Mix_LoadWAV("/root/blip1.wav"); - paddle_blip = Mix_LoadWAV("/root/blip2.wav"); - block_blip[0] = Mix_LoadWAV("/root/blip3.wav"); - block_blip[1] = Mix_LoadWAV("/root/blip4.wav"); - block_blip[2] = Mix_LoadWAV("/root/blip5.wav"); + wall_blip = Mix_LoadWAV("bin/blip1.wav"); + paddle_blip = Mix_LoadWAV("bin/blip2.wav"); + block_blip[0] = Mix_LoadWAV("bin/blip3.wav"); + block_blip[1] = Mix_LoadWAV("bin/blip4.wav"); + block_blip[2] = Mix_LoadWAV("bin/blip5.wav"); - while (1) - { - render_game(screen); - - usleep(20000); +try { + while (1) + { + render_game(screen); - } + usleep(20000); - ledscape_close(leds); + } +} +catch (control_exit_exception* ex) { + delete screen; +} return EXIT_SUCCESS; } diff --git a/src/ledgames/invader_sprite.cc b/src/ledgames/invader_sprite.cc index 1ede0d8d..d19ea0c8 100644 --- a/src/ledgames/invader_sprite.cc +++ b/src/ledgames/invader_sprite.cc @@ -1,22 +1,23 @@ #include "invader_sprite.hh" -invader_sprite_t::invader_sprite_t() : +invader_sprite_t::invader_sprite_t(uint32_t score) : sprite_t(), -frames_in_anim(0) +frames_in_anim_(0), +score_(score) { } void invader_sprite_t::draw_onto(Screen *screen) { if (frame_ == 2) { - frames_in_anim++; - if (frames_in_anim > 3) { - frames_in_anim = 0; + frames_in_anim_++; + if (frames_in_anim_ > 3) { + frames_in_anim_ = 0; frame_ = 3; } } else if (frame_ == 3) { - frames_in_anim++; - if (frames_in_anim > 3) { - frames_in_anim = 0; + frames_in_anim_++; + if (frames_in_anim_ > 3) { + frames_in_anim_ = 0; set_active(false); } } @@ -31,7 +32,8 @@ void invader_sprite_t::move_sprite(void) { } } -void invader_sprite_t::destroy_sprite(void) { +uint32_t invader_sprite_t::destroy_sprite(void) { frame_ = 2; - frames_in_anim = 0; + frames_in_anim_ = 0; + return score_; } \ No newline at end of file diff --git a/src/ledgames/invader_sprite.hh b/src/ledgames/invader_sprite.hh index 0217319d..95fec701 100644 --- a/src/ledgames/invader_sprite.hh +++ b/src/ledgames/invader_sprite.hh @@ -7,12 +7,13 @@ class invader_sprite_t : public sprite_t { public: - invader_sprite_t(); + invader_sprite_t(uint32_t score); virtual void draw_onto(Screen *screen) override; virtual void move_sprite(void) override; - virtual void destroy_sprite(void); + virtual uint32_t destroy_sprite(void); private: - uint32_t frames_in_anim; + uint32_t frames_in_anim_; + uint32_t score_; }; diff --git a/src/ledgames/invaders.cc b/src/ledgames/invaders.cc index 690ad8a5..6de8410c 100644 --- a/src/ledgames/invaders.cc +++ b/src/ledgames/invaders.cc @@ -69,7 +69,7 @@ static void reset_invaders(int for_player) { invader_speed = 0.05f; for (int row_counter = 0; row_counter < 4; row_counter++) { for (int column_counter = 0; column_counter < 6; column_counter++) { - invader_sprite_t invader_sprite; + invader_sprite_t invader_sprite((5 - row_counter) * 100); invader_sprite.set_active(true); invader_sprite.set_speed(invader_speed, 0.0); invader_sprite.set_position(column_counter * 10, 10 + (row_counter * 8)); @@ -275,7 +275,7 @@ void render_game(Screen *screen) { for (auto &invader_sprite : invader_sprites[current_player]) { active_invaders += (invader_sprite.is_active() ? 1 : 0); if (invader_sprite.test_collision(ship_missile_sprite)) { - invader_sprite.destroy_sprite(); + player_score[current_player] += invader_sprite.destroy_sprite(); ship_missile_sprite.set_active(false); for (uint8_t idx_ctr = 0; idx_ctr < 6; idx_ctr++) { if (lowest_invaders[idx_ctr] == invader_idx) { diff --git a/src/ledgames/menu.cc b/src/ledgames/menu.cc new file mode 100644 index 00000000..823acc19 --- /dev/null +++ b/src/ledgames/menu.cc @@ -0,0 +1,199 @@ +/** \file +* Test the matrix LCD PRU firmware with a multi-hue rainbow. +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "ledscape.h" + +#include "controls.hh" +#include "screen.hh" +#include "sprite.hh" +#include "png.hh" + +static controls_t *player_controls[2]; + +static Mix_Chunk *startup_bong; +static Mix_Chunk *menu_blip; + +static png_t sprite_sheet; +static std::vector game_sprites; + +static uint32_t current_option; + +enum class game_state_t { + Menu, + Menu_Select, + Service, +}; + +static game_state_t game_state; + + +static void reset_menu(void) { + game_state = game_state_t::Menu; + + sprite_t bricks_sprite; + bricks_sprite.set_active(true); + bricks_sprite.set_position(0,0); + bricks_sprite.set_image(0,0,64,32,&sprite_sheet); + + sprite_t paddles_sprite; + paddles_sprite.set_active(false); + paddles_sprite.set_position(0,0); + paddles_sprite.set_image(64,0,64,32,&sprite_sheet); + + sprite_t invaders_sprite; + invaders_sprite.set_active(false); + invaders_sprite.set_position(0,0); + invaders_sprite.set_image(128,0,64,32,&sprite_sheet); + + game_sprites.clear(); + game_sprites.push_back(bricks_sprite); + game_sprites.push_back(paddles_sprite); + game_sprites.push_back(invaders_sprite); + + current_option = 0; + + printf("\n\n\nGAME START\n\n\n"); +} + +void render_game(Screen *screen) { + screen->set_background_color(0x00000000); + screen->draw_start(); + + player_controls[0]->refresh_status(); + player_controls[1]->refresh_status(); + + if ((game_state == game_state_t::Menu) || (game_state == game_state_t::Menu_Select)) { + screen->draw_text(32,2,0x00808080,"LED games"); + screen->draw_text(40,2,0x00808080,"Joystick selects"); + screen->draw_text(48,2,0x00808080,"Button starts"); + + for (auto sprite : game_sprites) { + sprite.draw_onto(screen); + } + } + + screen->draw_end(); + + if (game_state == game_state_t::Menu) { + if (player_controls[0]->is_pressed(button_a)) { + exit(current_option); + } + + if (player_controls[0]->is_pressed(joystick_left)) { + game_sprites[current_option].set_active(false); + current_option = (current_option > 0) ? current_option-1 : 0; + game_sprites[current_option].set_active(true); + game_state = game_state_t::Menu_Select; + } + + if (player_controls[0]->is_pressed(joystick_right)) { + game_sprites[current_option].set_active(false); + current_option = (current_option < 2) ? current_option+1 : 2; + game_sprites[current_option].set_active(true); + game_state = game_state_t::Menu_Select; + } + } + + if (game_state == game_state_t::Menu_Select) { + if ((!player_controls[0]->is_pressed(joystick_left)) && (!player_controls[0]->is_pressed(joystick_right))) { + game_state = game_state_t::Menu; + } + } +} + +static void init_sdl(void) { + if (SDL_Init(SDL_INIT_AUDIO) != 0) { + fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); + exit(1); + } + + int audio_rate = 44100; + Uint16 audio_format = AUDIO_S16SYS; + int audio_channels = 2; + int audio_buffers = 16384; + + if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) != 0) { + fprintf(stderr, "Unable to initialize audio: %s\n", Mix_GetError()); + exit(1); + } + + startup_bong = Mix_LoadWAV("bin/startup.wav"); + if (startup_bong == NULL) { + fprintf(stderr, "Unable to load startup.wav: %s\n", Mix_GetError()); + exit(1); + } + + Mix_PlayChannel(-1, startup_bong, 0); +} + +int + main( + int argc, +const char ** argv + ) +{ + int width = 64; + int height = 64; + + ledscape_config_t * config = &ledscape_matrix_default; + if (argc > 1) + { + config = ledscape_config(argv[1]); + if (!config) + return EXIT_FAILURE; + } + + if (config->type == LEDSCAPE_MATRIX) + { + config->matrix_config.width = width; + config->matrix_config.height = height; + } + + sprite_sheet.read_file("bin/Menus.png"); + + ledscape_t * const leds = ledscape_init(config, 0); + + player_controls[0] = new controls_t(1); + player_controls[1] = new controls_t(3); + + reset_menu(); + + printf("init done\n"); + uint32_t * const p = (uint32_t*)calloc(width*height,4); + + Screen *screen = new Screen(leds, p); + + init_sdl(); + + menu_blip = Mix_LoadWAV("bin/blip3.wav"); + + try { + while (1) + { + render_game(screen); + + usleep(20000); + + } + } + catch (control_exit_exception* ex) { + delete screen; + } + + return EXIT_SUCCESS; +} diff --git a/src/ledgames/pong.cc b/src/ledgames/paddles.cc similarity index 96% rename from src/ledgames/pong.cc rename to src/ledgames/paddles.cc index 95d415bb..c85fd295 100644 --- a/src/ledgames/pong.cc +++ b/src/ledgames/paddles.cc @@ -134,9 +134,9 @@ void render_game(Screen *screen) { player_controls[0]->refresh_status(); player_controls[1]->refresh_status(); + player_controls[2]->refresh_status(); if (game_state == game_state_t::Attract) { - player_controls[2]->refresh_status(); if (player_controls[2]->is_pressed(button_a)) { reset_game(1); } else if (player_controls[2]->is_pressed(button_b)) { @@ -245,7 +245,7 @@ static void init_sdl(void) { exit(1); } - startup_bong = Mix_LoadWAV("/root/startup.wav"); + startup_bong = Mix_LoadWAV("bin/startup.wav"); if (startup_bong == NULL) { fprintf(stderr, "Unable to load startup.wav: %s\n", Mix_GetError()); exit(1); @@ -278,11 +278,11 @@ main( } ledscape_t * const leds = ledscape_init(config, 0); - + player_controls[0] = new controls_t(1); - player_controls[1] = new controls_t(2, true); + player_controls[1] = new controls_t(2); player_controls[2] = new controls_t(3); - + init_attract(); printf("init done\n"); @@ -292,17 +292,20 @@ main( init_sdl(); - paddle_blip = Mix_LoadWAV("/root/blip2.wav"); + paddle_blip = Mix_LoadWAV("bin/blip2.wav"); - while (1) - { - render_game(screen); +try { + while (1) + { + render_game(screen); - usleep(20000); + usleep(20000); - } - - ledscape_close(leds); + } +} +catch (control_exit_exception* ex) { + delete screen; +} return EXIT_SUCCESS; } diff --git a/src/ledgames/rsrc/Invaders.png b/src/ledgames/rsrc/Invaders.png index 7bfbd34965fc406232482067f5919ad06d65e3ef..e33a2c09b50bd4b7877ff1848ad0eda7ed69e3c3 100644 GIT binary patch delta 1045 zcmV+w1nT>z5Ty{XAOwH#Nkl%-6n#VdNHi`Omrfz9jWJQ7_XqetOiV10 zA7E`SP?(tbKWyym(Z*0M0gVN&(Zy(@5XO5Rd!A?RyqTSKlE=O0~Ce%Ic$}5r5p;jvPY6uq4x@Y0@+VoXG{iYrvSL zmpW^c#!%3Q$^al#PeVUR&%!8t3X2J2mfl28nl>$W@pFEf#<0-OiaD<_7+1nh3==D7 zh<#mJ_!oa5hJ`b%2%Fcweg7RV{CoXdw1xMh-Jk(r4+8?D*zRzlSMH=)ZM=q%4g2$I zY3vcQ^K)}a$G<;3)+K@sgVLtaJ8R`#M&}rmHckDr_8KN1j5cl7^U$wh(qJf0uj=Gx zt<%E7{d_RUcdZDL4+$~%AZ7*6AkovcGDzOfu<(CQqdGO^{-^h0nYKrIKQd!{2A$lc zYCUw-=(jsh^s<82-eU_(^mAUZ_Ru{BXLp`B&#D~vRLz1?IiF(fG3&8%s%ftt^cI%d z0?(y7IjzuvS$*%Zg(&R}O|kY~16EGG+N%e>g{ii*R~{N(NKlX`Hf(bHBfWR-dI*2AG;(cXJ~SaK)!o?I|6r#yRB?yKP- z=d1Vl3!Z-Rteyw<8a-Nb9t{AzISekx>)yHE&%o1m(a)mg&gbWIo-SN2EE+EM3=r{P zbQCYxVOT7=;_qxcE`D%&eqe@zRdwI{KzV=UOAt~5IslS zfPeqVS-of2??v0d-YvO6fX5>oI6Z**XvYd2?>~B2$RgBtB68~M+W!T++Q)|@H3kiR P00000NkvXXu0mjfgZdj+ delta 1047 zcmV+y1nB#v5T_8ZAOwH%NklX+6n;YxiG~5=;KC?`aYJ0F>^*=d@B$_# zE|BQfg}897NTP{}7w`lgz`eRLtcHNbg$}_PfEHr)vY?~_m^8Mvt{qlceJ@ne7w1whOHX9Qq zKLe|`i#acM8r#7J4n#}?r(X2%b4}^5q>y{kV0*UD&BXM+OiNRGVQpa4Ae=PJw~ua0 zXZ*dj1f0`@G1HuzIqe-=y{j@m{khU@_1&MpgZJImj@+6*A22snS{0AkoDN^EHe6r| zHNAcOZ*$&$a_E2Oc6J9LdiLQctn*-L-1iTk7o`AkV7SL1a~u@t2ve121HzbltjFBp z)TAu-FF=xw=69LcJMehY{rMM*`JjDkY{`M!{5BwrxyK-Lm*j^$k`^R+DqZ<1vjJ;k z1Chd3v-5VdGv;3BfKipxi!t{DwXE;S66jE;<E!9w--*Cl%_Kr5W7Z|rW@a0IGJ)Gi-iVjr8M3Axa;SVyFLGRsvo>NeL}AsYw)D13t4I2dHso0BI^c;!%_86>xl(JXPHNj zinTc$;B2)XyW!ynk7{|vR)dFY%)O|?5o@V1=f%V=`{~> RwhRCO002ovPDHLkV1j472}A$@ diff --git a/src/ledgames/rsrc/Makefile b/src/ledgames/rsrc/Makefile index 34ed7e29..46ba956f 100644 --- a/src/ledgames/rsrc/Makefile +++ b/src/ledgames/rsrc/Makefile @@ -5,7 +5,8 @@ FILES = blip2.wav \ blip4.wav \ blip5.wav \ startup.wav \ - Invaders.png + Invaders.png \ + Menus.png all: copy diff --git a/src/ledgames/rsrc/Menus.png b/src/ledgames/rsrc/Menus.png new file mode 100644 index 0000000000000000000000000000000000000000..4ac9b2924d4e71637b56388a46adfe6fa1d6afb9 GIT binary patch literal 2187 zcmV;62z2*}P)4Tx062|}Ro!pfR1`mnZ(O7nKcKOW4i$^9Ra0BJ8yc;~21%2p=|UR0&DbiW z$#rfTQ`a`O(`{9s_5yDV_yd5l2Of}kLK+Oj_Ok5(v`JGz71bo9J#^YYXp{DWs&KBa zQ@dTpxRI}aIp=pi@6k0t$5)!;m`NF6-tt{FpOKHBn3g+MAqmexC-gw4rh87hTrL7G z#)U`L!(So6-Zux@>;H3gR;i~0B%VTSS3P|m@o9jRsXML@Al^p#@G0Lx-0?i(9WEw_ zSYddU<1E8793KxjQ|c&UmW!mTC>k>?{om1c9S zUx<6_jj_!T&^M{wWM#>IBbOSf*xP<^F{$j$aOQ5Y{cT zROCL1M7^NKKL z&(yA}mSw#iM0^;IB{ZO5!wl{^Sg-*ysE~&Yz8!E;Qv(A`lu*=Clo*MpVGd>OdF6n^ zam1Jntk;<}MrqIC5$=Q>n{*R}?8oOIDUw5En2dl--Xw34!z7E+5pr-OgyQ-soSab)C%saskMla`aQLVzg0+MZf20tJU&K{hZoBrUc+U4e9&3o zw|KmGEe4#xz17wBu{f`SS_4i66?j31EjY7n{zGfhONK~c+td!TS#B}JoR}5UAd7p& z5phTyXSkK0xCeD3xaYP^o&J~#Xp9xFb0C;HHml5fA<%h1eR|qw7wxF+oNL9T1Aits?sKNIwvGaN)^WO$I^cUV)HzL_| z1K?{9p!>B*)`xfEv!4N6IG{J&h49W#Bz^(#YWw%`e_a{8n{G9m5AeR~_yl0%<7V@p zw5=04l1;gpwdcK}7*K7d`7`Zr5I)zc%bxa%Seu+xggC z+vg-Vb8h>uvm@gfC^PQexocT>Z_QUTu(!YI84(k_71R%C*Du<_p? z{#kB*k#YcsT-QHAOVKIk(ag+AFP+Q! z9pHuA_OC;+AmR=WT^lVZ?tGl0zxIb5c=$o8)gar0!X z9%eu`{r#Kwsz_o#xpSkkr%;l30u)6#MeoVv%&GrR=U*Jo6c)fT(9Noy!a$u4*M zXIqa}a=khGFzHjkJ_4;Qi2*~*!0zUTJDq)Yr|wo2{;vD(cF!-qgHVAZEA|8!dBW36 zSEg6eh!xorV8qEzGF6deRihO(%>@wiZL9zJ3n{txKic+gPBh5{P!!FDMNpc9B+AIW z|CE-+-T_itjVWr${8!M63t;^(#p^p6Y)GspY)IfD8T09aX&g4BjwALE2j`RcKASPt znO}!%ACD6q2Y8TzvkqP#(ic}SoX7ziQsZ?td?IDM9FP~*#ZMhu^LPyF97F5!jj*-O zMS@G?U_&BqlP$auhw+f^8;{(O*AHfwY6b3-Aui{aaco0})PA;^Q-_O>{jecJao}ee z>WMkfLtI}z#-KwY9^23%g~K}A8u!Jkshb61*s6otTi*PRJBB4t*)EaJ@LiNo zooyXk?7=<)A$d~)zM=%v;}8#g?FU{b>lPp5VmRQkM1AYj#c|r`ZF9x+7Q@jsqIbrD z=^8^gkB!lNadfVjIP(}%9fy;$jxmDq$++kk1CI8?1{XX?_z?%TmTeZc4Oi#UHrLfw zmsl7BiTGmUWDL5NZF N002ovPDHLkV1j5JI$;0+ literal 0 HcmV?d00001 diff --git a/src/script/Makefile b/src/script/Makefile index b2ef5e82..20a6664b 100644 --- a/src/script/Makefile +++ b/src/script/Makefile @@ -10,7 +10,8 @@ FILES = bbb-network-setup \ run-videoplayer \ twitter-scroller \ videoplayer \ - videoplayer.service + videoplayer.service \ + run-menu all: copy diff --git a/src/script/run-ledscape b/src/script/run-ledscape index e86b6d4e..45db587a 100755 --- a/src/script/run-ledscape +++ b/src/script/run-ledscape @@ -22,5 +22,5 @@ then CONFIGFILE="$USBMOUNT/ledscape.config" fi -exec ./bin/breakout > /dev/null +exec ./bin/run-menu > /dev/null #exec ./bin/matrix-udp-rx -m "Starting LEDscape" -c "$CONFIGFILE" >/dev/null diff --git a/src/script/run-menu b/src/script/run-menu new file mode 100755 index 00000000..a78c1b0c --- /dev/null +++ b/src/script/run-menu @@ -0,0 +1,24 @@ +#!/bin/bash + +function runmenu { + bin/menu + local status=$? + + if [ $status -eq 0 ]; then + bin/bricks + fi + + if [ $status -eq 1 ]; then + bin/paddles + fi + + if [ $status -eq 2 ]; then + bin/invaders + fi +} + +while true +do + runmenu +done + From 670a04348440f4c3239999b223b11b179aa27397 Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Sun, 26 Apr 2015 15:57:44 -0700 Subject: [PATCH 329/332] Menu doesn't exit. Menu range calculated from sprites vector! --- src/ledgames/menu.cc | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/ledgames/menu.cc b/src/ledgames/menu.cc index 823acc19..d7fecf98 100644 --- a/src/ledgames/menu.cc +++ b/src/ledgames/menu.cc @@ -103,7 +103,7 @@ void render_game(Screen *screen) { if (player_controls[0]->is_pressed(joystick_right)) { game_sprites[current_option].set_active(false); - current_option = (current_option < 2) ? current_option+1 : 2; + current_option = (current_option < game_sprites.size()-1) ? current_option+1 : game_sprites.size()-1; game_sprites[current_option].set_active(true); game_state = game_state_t::Menu_Select; } @@ -182,17 +182,15 @@ const char ** argv menu_blip = Mix_LoadWAV("bin/blip3.wav"); - try { - while (1) - { + while (1) + { + try { render_game(screen); - usleep(20000); - } - } - catch (control_exit_exception* ex) { - delete screen; + catch (control_exit_exception* ex) { + // Ignore the exception, as there is no useful exit program. + } } return EXIT_SUCCESS; From 0c7c05c0265c3dfc1cc027510ac6c25c4dfb0279 Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Sun, 26 Apr 2015 16:53:58 -0700 Subject: [PATCH 330/332] Slow down invader firing. Pixel-accurate collision --- src/ledgames/invaders.cc | 4 ++-- src/ledgames/sprite.cc | 23 +++++++++++++++-------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/ledgames/invaders.cc b/src/ledgames/invaders.cc index 6de8410c..2bdc0c62 100644 --- a/src/ledgames/invaders.cc +++ b/src/ledgames/invaders.cc @@ -61,7 +61,7 @@ static uint32_t frames_till_shot; static std::default_random_engine generator; static std::uniform_int_distribution invader_distribution(0,5); -static std::uniform_int_distribution shot_distribution(45,75); +static std::uniform_int_distribution shot_distribution(65,95); static void reset_invaders(int for_player) { invader_sprites[for_player].clear(); @@ -208,7 +208,7 @@ void render_game(Screen *screen) { sprite_t invader_sprite = invader_sprites[current_player][invader_column]; invader_missile_sprite.set_position(invader_sprite.get_x_position(), invader_sprite.get_y_position()); invader_missile_sprite.set_image(196,0,7,7,&sprite_sheet); - invader_missile_sprite.set_speed(0.0f, 1.0f); + invader_missile_sprite.set_speed(0.0f, 0.8f); frames_till_shot=shot_distribution(generator); } diff --git a/src/ledgames/sprite.cc b/src/ledgames/sprite.cc index 2e1b55e1..db7a0dc8 100644 --- a/src/ledgames/sprite.cc +++ b/src/ledgames/sprite.cc @@ -79,14 +79,21 @@ bool sprite_t::test_collision(const sprite_t &other_sprite) { if (!active_) return false; if (!other_sprite.is_active()) return false; - uint8_t visible_x = x_; - uint8_t visible_y = y_; - uint8_t other_visible_x = other_sprite.x_; - uint8_t other_visible_y = other_sprite.y_; - - return !((visible_x + width_ - 1) < other_visible_x || (visible_y + height_ - 1) < (other_visible_y) || - x_ > (other_visible_x + other_sprite.width_ - 1) || - y_ > (other_visible_y + other_sprite.height_ - 1) ); + uint8_t top = std::max(y_, other_sprite.y_); + uint8_t bottom = std::min(y_+height_, other_sprite.y_ + other_sprite.height_); + uint8_t left = std::max(x_, other_sprite.x_); + uint8_t right = std::min(x_+width_, other_sprite.x_ + other_sprite.width_); + + for (uint8_t y = top ; y < bottom; y++) { + for (uint8_t x = left; x < right; x++) { + uint32_t this_color = sprite_data_[frame_][(x - x_) + (y - y_) * width_]; + uint32_t other_color = other_sprite.sprite_data_[other_sprite.frame_][(x - other_sprite.x_) + (y - other_sprite.y_) * other_sprite.width_]; + if ((this_color != 0x00000000) && (other_color != 0x00000000)) { + return true; + } + } + } + return false; } float sprite_t::get_x_position(void) { From ce585c2a44d9c5729553aa5a5f6f225d5f17d81d Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Sun, 26 Apr 2015 16:57:17 -0700 Subject: [PATCH 331/332] Flip controls for dual player --- src/ledgames/paddles.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ledgames/paddles.cc b/src/ledgames/paddles.cc index c85fd295..711d6cc5 100644 --- a/src/ledgames/paddles.cc +++ b/src/ledgames/paddles.cc @@ -280,7 +280,7 @@ main( ledscape_t * const leds = ledscape_init(config, 0); player_controls[0] = new controls_t(1); - player_controls[1] = new controls_t(2); + player_controls[1] = new controls_t(2, true); player_controls[2] = new controls_t(3); init_attract(); From 04c8c0a1d75a4a551a9c5fd69a5154c79bfb59c4 Mon Sep 17 00:00:00 2001 From: Keith Henrickson Date: Sat, 9 May 2015 19:52:59 -0700 Subject: [PATCH 332/332] Add sounds to invaders mode! --- src/ledgames/bricks.cc | 6 +- src/ledgames/invaders.cc | 51 +++++++++---- src/ledgames/menu.cc | 92 +++++++++++++++++++++++- src/ledgames/paddles.cc | 6 +- src/ledgames/rsrc/Makefile | 9 ++- src/ledgames/rsrc/invader_explosion.wav | Bin 0 -> 74568 bytes src/ledgames/rsrc/invader_march1.wav | Bin 0 -> 104636 bytes src/ledgames/rsrc/invader_march2.wav | Bin 0 -> 94104 bytes src/ledgames/rsrc/invader_march3.wav | Bin 0 -> 93404 bytes src/ledgames/rsrc/invader_march4.wav | Bin 0 -> 95608 bytes src/ledgames/rsrc/ship_explosion.wav | Bin 0 -> 427064 bytes src/ledgames/screen.cc | 4 +- src/ledgames/screen.hh | 4 +- src/ledgames/sprite.cc | 13 +++- src/ledgames/sprite.hh | 2 +- 15 files changed, 156 insertions(+), 31 deletions(-) create mode 100644 src/ledgames/rsrc/invader_explosion.wav create mode 100644 src/ledgames/rsrc/invader_march1.wav create mode 100644 src/ledgames/rsrc/invader_march2.wav create mode 100644 src/ledgames/rsrc/invader_march3.wav create mode 100644 src/ledgames/rsrc/invader_march4.wav create mode 100644 src/ledgames/rsrc/ship_explosion.wav diff --git a/src/ledgames/bricks.cc b/src/ledgames/bricks.cc index 20a79ac9..32505d3b 100644 --- a/src/ledgames/bricks.cc +++ b/src/ledgames/bricks.cc @@ -1,5 +1,5 @@ /** \file - * Test the matrix LCD PRU firmware with a multi-hue rainbow. + * Bricks sample game */ #include #include @@ -201,7 +201,7 @@ void render_game(Screen *screen) { ball_sprite.move_sprite(); } - if (ball_sprite.test_collision(paddle_sprite)) { + if (ball_sprite.test_collision(paddle_sprite, true)) { ball_sprite.y_ = 59.0f; ball_sprite.dy_ = -ball_sprite.dy_; ball_sprite.dx_ = ball_horizontal_speeds[(int)(ball_sprite.x_ - (paddle_sprite.x_ - 1))]; @@ -225,7 +225,7 @@ void render_game(Screen *screen) { bool active_bricks = false; for (auto &brick_sprite : brick_sprites[current_player]) { active_bricks |= brick_sprite.is_active(); - if (brick_sprite.test_collision(ball_sprite)) { + if (brick_sprite.test_collision(ball_sprite, true)) { brick_sprite.set_active(false); game_state = game_state_t::Resetting; ball_sprite.dy_ = -ball_sprite.dy_; diff --git a/src/ledgames/invaders.cc b/src/ledgames/invaders.cc index 2bdc0c62..2430619b 100644 --- a/src/ledgames/invaders.cc +++ b/src/ledgames/invaders.cc @@ -1,5 +1,5 @@ /** \file -* Test the matrix LCD PRU firmware with a multi-hue rainbow. +* Invaders sample game */ #include #include @@ -38,9 +38,9 @@ static sprite_t invader_missile_sprite; static int32_t lowest_invaders[6]; static Mix_Chunk *startup_bong; -static Mix_Chunk *wall_blip; -static Mix_Chunk *block_blip[3]; -static Mix_Chunk *paddle_blip; +static Mix_Chunk *invader_explosion; +static Mix_Chunk *ship_explosion; +static Mix_Chunk *invader_march[4]; static png_t sprite_sheet; @@ -59,6 +59,9 @@ static float invader_speed; static uint32_t frames_in_state; static uint32_t frames_till_shot; +static uint32_t invader_march_state; +static uint32_t invader_march_frames; + static std::default_random_engine generator; static std::uniform_int_distribution invader_distribution(0,5); static std::uniform_int_distribution shot_distribution(65,95); @@ -104,6 +107,9 @@ static bool reset_round(void) { game_state = game_state_t::Playing; frames_till_shot = 60; + + invader_march_state = 0; + invader_march_frames = 0; return true; } @@ -182,6 +188,7 @@ void render_game(Screen *screen) { if (invader_touchdown) { game_state = game_state_t::Touchdown; + Mix_PlayChannel(-1, ship_explosion, 0); frames_in_state = 0; ship_sprite.set_active(false); player_lives[current_player] = 0; @@ -213,9 +220,9 @@ void render_game(Screen *screen) { } if (game_state == game_state_t::Attract) { - screen->draw_text(32,2,0x00808080,"GAME OVER!"); - screen->draw_text(40,2,0x00808080,"PRESS PLYR"); - screen->draw_text(48,2,0x00808080," 1 OR 2 "); + screen->draw_text(0,2,0x00808080,"GAME OVER!"); + screen->draw_text(48,2,0x00808080,"PRESS PLYR"); + screen->draw_text(56,2,0x00808080," 1 OR 2 "); } else if ((game_state == game_state_t::Playing) || (game_state == game_state_t::NewShip)) { char score[7]; char lives[1]; @@ -267,6 +274,7 @@ void render_game(Screen *screen) { if (!player_controls[current_player]->is_pressed(button_a)) { shot_fired = false; } + } if ((game_state == game_state_t::Attract) || (game_state == game_state_t::Playing)) { @@ -274,7 +282,8 @@ void render_game(Screen *screen) { int32_t invader_idx = 0; for (auto &invader_sprite : invader_sprites[current_player]) { active_invaders += (invader_sprite.is_active() ? 1 : 0); - if (invader_sprite.test_collision(ship_missile_sprite)) { + if (invader_sprite.test_collision(ship_missile_sprite, false)) { + Mix_PlayChannel(-1, invader_explosion, 0); player_score[current_player] += invader_sprite.destroy_sprite(); ship_missile_sprite.set_active(false); for (uint8_t idx_ctr = 0; idx_ctr < 6; idx_ctr++) { @@ -286,12 +295,23 @@ void render_game(Screen *screen) { } invader_idx++; } - invader_speed = 0.05f + ((24 - active_invaders) * 0.07f); + invader_speed = 0.06f + ((24 - active_invaders) * 0.05f); if (active_invaders == 0) { reset_invaders(current_player); } - if (ship_sprite.test_collision(invader_missile_sprite)) { + if (game_state == game_state_t::Playing) { + if (invader_march_frames == 0) { + Mix_PlayChannel(-1, invader_march[invader_march_state], 0); + invader_march_state = (invader_march_state + 1) % 4; + invader_march_frames = 10 + (active_invaders/4); + } else { + invader_march_frames--; + } + } + + if (ship_sprite.test_collision(invader_missile_sprite, false)) { + Mix_PlayChannel(-1, ship_explosion, 0); game_state = game_state_t::NewShip; ship_sprite.destroy_sprite(); player_lives[current_player]--; @@ -392,11 +412,12 @@ const char ** argv init_sdl(); - wall_blip = Mix_LoadWAV("/root/blip1.wav"); - paddle_blip = Mix_LoadWAV("/root/blip2.wav"); - block_blip[0] = Mix_LoadWAV("/root/blip3.wav"); - block_blip[1] = Mix_LoadWAV("/root/blip4.wav"); - block_blip[2] = Mix_LoadWAV("/root/blip5.wav"); + invader_explosion = Mix_LoadWAV("bin/invader_explosion.wav"); + ship_explosion = Mix_LoadWAV("bin/ship_explosion.wav"); + invader_march[0] = Mix_LoadWAV("bin/invader_march1.wav"); + invader_march[1] = Mix_LoadWAV("bin/invader_march2.wav"); + invader_march[2] = Mix_LoadWAV("bin/invader_march3.wav"); + invader_march[3] = Mix_LoadWAV("bin/invader_march4.wav"); try { while (1) diff --git a/src/ledgames/menu.cc b/src/ledgames/menu.cc index d7fecf98..3f1c5370 100644 --- a/src/ledgames/menu.cc +++ b/src/ledgames/menu.cc @@ -33,6 +33,9 @@ static std::vector game_sprites; static uint32_t current_option; +static uint32_t marque_position; +static uint32_t text_color; + enum class game_state_t { Menu, Menu_Select, @@ -41,6 +44,70 @@ enum class game_state_t { static game_state_t game_state; +static uint32_t rainbowColors[180]; + +static char marque_text[] = "Welcome to LED Games at MakerFaire Bay Area 2015!"; + +// Borrowed by OctoWS2811 rainbow test +static unsigned int +h2rgb( + unsigned int v1, + unsigned int v2, + unsigned int hue +) +{ + if (hue < 60) + return v1 * 60 + (v2 - v1) * hue; + if (hue < 180) + return v2 * 60; + if (hue < 240) + return v1 * 60 + (v2 - v1) * (240 - hue); + + return v1 * 60; +} + +// Convert HSL (Hue, Saturation, Lightness) to RGB (Red, Green, Blue) +// +// hue: 0 to 359 - position on the color wheel, 0=red, 60=orange, +// 120=yellow, 180=green, 240=blue, 300=violet +// +// saturation: 0 to 100 - how bright or dull the color, 100=full, 0=gray +// +// lightness: 0 to 100 - how light the color is, 100=white, 50=color, 0=black +// +static uint32_t +makeColor( + unsigned int hue, + unsigned int saturation, + unsigned int lightness +) +{ + unsigned int red, green, blue; + unsigned int var1, var2; + + if (hue > 359) + hue = hue % 360; + if (saturation > 100) + saturation = 100; + if (lightness > 100) + lightness = 100; + + // algorithm from: http://www.easyrgb.com/index.php?X=MATH&H=19#text19 + if (saturation == 0) { + red = green = blue = lightness * 255 / 100; + } else { + if (lightness < 50) { + var2 = lightness * (100 + saturation); + } else { + var2 = ((lightness + saturation) * 100) - (saturation * lightness); + } + var1 = lightness * 200 - var2; + red = h2rgb(var1, var2, (hue < 240) ? hue + 120 : hue - 240) * 255 / 600000; + green = h2rgb(var1, var2, hue) * 255 / 600000; + blue = h2rgb(var1, var2, (hue >= 120) ? hue - 120 : hue + 240) * 255 / 600000; + } + return (red << 16) | (green << 8) | blue; +} static void reset_menu(void) { game_state = game_state_t::Menu; @@ -66,6 +133,18 @@ static void reset_menu(void) { game_sprites.push_back(invaders_sprite); current_option = 0; + + marque_position = 64; + + // pre-compute the 180 rainbow colors + for (int i=0; i<180; i++) + { + int hue = i * 2; + int saturation = 100; + int lightness = 50; + rainbowColors[i] = makeColor(hue, saturation, lightness); + } + text_color = 0; printf("\n\n\nGAME START\n\n\n"); } @@ -78,13 +157,20 @@ void render_game(Screen *screen) { player_controls[1]->refresh_status(); if ((game_state == game_state_t::Menu) || (game_state == game_state_t::Menu_Select)) { - screen->draw_text(32,2,0x00808080,"LED games"); - screen->draw_text(40,2,0x00808080,"Joystick selects"); - screen->draw_text(48,2,0x00808080,"Button starts"); + screen->draw_text(32,marque_position,rainbowColors[text_color % 180],marque_text); + screen->draw_text(40,2,rainbowColors[text_color % 180],"Joy. sel."); + screen->draw_text(48,2,rainbowColors[text_color % 180],"Btn. start"); for (auto sprite : game_sprites) { sprite.draw_onto(screen); } + + marque_position--; + if (marque_position == (0xFFFFFFFF - (5 * sizeof(marque_text)) - 64)) { + marque_position = 64; + } + + text_color++; } screen->draw_end(); diff --git a/src/ledgames/paddles.cc b/src/ledgames/paddles.cc index 711d6cc5..e55ade72 100644 --- a/src/ledgames/paddles.cc +++ b/src/ledgames/paddles.cc @@ -1,5 +1,5 @@ /** \file - * Test the matrix LCD PRU firmware with a multi-hue rainbow. + * Paddles sample game */ #include #include @@ -180,7 +180,7 @@ void render_game(Screen *screen) { ball_sprite.move_sprite(); } - if (ball_sprite.test_collision(paddle_sprite[0])) { + if (ball_sprite.test_collision(paddle_sprite[0], true)) { ball_sprite.y_ = 59.0f; ball_sprite.dy_ = -ball_sprite.dy_ * 1.1f; if (ball_sprite.dy_ < -2.0f) ball_sprite.dy_ = -2.0f; @@ -188,7 +188,7 @@ void render_game(Screen *screen) { Mix_PlayChannel(-1, paddle_blip, 0); } - if (ball_sprite.test_collision(paddle_sprite[1])) { + if (ball_sprite.test_collision(paddle_sprite[1], true)) { ball_sprite.y_ = 5.0f; ball_sprite.dy_ = -ball_sprite.dy_ * 1.1f; if (ball_sprite.dy_ > 2.0f) ball_sprite.dy_ = 2.0f; diff --git a/src/ledgames/rsrc/Makefile b/src/ledgames/rsrc/Makefile index 46ba956f..a8ac78f5 100644 --- a/src/ledgames/rsrc/Makefile +++ b/src/ledgames/rsrc/Makefile @@ -6,7 +6,14 @@ FILES = blip2.wav \ blip5.wav \ startup.wav \ Invaders.png \ - Menus.png + Menus.png \ + invader_explosion.wav \ + ship_explosion.wav \ + invader_march1.wav \ + invader_march2.wav \ + invader_march3.wav \ + invader_march4.wav + all: copy diff --git a/src/ledgames/rsrc/invader_explosion.wav b/src/ledgames/rsrc/invader_explosion.wav new file mode 100644 index 0000000000000000000000000000000000000000..b51cfd014120c7debafb3b820225bd8e7a0f5e75 GIT binary patch literal 74568 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 z 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

-SQ7pmU80;X;;Ckf%hWS33zX&t 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 z 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 AvgXfO*4bDmCih#g9jQC;`|`ALE>*?wvI zI?hW@P}!a&&pGzbBEdM!#f;=p9%mFzKk}rUkuiVN zrHdt2q_cv^$S^Un!iy)+b4vTtouG!;CxlvL{pwW@FcHb~-?h1AJIKTFB9j+AvvWkJp9yaLT&dPTl0or@j z@G&T=!agyt7%B%@31oRgDxOpvV{BI0{7K;l=E$*fVNK+0@Z`z2l*u-fy-_|<%Dv0V zC%v`P?c`fkV%jD%AspV0`BMT8Z=5zN@wtb`NwQPl=iCbGWu(8A(p$Y>%OWMYe~su; zDLTyfM*h%5-(G@Y`umkSN0g0Z3fG|uaZCl8$280{{UCVkgd9D zNh`l>Dda3E#+=dPWSGdYP{e~I#iRE)Zz0#I!So}tb8u(pJW$sIU`O+4$@ypcdiEk| z6UZCnYBX3`LrUGKd*pQkVn0h9GSH#Z(0S`kpmR)kn@zyKr-$i_Dy3Z&CBco!L6YhY zSnBz3h<;bPg}*Kb5{=XokMrkwj@q9^7cTSna%^Q>$Qe%H->WbOv4J*>`tt zp5Ux~#Z~*dqqgi~vg|^->{7S94jWhbYve1f3erPu*bg<4Ulkm8p=Xb#PBeN%%W6bQhP6UmUH18U zuK5Cv-FV8zb|e_iKf#oMOq@`BCI`VC7sPd)L0L#V-lg?sn5t^FoKvN5=)BJQ-i{-) zdo8$YM(J1mjE-|nsApIag1L{8{aN{;5AMKdMjMvgep~()oY6kMI1vYecN{6X7&e6L z$3JVKV{S)aX@m()Zf*Yfo4w052z@`r7qz?BJSoqnDAtV73=3o_Iu1}3B9C$61hH)n zV-?6{sH2RikUY`(k6CEu+9`+WT?qQHAzUaS9)W0CaJ3u+?5gh`g_FTyoemQKOJFyd!RqRG&GXc*0CxxTtPgaGvsie5C ztFsTTw*1k+Ic} zrgV<=Sh_Y80WC&d3_tWOhC~awdg3s87BX|vQyp@evK-dMFhr;IRz2%Dhb&yS#*Z`V zKAeSSJog@vw+Y}}D9b+WCzH8+m8u&?bEZZa={}}@5IsTZ70&or5@jw8VtHp~>ASpP z`cAxq{exoXZ-U*PKzH}%%N^Iv?Ubu&GQ{F8lEo8DWN|E1J4&_6hGQ7dP*dug4R(v@ zd!I4dercZxZO4@k?4vDQClAI5D)*5*(m&QAbf!1=GrL{qZvE|l2I94iVv?&-uOWg5 zB8?H*YaS7%2cMs(!|R5{Ah!oc(d_)LRx^bOvlJFkl+x5dIjfs)k!{0Zr?g5vwqDkb zp9lWugFOC%L$6>zst}$yyt+(gEY12p1pYk1Y>W|GTK0}&_l7UOU6g(R-}|#sK>80# zILaghCQkoYf};5GG$b*vyskF^-bnZHt?e+yZn)YPgsN-T>!VfJ6-{F+bEXM<=7VUQ zQ%_7^4g36+)i_^j=sUYrf}y()Ao9=@gb!FL%dGfQ!t0wr!&U3pk|9;}2U*6O{Vp?8 z(P;GXAAZ8+#;bC}1!aB+eDA2RXXmwxefDfAxSepgVi@6e;?d2?EuodtZ2_2JBg3a) z4xFRhaFZ2dkHL_jTWgOY1cwU4zL&fZA%5hdM;b5w5TY42krx_oRx`!Yv-OZ6(h0*r z1TJ*mP8YJNJ819+UXVbiw+DX4_Lrc-WIN1Zgf-I0@oRKHr!y)O_vY`gXo$XsKnw^; z_`@R=H(ayT6M8Sbc*C0D-}(>`op_XP6mk#jUfE7n>{^jfoP%2r{a11Gdb7vOQ|}}{ z*HMl*or%2<_+dcm5TgU9sowNMam9Agb33WAmjEnC1soj5lstv?r(;9Ob&iy+V-L!4 ziMrlFhl=2RWOOyN$TLgJcnj$klb)Jjw^7MT^Y;DySbGf($x_oSC(645BDRLs^D=DR2={0ft*( z2T|o7@vdMUl72B5R79vzlM7fsI)85;x9Bfo}@A0gvTMJqKfBY~Bjj$)lo z@3e^TviVKjm5 zXLwf-Xp?R?6)79F0x2llk{C|iD5BwsVybC~$`s3Luu9yjKPf`T5!o&}GI(g_3LP@v z!xa`V#&pFWdkGa0I-_oH(8E@IuTHCr11fhNqa{}Z5-J`Nz?*={EJJdsX((-hMmqfn zP#o}89w(_m*xEZ-0qO;6Hi@E56lkfDL+1Pp)N$0&1+kKBIFj=}Bp2w!JA7-T-Jj(h z;`_GlnValHHLm>xpXIoY0@681)`~;fo4>WuG`7)g&nm7PV4HbprT)UMz|^=W`4HNgSgVfcL3`gzleI9 zT;kb`cA!>x_dON<&R#`YxYY(s)eK3iIKPi!Oj#RzmUiyC4xIiY+-JbM6DYLs`SC3d z9;5_F4w_-nJ!}^Qd*hwTi;GN#_fh?uNhU4J&WnJ!Dx!*3zI;I-8a!M~@^lhyC52}H zH&!U9*hC7;Z17+zIueh-*XpbT>uzbm6}IaZK@z4@x-qG))>D-$WMQP%)i#iDnHNEj z2Up)KD*tnF@!ex30bWMDJ?oXcXh;^RShratbO2Uy{*ID%)x2~Pc(pcsUFz7j2Gw?g z!cz$11fNSTzu4*|*=^nCfLx)tApSG!HOhfCVadfy-_MP|(v~0I6hzOZlae87tw*gtqZRp6+OmMi8#eJLEwBv!|QNcGO zi4;SHVrN_(b^T9NbMogPkuO3bt~nF35b<^d@>(&rfb2X)c)EPyqx5av_f9&JVMPNO z>~@L;OLQy#NJxA1urH(uNh~H#7@~|hh@)Qu`%2P>Psu08$xFw{vt*7F9%GRMdoea+ z_d)dRSF)4B(OaJuH*p91jW1FMDB10D8$sqL8mTFp+v(Hbd-zReG*<*BNug*we{h;4 zfK7=t7@v*BoD#}hw2Ez4E29%tas*Lw+(q)tW$*L35HH{zxo%Z4U*Dv~b8gY9>%Qon zyN0VkmWOj(BHr{^h1}7kB;ci9KeL9jnb5%mZ|`U!`H_#zKQ zWF}nhNUZFdgx1p(zJ1n2%Vq3I!&})IzwH#-Dow0O*3={EhCd0}rTp-P^j3P5(s7ME zr9zu}1OH>rQFI2^gYI~468CK4N(%R#nv8Nnj>K6Nce6J}baIE&40TXtOdKwx80V*c z46=mVIp@)ysMM;k0CpCeaiVeYC%^3&My%tsVELpv8ORPuuTvZhn;8y|B~^JV%GxVG1` z_9ofP1+B&$*lzfFCZsHJ)flYK$D(-r7GsiO?J=!3Gb*3X;5N%q?DMt4*uXj@|EAQ; zaCtKB4y*u;h9vAUQ?`(5IMSs@FxNV3KErCMVXXA8yC!>R@Jq6Lb1{r&K4~0#K9mZu z&yYJB?rfJV;}mfmG}6Rgazj)YSL2W%wN}ehdn_U_x*X9@6>g^-auG8nPjolgDo^Y-HJKzbm^td*9<;uW2e7O6ExO#Q`@5yl zXiIBIq30$|?su=8bC`ai$cH>XtbC^@6~un#!N?EYT>#%R5h=JKDFY=WeViYskZBRh zb0Iu)-aeh&#B$mcON*L8W(2U4mFQZ+NMl|Ga|T|nx$h_4JnY-JjECI}PkWl5LEo+g zC~}%|!wlX*-tr>0+6CWa3|m{~Rr-sOyvtTf8y)3u0OVU^8H-K0Sn9$ru;KQ)OL<`2 zZt2&2dAW$M4PP8@-@18WESX@cXM~ani<5-{7?4pnVVL*);MZX4w_gy={EMGbgiPbE zcior6EyF=K<_9B5^2fI&`8LiRytbn{bB;gU@3htAxS)m1JImIH##dU_YVIaiT7q=b z(R6TSbmh0HnxrUB+lCye%!DW!gxpV{v?Q>^XLg=VNpd!ra4VXv21sC|&HY1Urr$^>aT;K6h=5LJTGm2)* zSwI47YlSJ|V)Mwjc4`OBD<~mzP)d+%DvLN3T%N^G2Sb|9-7~&)rO?zxU-E zis0+$Xr9mW`jO%5>9(Qo+jQ&wN9)Ji$KA(=$J^GXe5|irDnxnXvKnu;j#SoHs&ubX zl|OQ-H~gx1CMO1Vw1&X1LSZMZ>Cf&a0gS-F$Pviox_&ia2pTZ7J>9sVevlOyv8-j% z%`%K_Q$L6UjISRNnQ~05A1xUnNdqR*#mLlfaPmYe+p%c0V>G_5tsPR0FvlBZjK*5! zvbH>7jd=EJ9er3`PVGC*YzVzK-;<25HN+Cf3VZ=t;K)XbnxW7niGsG;`;y4f`8g@1 zxUk+-UVwEhU*e((2d`mReBJ%Vx5vHw;--D3)qt&bdy=1Md)EJ#*X$Ngsq>6)&S}RC zjf4O{?!u#P-NwEU*Q3KAj>uB0ez#e7I-HONDk;kfz%MYX&9BtZ#)@<3Z=Ea{EtSzA zNuBd91RTUiu#+#OO9zw2MzPbMIF1vi2em_zB?~bxv}qx#F;Q4itjE+h<6rI^v#*wpTctze%z4?uP*%aN=;0-lTgCw`n z@2M2uu~oTk|3twl3i|p-M9t`1=TI~5%i`v+BgI;6HR0RVP+eNXy%2D713?VJ$uuwp z>E;C=apPKPCfD(BuiyzoU-W0nT*Q&%%e^6We~olvVQWb<92(IU(W@l-7d}?Tr1r4rch&!PAW@!Ri&>p`xl~8G|G^Tt|ez5tFY}OQQCFK{P?T*%72WDky@?m?i5x!eTuGFs`q@Ljq=y@*kG zzY`TV(7e>+nbQ-)o+@cEvQdU2cxW&{hB^I6IJHuNz3m==_<8BboPwv^BUAcLmfR+^ z*Iz@^t#g~b)68-^WUnWTsY*shigD4ET2HHT8-Hwf`+a?Xb~3ZpHfyQALCLKo`>jiJ z7XBm@=pAX_+mSEZKXK9%j$+gJ*mirn>U6$Zy8Hrr?B{E&r}Iw?PS2p0Vn6Abx* z`#xM_7|NZ@?+7qzjRj%eML5)K&N7$5hHCG&f!QjO=dRU>#ypabTILnB8r>C~JJ`Wq zUZeiq=8n>-XDxOO^R!xRzAs2pN0j|s^no56$I2Sqc8q0od$p$>dM;Zsg*Zn~unNb@D`zoQ zhzYtQo^WofEjCa&&9BRsxtHmIby01cM)PuP4a?Vaq7!}k;e2^Qu*bZi-MHF{^%ox> zW%KGp-reh!(Z+xs@zI%PmdCwR^bf4*uNSjxTb&;IS_`QZf-Wms+&SE_+@@t<>^xrr zc`~h4(@0zj?GxrwcmY2O;qb&!?4IQ-Oct<-3W$SOD8Ejoe;N{iQl+`}*P8 zEKy+n2C;gfe4vRy*(F~2>^oh!?3=!!_^_OQcgXFXK-I|D6(P`B^gU-^7_vduo*c~R z>A@T69;VKNj~~#767YQ$5CJBPQbfQ5P~(e@h0J%t1fK@u4(fBkF8d<5`)eh2G5qem zMf)vtx#Gk}y;hqZm!|pW=C~3C#SoR=m(HhL1nTFrlw@>g-I?$3hWztWJC&@_?JHE? z7B00K%mvWf2WzU`QH9~6WHas0ExKZ{Jnh-w)^{9K=j6{2&&-V*G2|w`>sH&Gpleg~ zN-)73RK~wkrHIYw0HUw}D%3}~fKyodAxTnUy#zb}>PJ2ozzuc^%7`934J==9f{T7f zIsgIfeNte{Le4e!fZJ-~w!OiaNg^-NZunfAYc$urDJ`YlyQM_r{ZGf1cHGmiXOUqx zcckXZ@75P6rZZ9PixpNgZ3?ZZSJr)U59S?y1=>eLAC{VL`Qmss> zrjLSNwZ4J~Z0LbU8#irf^+a8Bp>{h-zKiC$*z5WS56@)#j)Ve4>|Kb?<|8mAyxd^d zCS7FuH&Nzpu-#B}`>v9Vv!E45?OHPd-@ZnmKn=Dv6%3+(_T4W4fkfXi#4T80hm!m= zdLX<<=HMaID|o@bFWt zkA~Bo2GmQ1>S;L`z4tvxP@Q|D@Z%s7mjKB#;e6iWPmH7_;*G+LU~a->O=wq8`AFaw z07UUVumCGqEr>d>z)LU^y96|V{|@5{B%q!N(2S}D5XPcE7cdNknn>CZybYE%{sFa8 zglWmjtwd&8Qlc83oS+aJ^>nyeykxEYKqQbh{YLXl=jAK*U3_o1J;97otdnB}J%&fS z_4ckv2m7O?1>?o(o-Y!Tguu81M+{&>wifENa~nn)5KD3qxC3TO0~c9ZBzvf zkdqWf3BZC?3kbROTlg}DU4jnqFW4q=Ko2N@J)^5m6#)$G6EzV593cU+sB5YjP`^k> zI_dyO$z6CO07}RNzt7Lre76M5Q+5qMUQ13}oB$I3A`eW2NVkqe;-Y&=M3T=jzc;Rc zu?PGnAo)}IQ{@1Yz15l;F=g(49Hw?7U)2H z0OaQYv!@3b06@2z+Adr_>KVp)k`+MZA*6Xztkxd{zBhxWQ1i30xz6 z|Ms)6CUyk5Fa&m+26A8nvr_e#RNr`J3;M5WIWBprN$uiNraNduq~_Njk{?bI@Y2P47jiUT;b2uT9Ce|-GJ z3H(e?vgh78hY_$2o1caO_6Meb6R=MChz2m4Mub{mHh2Y#oNJ*^hze+Hw;Ze~TOApS zQx(AE?04I%<()2x3YZ);l4F5<1sA~0v0fM!R;K2HpNlQovR_Pr|kik>6ch21p z$h3sBweW<);RA3QRDad?VKnIP7o>(L1Hq()Ycbh0_INFa^&oRQSe+}Lxgm#MYB=z4 zT{v-B{eJBQ4ANeZG5&s#^(Iu9FJ0`^oXtHDoErCh40*fMBzsGnadgDt+nm^J(tMa1 zvDGMkN;&VVn-HW#OEj z{$@6;v4K1EX}Bhd6ICTifbd+61dQ0w$z(tiz5l7e)BaR{Cku8lKZu8jHQqp4*J48> zoB{^EGqO#kjoH=MtAG-K17O^HM}-Y&(36^9n~Um= zbvfe-zv|?Wi>%Ea4Jm8&HL~vjcq{|cl4YzVcIu-+r#$enL&yM=+c)w^__XImX;D0; zscCTl-LQKT01zZ#0&mB%4NmfG6~=9itD8)IGM&KzSs>Re8P+YOV2I|HdlPdoY$Y^h z*nQrY5ySsg6~sV)Ps=YqsZzxeM8G1f<6`2V*17U^eXE}{Zu88$AdJ=FvR_cD4O1w& zPTwtFwoK@gd&~sT;p`B$O9!=bcfkRu5*+q|gd4as&YYj=uLj`2Y;h_$I1&Ln+%%LB zJ2eP)BY+5z%!|yL0*dyFBp$Y2EUeR}6SMu6UFswC`t(HKaNahC^@fkG%{Lo$lNAiy zWKs!#-OKH6U#TLKc4gy0KWm>f`rFKhqR!JPZ95^a`tkhie*IV-_8LRk)+mjFWEAV< zTx6qNNTYZ3z?&r~EWXnr$<_drNN1FVv&E!{bDT&fC_ElkVTbg>q0w1-9Y)3x~vcn#IS9C$JoL_I|<*$5dpC3&);lIp$^$5YQ98IhE* zu#=AA00;pytcNEbUoC=bD+RB(7(o(@^?A^OI z&Oq2~t(?WCMGBu~wR<=Z{kFdL-)~XpbUR;p#zWIqSGQ^qu!HEq(p)Fa=bbwOR;1$HiFM#QoS#cveVB!u zzU!Zv3qHeB(OAZzb4PfIkvT?}KcT%<;EF<53KhuWgo2&t^00yWK6!_}kY9oLzPJ>H z>D%x1bn9qf@H5$>_UZlZ6hcIo^Xciy78!N}%klR1kY0}Iy?w(;SSY#2_a!s^o~^aP z@fvP4er>Drm=L}?4r3*oq?Ro&OAGZY&Gx3r%1UGQ?a-E47}Sr!fi1XK(TVPFgfMHf zH+?Et_KY63HYF*_szJi2quXzoT&r^SUSF7G@{^WA^J;+#x?VudWxkgA&t%2SdJSF!=bem7|VCK$F-XhQM;ckSX+8^47}(okRjwv?FEXK?J~CPD`dl0=*;@@lXjjHAMpS7n4|V;iYdrb7N7?5 zBLHY`WADUdY7bO0wlQ;YG5gD5jrFx-)5_Gc474*-vyJMkOKeIFt^0=!G}2Qt3^X$8 z(oEBG_391GY>F~$b<#^5tSp=h95QTQR^;X6WEYy5SvWb^nwjOk)Jv*31 zD>6>YPtz&G2H+GFqp+j=YaP9zxa#6T0{|=7|5``?Sx|rdtYIx>=M8RDzuDR=2WK{S z6eE&A;gQGhfeEbg7|==h#}9>B^b99|ZTE-R4ZkMPOfBgB5x&+wpYQNjzD@%QCkAY^rdQ zpje{F{&L6qu0%@*9#>0_nYe9_@?zVrA5V$#j5Zm&Z+I7g4r61?){l{7M4JZA+UDe@ zV6lT*;j54-*GuvAiB9sTQ<$g)t}%U+?z#!DfMd|^T8dN=f&H@D)-i6h^ZM0rZ^}M5 z$C5~|MuB1FnNF?z^)aOJo~k98y_WKaI7h$xEz&5x`j`r*F~-b-8D#5>2Dlw)z=E0#_46E|gfW`s(;cr>m$u2nxI zKOoq&^VyzL$XR?B{lLNhlHyFRRgP*LazBdBi8o&7aHEm2!9sw`1y3%2?NSfvGXzCu zg7?hz(j~ZcvuQ?jHiY_)<#G_5mhk0!Gr0wcjjWV-&{E8&q)>1cdNJtIl|wAV1|_*Q zi);y1bULDx2HVvAH%Y}q5q1$p6!-7y&HSj(@_9|6rr|k6NKmy{_ZoeMVz&Dk*`ptbtrqbSZh{JJf=FrpT&{X_Ha@#X%Q zORi3FcKM`|qV=nTn<JeXF)nboPDLjK1}c4_DxB5I8pNQpX}Ac-t`(3ii#Xz@ZadS#-eVIX#gm zg+_m){~;tZ{2sxlzCF&xC);A4ay^8=s0iEW9OF}fnG`yn0@5G#<I_Zco-^h?6tH_~C!fg8@|;^JSAK|bFmYD8YlsMB zH4eX3vvuM>@D2L)uG@}#4|pgL!x-St<5RuZZ=ar(G~4jhdK|{!qI0{vYxM|Df4KbY zxOCSc#v}S-nU`T0GF3w*$Nk`7#j|yPdHHa!AbsaL#kxCeP>us(^@6xu^GfQhHY0NN zh{!_a!d3*X`nf<|^>7lJ|C9yO{fJoX4w~l)rz)$-lO^N%Q?9OG!9CME#D9l4+!v<^ zE>LLW05v#Jv$3+XcK(0FH5KV;*%`(0DcM$acqGTgW+j!n*8PU@@u|uCDcMQQxz>Gf zP^ba}XZR~v!UFy#JuSZ0oSO#`14CWC8uZ;r?y^4Hw{AA+`jXu?i41 zMfoo{f|LJHp1+CDU#sGu;}MMhAAo<`e*;i3a2Oo?fC4xKfHLC$1weTE9{>j@dvhxr zGiN5Ct*14UtFybA3DDly#mv;%-QI!G3JCoF0se2o{m+S%9EJXe@BTr*{|Q6;Wc>F8 z{@eb0eE-c7{|WOr2K|5KjQ>O_>oWNp<=^(-DF4m+{)rMd{*S@@XGQ+oS%drk1M_eD wZ!o*n)<0t9W~-y`_9Rg#4Qu~Yy69`rk literal 0 HcmV?d00001 diff --git a/acrylic/LedBasePlate-X7.cdr b/acrylic/LedBasePlate-X7.cdr new file mode 100755 index 0000000000000000000000000000000000000000..7687d02e0bea8b4ea0ebed70fd6dc2ab528bd039 GIT binary patch literal 457699 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