Repository: osresearch/LEDscape Branch: master Commit: f94708c188f5 Files: 109 Total size: 4.1 MB Directory structure: gitextract__f3o1sre/ ├── .gitignore ├── Makefile ├── Makefile.common ├── README.md ├── Setup.md ├── am335x/ │ ├── app_loader/ │ │ ├── include/ │ │ │ ├── pruss_intc_mapping.h │ │ │ └── prussdrv.h │ │ └── interface/ │ │ ├── Makefile │ │ ├── __prussdrv.h │ │ └── prussdrv.c │ └── pasm/ │ ├── LICENCE.txt │ ├── Makefile │ ├── pasm.c │ ├── pasm.h │ ├── pasmdbg.h │ ├── pasmdot.c │ ├── pasmexp.c │ ├── pasmmacro.c │ ├── pasmop.c │ ├── pasmpp.c │ ├── pasmstruct.c │ └── pru_ins.h ├── brackets/ │ ├── Letters.dxf │ ├── Write.scad │ ├── flat-bracket.scad │ ├── matrix-bracket.scad │ ├── octoscroller.scad │ └── spiral.scad ├── default.config ├── dts/ │ ├── CAPE-BONE-OCTO-00A0.dtbo │ ├── LEDscape.dts │ ├── README.md │ ├── angstrom.dtb │ ├── angstrom.dts │ ├── cape-bone-octo.dts │ └── ubuntu-3.8.13-bone32.dts ├── fonts/ │ ├── json2bmp │ └── mta-sign.json ├── lib/ │ └── .empty ├── obj/ │ └── .empty ├── pcb/ │ ├── LEDscape pin assignments.csv │ ├── LEDscape.brd │ ├── LEDscape.lbr │ ├── LEDscape.sch │ ├── TODO │ ├── flat-20mm.scad │ ├── lightbuddy-transmitter.brd │ ├── lightbuddy-transmitter.sch │ ├── octoscroller.brd │ ├── octoscroller.sch │ ├── receiver-2x.brd │ ├── receiver-2x.sch │ ├── receiver-4x.brd │ ├── receiver-4x.sch │ ├── receiver.brd │ └── receiver.sch ├── radials.config ├── src/ │ ├── demos/ │ │ ├── Makefile │ │ ├── companion-cube.raw │ │ ├── cube-image.c │ │ ├── cube-life.c │ │ ├── fire.c │ │ ├── identify.c │ │ ├── life.c │ │ ├── lightcycles.c │ │ └── matrix-test.c │ ├── ledscape/ │ │ ├── Makefile │ │ ├── bitpattern.h │ │ ├── config.c │ │ ├── fixed-font.c │ │ ├── ledscape.c │ │ ├── ledscape.h │ │ ├── matrix.p │ │ ├── pru.c │ │ ├── pru.h │ │ ├── util.c │ │ ├── util.h │ │ ├── ws281x.hp │ │ └── ws281x.p │ ├── mta/ │ │ ├── Makefile │ │ ├── mta-font.c │ │ └── mta-sign.c │ ├── net/ │ │ ├── Makefile │ │ ├── matrix-tcp-rx.c │ │ ├── matrix-udp-rx.c │ │ └── opc-rx.c │ ├── perlin/ │ │ ├── Makefile │ │ ├── gammalut.h │ │ ├── globals.h │ │ ├── knobs/ │ │ │ └── knobs.ino │ │ ├── pattern.cpp │ │ ├── pattern.h │ │ ├── perlin-ledscape.cpp │ │ ├── pf2.cpp │ │ └── pf2.h │ └── script/ │ ├── Makefile │ ├── bbb-network-setup │ ├── find-serial │ ├── install │ ├── ledscape.service │ ├── python-test │ ├── run-ledscape │ ├── run-videoplayer │ ├── twitter-scroller │ ├── videoplayer │ └── videoplayer.service ├── strips.config ├── tall-cylinder.config └── ubuntu/ └── ledscape.conf ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .*.swp .*.swo *.i *.o *.a *.bin pcb/*.b[^r][^d] pcb/*.p[^c][^b] rgb-test am335x/pasm/pasm .*.d *~ *~ bin/* ================================================ FILE: Makefile ================================================ ######### # # Top level Makefile. # Mostly just recurse into subdirectories. SUBDIR-y += src/ledscape 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 \ $(MAKE) -C $$dir || exit 1; \ done clean: for dir in $(SUBDIR-y); do \ $(MAKE) -C $$dir clean; \ done firmware: echo CAPE-BONE-OCTO > /sys/devices/bone_capemgr.8/slots ================================================ FILE: Makefile.common ================================================ ######### # # Common build targets # # TOP ?= ../.. OBJDIR ?= $(TOP)/obj LIBDIR ?= $(TOP)/lib BINDIR ?= $(TOP)/bin 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; # 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 GENERIC_CFLAGS += \ -g \ -W \ -Wall \ -D_BSD_SOURCE \ -Wp,-MMD,$(dir $@).$(notdir $@).d \ -Wp,-MT,$@ \ -I. \ -I$(TOP)/src/ledscape \ -O2 \ -mtune=cortex-a8 \ -march=armv7-a \ CFLAGS += \ -std=c99 \ $(GENERIC_CFLAGS) \ CPPFLAGS += \ $(GENERIC_CFLAGS) \ LDFLAGS += \ LDLIBS += \ -L$(LIBDIR) \ -lledscape \ -lpthread \ -lm \ 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)g++ $(LDFLAGS) -o $@ $^ $(LDLIBS) $(OBJDIR)/%.o: %.c $(COMPILE.c-o) $(OBJDIR)/%.o: %.cpp $(COMPILE.cpp-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 # # 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) $(LIBDIR)/libledscape.a)) $(foreach O,$(LIB-y),\ $(eval $(LIBDIR)/$O: $(foreach s,$($(basename $O).srcs),$(OBJDIR)/$(basename $s).o) $(APP_LOADER_LIB))) #$(TARGETS): #$(COMPILE.link) .PHONY: clean # Include all of the generated dependency files -include $(OBJDIR)/.*.o.d clean: rm -rf \ $(OBJDIR)/*.o \ $(LIBDIR)/*.a \ $(OBJDIR)/.*.o.d \ $(LIBDIR)/*.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) ================================================ FILE: README.md ================================================ ![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 ================================================ FILE: Setup.md ================================================ # 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: BBB-eMMC-flasher-debian-7.8-console-armhf-2015-03-01-2gb.img.xz The latest version can be found at: http://elinux.org/Beagleboard:BeagleBoneBlack_Debian#Debian_Releases First, we need to expand the image to use the whole SD card. By default, it is only 2GB. Note: If using a RevC or lower BBB, the EMMC is only 2GB so this isn't necessicary. 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 -y sudo apt-get install git build-essential python vim -y Disable the HDMI output: If you are using a Debian image from 2014.8.13 or newer, do this: sudo cp /boot/uEnv.txt /boot/uEnv.txt.backup 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 Otherwise, modify the uEnv boot file by hand to disable HDMI and HDMIN overlays. Enable a larger shared memory space (8MB) with the PRU: echo 'options uio_pruss extram_pool_sz=0x800000' | sudo tee -a /etc/modprobe.d/ledscape.conf Finally, reboot to apply these changs: sudo 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 | The following line consists of Width,Height. For LED strip mode, this means: W: length of the longest strip H: number of output strips ## 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. ## Debian Debian uses 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 ## Ubuntu Note: The Ubuntu startup script is old and probably needs fixing. Ubuntu appears to use upstart. Do this: sudo cp ubuntu/ledscape.conf /etc/init sudo start ledscape # Extra credit ## Make the filesystem read-only To help prevent the configuration from breaking, it's helpful to configure the system as read only. The insructions are from: http://armsdr.blogspot.com/2014/11/beaglebone-debian-read-only-filesystem.html First, back up the original fstab: sudo cp /etc/fstab /etc/fstab_rw Now, set the root filesystem to be readonly: sudo sed -i 's/ext4 noatime/ext4 ro,noatime/g' /etc/fstab Finally, add some temporary rw mounts so that the system can continue to function: echo "tmpfs /tmp tmpfs nodev,nosuid,size=32M 0 0 tmpfs /srv tmpfs nodev,size=512K 0 0 tmpfs /var/log tmpfs defaults,noatime,size=1M 0 0 tmpfs /var/tmp tmpfs defaults,noatime,size=512K 0 0 tmpfs /var/run tmpfs defaults,noatime,size=512K 0 0" | sudo tee -a /etc/fstab Later, write capability can be restored using the following command: sudo mount -o remount,rw / And disabled again using: sudo mount -o remount,ro / ## Speed up boot when Ethernet is not connected The ethernet PHY on some BBBs can be flaky and cause a long delay during boot. To work around this, set it to not load at boot: sudo sudo sed -i 's/auto eth0/#auto eth0/g' /etc/network/interfaces Later it can be enabled by typing: sudo ifup eth0 ## Set the time automatically (when network is available) sudo apt-get install ntpdate -y # 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 To use the video player, some additional packages will need to be installed: sudo apt-get install libavformat-dev x264 v4l-utils ffmpeg libcv2.3 libcvaux2.3 libhighgui2.3 python-opencv opencv-doc libcv-dev libcvaux-dev libhighgui-dev -y #Helpful things for development ## Make VIM prettier Enable color highlighting echo 'syntax on' >>~/.vimrc ================================================ FILE: am335x/app_loader/include/pruss_intc_mapping.h ================================================ /* * 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 */ \ } \ ================================================ FILE: am335x/app_loader/include/prussdrv.h ================================================ /* * 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 ================================================ FILE: am335x/app_loader/interface/Makefile ================================================ ROOTDIR = .. TARGET = libprussdrv CROSS_COMPILE?=arm-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/* ================================================ FILE: am335x/app_loader/interface/__prussdrv.h ================================================ /* * __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)); } ================================================ FILE: am335x/app_loader/interface/prussdrv.c ================================================ /* * 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; } ================================================ FILE: am335x/pasm/LICENCE.txt ================================================ /* * {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. * */ ================================================ FILE: am335x/pasm/Makefile ================================================ # 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 ================================================ FILE: am335x/pasm/pasm.c ================================================ /* * 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); } ================================================ FILE: am335x/pasm/pasm.h ================================================ /* * 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 ); ================================================ FILE: am335x/pasm/pasmdbg.h ================================================ /* * 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; ================================================ FILE: am335x/pasm/pasmdot.c ================================================ /* * 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(); } ================================================ FILE: am335x/pasm/pasmexp.c ================================================ /* * 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); } ================================================ FILE: am335x/pasm/pasmmacro.c ================================================ /* * 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); } ================================================ FILE: am335x/pasm/pasmop.c ================================================ /* * 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); } ================================================ FILE: am335x/pasm/pasmpp.c ================================================ /* * 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); } ================================================ FILE: am335x/pasm/pasmstruct.c ================================================ /* * 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); } ================================================ FILE: am335x/pasm/pru_ins.h ================================================ /* * 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[]; ================================================ FILE: brackets/Letters.dxf ================================================ 999 DXF created by Inkscape 0 SECTION 2 HEADER 9 $ACADVER 1 AC1014 9 $HANDSEED 5 FFFF 9 $MEASUREMENT 70 1 0 ENDSEC 0 SECTION 2 TABLES 0 TABLE 2 VPORT 5 8 330 0 100 AcDbSymbolTable 70 4 0 VPORT 5 2E 330 8 100 AcDbSymbolTableRecord 100 AcDbViewportTableRecord 2 *ACTIVE 70 0 10 0.0 20 0.0 11 1.0 21 1.0 12 210.0 22 148.5 13 0.0 23 0.0 14 10.0 24 10.0 15 10.0 25 10.0 16 0.0 26 0.0 36 1.0 17 0.0 27 0.0 37 0.0 40 341.0 41 1.24 42 50.0 43 0.0 44 0.0 50 0.0 51 0.0 71 0 72 100 73 1 74 3 75 0 76 0 77 0 78 0 0 ENDTAB 0 TABLE 2 LTYPE 5 5 330 0 100 AcDbSymbolTable 70 1 0 LTYPE 5 14 330 5 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 BYBLOCK 70 0 3 72 65 73 0 40 0.0 0 LTYPE 5 15 330 5 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 BYLAYER 70 0 3 72 65 73 0 40 0.0 0 LTYPE 5 16 330 5 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 CONTINUOUS 70 0 3 Solid line 72 65 73 0 40 0.0 0 ENDTAB 0 TABLE 2 LAYER 5 2 100 AcDbSymbolTable 70 93 0 LAYER 5 50 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 0 70 0 6 CONTINUOUS 0 LAYER 5 51 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 A 70 0 6 CONTINUOUS 0 LAYER 5 52 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 B 70 0 6 CONTINUOUS 0 LAYER 5 53 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 C 70 0 6 CONTINUOUS 0 LAYER 5 54 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 D 70 0 6 CONTINUOUS 0 LAYER 5 55 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 E 70 0 6 CONTINUOUS 0 LAYER 5 56 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 F 70 0 6 CONTINUOUS 0 LAYER 5 57 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 G 70 0 6 CONTINUOUS 0 LAYER 5 58 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 H 70 0 6 CONTINUOUS 0 LAYER 5 59 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 I 70 0 6 CONTINUOUS 0 LAYER 5 5a 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 J 70 0 6 CONTINUOUS 0 LAYER 5 5b 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 K 70 0 6 CONTINUOUS 0 LAYER 5 5c 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 L 70 0 6 CONTINUOUS 0 LAYER 5 5d 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 M 70 0 6 CONTINUOUS 0 LAYER 5 5e 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 N 70 0 6 CONTINUOUS 0 LAYER 5 5f 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 O 70 0 6 CONTINUOUS 0 LAYER 5 60 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 P 70 0 6 CONTINUOUS 0 LAYER 5 61 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 Q 70 0 6 CONTINUOUS 0 LAYER 5 62 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 R 70 0 6 CONTINUOUS 0 LAYER 5 63 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 S 70 0 6 CONTINUOUS 0 LAYER 5 64 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 T 70 0 6 CONTINUOUS 0 LAYER 5 65 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 U 70 0 6 CONTINUOUS 0 LAYER 5 66 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 V 70 0 6 CONTINUOUS 0 LAYER 5 67 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 W 70 0 6 CONTINUOUS 0 LAYER 5 68 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 X 70 0 6 CONTINUOUS 0 LAYER 5 69 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 Y 70 0 6 CONTINUOUS 0 LAYER 5 6a 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 Z 70 0 6 CONTINUOUS 0 LAYER 5 6b 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 1 70 0 6 CONTINUOUS 0 LAYER 5 6c 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 2 70 0 6 CONTINUOUS 0 LAYER 5 6d 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 3 70 0 6 CONTINUOUS 0 LAYER 5 6e 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 4 70 0 6 CONTINUOUS 0 LAYER 5 6f 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 5 70 0 6 CONTINUOUS 0 LAYER 5 70 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 6 70 0 6 CONTINUOUS 0 LAYER 5 71 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 7 70 0 6 CONTINUOUS 0 LAYER 5 72 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 8 70 0 6 CONTINUOUS 0 LAYER 5 73 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 9 70 0 6 CONTINUOUS 0 LAYER 5 74 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 a_ 70 0 6 CONTINUOUS 0 LAYER 5 75 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 b_ 70 0 6 CONTINUOUS 0 LAYER 5 76 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 c_ 70 0 6 CONTINUOUS 0 LAYER 5 77 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 d_ 70 0 6 CONTINUOUS 0 LAYER 5 78 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 e_ 70 0 6 CONTINUOUS 0 LAYER 5 79 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 f_ 70 0 6 CONTINUOUS 0 LAYER 5 7a 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 g_ 70 0 6 CONTINUOUS 0 LAYER 5 7b 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 h_ 70 0 6 CONTINUOUS 0 LAYER 5 7c 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 i_ 70 0 6 CONTINUOUS 0 LAYER 5 7d 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 j_ 70 0 6 CONTINUOUS 0 LAYER 5 7e 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 k_ 70 0 6 CONTINUOUS 0 LAYER 5 7f 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 l_ 70 0 6 CONTINUOUS 0 LAYER 5 80 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 m_ 70 0 6 CONTINUOUS 0 LAYER 5 81 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 n_ 70 0 6 CONTINUOUS 0 LAYER 5 82 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 o_ 70 0 6 CONTINUOUS 0 LAYER 5 83 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 p_ 70 0 6 CONTINUOUS 0 LAYER 5 84 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 q_ 70 0 6 CONTINUOUS 0 LAYER 5 85 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 r_ 70 0 6 CONTINUOUS 0 LAYER 5 86 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 s_ 70 0 6 CONTINUOUS 0 LAYER 5 87 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 t_ 70 0 6 CONTINUOUS 0 LAYER 5 88 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 u_ 70 0 6 CONTINUOUS 0 LAYER 5 89 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 v_ 70 0 6 CONTINUOUS 0 LAYER 5 8a 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 w_ 70 0 6 CONTINUOUS 0 LAYER 5 8b 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 x_ 70 0 6 CONTINUOUS 0 LAYER 5 8c 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 y_ 70 0 6 CONTINUOUS 0 LAYER 5 8d 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 z_ 70 0 6 CONTINUOUS 0 LAYER 5 8e 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 ~ 70 0 6 CONTINUOUS 0 LAYER 5 8f 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 ! 70 0 6 CONTINUOUS 0 LAYER 5 90 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 @ 70 0 6 CONTINUOUS 0 LAYER 5 91 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 # 70 0 6 CONTINUOUS 0 LAYER 5 92 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 $ 70 0 6 CONTINUOUS 0 LAYER 5 93 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 % 70 0 6 CONTINUOUS 0 LAYER 5 94 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 ^ 70 0 6 CONTINUOUS 0 LAYER 5 95 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 & 70 0 6 CONTINUOUS 0 LAYER 5 96 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 * 70 0 6 CONTINUOUS 0 LAYER 5 97 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 ( 70 0 6 CONTINUOUS 0 LAYER 5 98 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 ) 70 0 6 CONTINUOUS 0 LAYER 5 99 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 _ 70 0 6 CONTINUOUS 0 LAYER 5 9a 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 + 70 0 6 CONTINUOUS 0 LAYER 5 9b 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 - 70 0 6 CONTINUOUS 0 LAYER 5 9c 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 = 70 0 6 CONTINUOUS 0 LAYER 5 9d 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 , 70 0 6 CONTINUOUS 0 LAYER 5 9e 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 . 70 0 6 CONTINUOUS 0 LAYER 5 9f 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 < 70 0 6 CONTINUOUS 0 LAYER 5 a0 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 > 70 0 6 CONTINUOUS 0 LAYER 5 a1 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 ? 70 0 6 CONTINUOUS 0 LAYER 5 a2 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 / 70 0 6 CONTINUOUS 0 LAYER 5 a3 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 ; 70 0 6 CONTINUOUS 0 LAYER 5 a4 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 : 70 0 6 CONTINUOUS 0 LAYER 5 a5 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 ' 70 0 6 CONTINUOUS 0 LAYER 5 a6 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 ` 70 0 6 CONTINUOUS 0 LAYER 5 a7 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 " 70 0 6 CONTINUOUS 0 LAYER 5 a8 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 [ 70 0 6 CONTINUOUS 0 LAYER 5 a9 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 ] 70 0 6 CONTINUOUS 0 LAYER 5 aa 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 { 70 0 6 CONTINUOUS 0 LAYER 5 ab 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 } 70 0 6 CONTINUOUS 0 LAYER 5 ac 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 | 70 0 6 CONTINUOUS 0 ENDTAB 0 TABLE 2 STYLE 5 3 330 0 100 AcDbSymbolTable 70 1 0 STYLE 5 11 330 3 100 AcDbSymbolTableRecord 100 AcDbTextStyleTableRecord 2 STANDARD 70 0 40 0.0 41 1.0 50 0.0 71 0 42 2.5 3 txt 4 0 ENDTAB 0 TABLE 2 VIEW 5 6 330 0 100 AcDbSymbolTable 70 0 0 ENDTAB 0 TABLE 2 UCS 5 7 330 0 100 AcDbSymbolTable 70 0 0 ENDTAB 0 TABLE 2 APPID 5 9 330 0 100 AcDbSymbolTable 70 2 0 APPID 5 12 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD 70 0 0 ENDTAB 0 TABLE 2 DIMSTYLE 5 A 330 0 100 AcDbSymbolTable 70 1 0 DIMSTYLE 105 27 330 A 100 AcDbSymbolTableRecord 100 AcDbDimStyleTableRecord 2 ISO-25 70 0 3 4 5 6 7 40 1.0 41 2.5 42 0.625 43 3.75 44 1.25 45 0.0 46 0.0 47 0.0 48 0.0 140 2.5 141 2.5 142 0.0 143 0.03937007874016 144 1.0 145 0.0 146 1.0 147 0.625 71 0 72 0 73 0 74 0 75 0 76 0 77 1 78 8 170 0 171 3 172 1 173 0 174 0 175 0 176 0 177 0 178 0 270 2 271 2 272 2 273 2 274 3 340 11 275 0 280 0 281 0 282 0 283 0 284 8 285 0 286 0 287 3 288 0 0 ENDTAB 0 TABLE 2 BLOCK_RECORD 5 1 330 0 100 AcDbSymbolTable 70 1 0 BLOCK_RECORD 5 1F 330 1 100 AcDbSymbolTableRecord 100 AcDbBlockTableRecord 2 *MODEL_SPACE 0 BLOCK_RECORD 5 1B 330 1 100 AcDbSymbolTableRecord 100 AcDbBlockTableRecord 2 *PAPER_SPACE 0 ENDTAB 0 ENDSEC 0 SECTION 2 BLOCKS 0 BLOCK 5 20 330 1F 100 AcDbEntity 8 0 100 AcDbBlockBegin 2 *MODEL_SPACE 70 0 10 0.0 20 0.0 30 0.0 3 *MODEL_SPACE 1 0 ENDBLK 5 21 330 1F 100 AcDbEntity 8 0 100 AcDbBlockEnd 0 BLOCK 5 1C 330 1B 100 AcDbEntity 67 1 8 0 100 AcDbBlockBegin 2 *PAPER_SPACE 1 0 ENDBLK 5 1D 330 1B 100 AcDbEntity 67 1 8 0 100 AcDbBlockEnd 0 ENDSEC 0 SECTION 2 ENTITIES 0 LWPOLYLINE 5 100 100 AcDbEntity 8 A 62 7 100 AcDbPolyline 90 9 70 0 10 0.000282 20 0.000284 30 0.0 10 2.084860 20 8.081096 30 0.0 10 2.858708 20 8.081096 30 0.0 10 5.080282 20 0.000284 30 0.0 10 4.262002 20 0.000284 30 0.0 10 3.628854 20 2.447686 30 0.0 10 1.359145 20 2.447686 30 0.0 10 0.763023 20 0.000284 30 0.0 10 0.000282 20 0.000284 30 0.0 0 LWPOLYLINE 5 101 100 AcDbEntity 8 A 62 7 100 AcDbPolyline 90 6 70 0 10 1.566492 20 3.318596 30 0.0 10 3.406696 20 3.318596 30 0.0 10 2.840195 20 5.556534 30 0.0 10 2.455122 20 7.232228 30 0.0 10 2.162615 20 5.688811 30 0.0 10 1.566492 20 3.318596 30 0.0 0 LWPOLYLINE 5 102 100 AcDbEntity 8 B 62 7 100 AcDbPolyline 90 15 70 0 10 0.000282 20 0.000284 30 0.0 10 0.000282 20 8.081096 30 0.0 10 2.524221 20 8.081096 30 0.0 10 3.760951 20 7.835817 30 0.0 10 4.490598 20 7.080646 30 0.0 10 4.754465 20 6.014044 30 0.0 10 4.520427 20 5.038402 30 0.0 10 3.813724 20 4.299770 30 0.0 10 4.752170 20 3.566641 30 0.0 10 5.080282 20 2.342954 30 0.0 10 4.880661 20 1.287358 30 0.0 10 4.387346 20 0.534954 30 0.0 10 3.650815 20 0.135327 30 0.0 10 2.565522 20 0.000284 30 0.0 10 0.000282 20 0.000284 30 0.0 0 LWPOLYLINE 5 103 100 AcDbEntity 8 B 62 7 100 AcDbPolyline 90 10 70 0 10 0.890544 20 4.685624 30 0.0 10 2.345251 20 4.685624 30 0.0 10 3.194212 20 4.779322 30 0.0 10 3.705883 20 5.181714 30 0.0 10 3.877970 20 5.887270 30 0.0 10 3.717355 20 6.595563 30 0.0 10 3.258457 20 7.014494 30 0.0 10 2.235115 20 7.127495 30 0.0 10 0.890544 20 7.127495 30 0.0 10 0.890544 20 4.685624 30 0.0 0 LWPOLYLINE 5 104 100 AcDbEntity 8 B 62 7 100 AcDbPolyline 90 11 70 0 10 0.890544 20 0.953884 30 0.0 10 2.565522 20 0.953884 30 0.0 10 3.171267 20 0.992464 30 0.0 10 3.685233 20 1.212964 30 0.0 10 4.024817 20 1.662206 30 0.0 10 4.157897 20 2.342954 30 0.0 10 3.965160 20 3.128435 30 0.0 10 3.430544 20 3.596952 30 0.0 10 2.446208 20 3.732023 30 0.0 10 0.890544 20 3.732023 30 0.0 10 0.890544 20 0.953884 30 0.0 0 LWPOLYLINE 5 105 100 AcDbEntity 8 C 62 7 100 AcDbPolyline 90 23 70 0 10 4.319850 20 2.971322 30 0.0 10 5.080282 20 2.701235 30 0.0 10 4.219896 20 0.692067 30 0.0 10 2.700992 20 0.000284 30 0.0 10 1.189927 20 0.532216 30 0.0 10 0.304063 20 2.072839 30 0.0 10 0.000282 20 4.239120 30 0.0 10 0.343261 20 6.441244 30 0.0 10 1.319279 20 7.868893 30 0.0 10 2.712751 20 8.356714 30 0.0 10 4.163060 20 7.739353 30 0.0 10 4.982288 20 6.003009 30 0.0 10 4.233616 20 5.754964 30 0.0 10 3.653492 20 7.039301 30 0.0 10 2.697072 20 7.441693 30 0.0 10 1.589742 20 6.995218 30 0.0 10 0.964541 20 5.796310 30 0.0 10 0.784233 20 4.244652 30 0.0 10 0.997859 20 2.444921 30 0.0 10 1.662258 20 1.295627 30 0.0 10 2.638276 20 0.915304 30 0.0 10 3.720128 20 1.433436 30 0.0 10 4.319850 20 2.971322 30 0.0 0 LWPOLYLINE 5 106 100 AcDbEntity 8 D 62 7 100 AcDbPolyline 90 13 70 0 10 0.000282 20 0.000284 30 0.0 10 0.000282 20 8.081096 30 0.0 10 2.116949 20 8.081096 30 0.0 10 3.210909 20 7.965357 30 0.0 10 4.112064 20 7.386575 30 0.0 10 4.839276 20 6.005775 30 0.0 10 5.080282 20 4.084801 30 0.0 10 4.916817 20 2.453190 30 0.0 10 4.497675 20 1.276351 30 0.0 10 3.938120 20 0.543223 30 0.0 10 3.204622 20 0.138093 30 0.0 10 2.217543 20 0.000284 30 0.0 10 0.000282 20 0.000284 30 0.0 0 LWPOLYLINE 5 107 100 AcDbEntity 8 D 62 7 100 AcDbPolyline 90 11 70 0 10 0.813418 20 0.953884 30 0.0 10 2.125332 20 0.953884 30 0.0 10 3.078880 20 1.102700 30 0.0 10 3.630051 20 1.521631 30 0.0 10 4.080629 20 2.544150 30 0.0 10 4.241998 20 4.101311 30 0.0 10 3.925546 20 6.049858 30 0.0 10 3.156421 20 6.962141 30 0.0 10 2.104375 20 7.127495 30 0.0 10 0.813418 20 7.127495 30 0.0 10 0.813418 20 0.953884 30 0.0 0 LWPOLYLINE 5 108 100 AcDbEntity 8 E 62 7 100 AcDbPolyline 90 15 70 0 10 0.000282 20 0.000284 30 0.0 10 0.000282 20 8.081096 30 0.0 10 0.910743 20 8.081096 30 0.0 10 4.922403 20 8.081096 30 0.0 10 4.922403 20 7.127495 30 0.0 10 0.901123 20 7.127495 30 0.0 10 0.901123 20 4.652548 30 0.0 10 4.667010 20 4.652548 30 0.0 10 4.667010 20 3.704450 30 0.0 10 0.901123 20 3.704450 30 0.0 10 0.901123 20 0.953884 30 0.0 10 5.080282 20 0.953884 30 0.0 10 5.080282 20 0.000284 30 0.0 10 0.910743 20 0.028732 30 0.0 10 0.000282 20 0.000284 30 0.0 0 LWPOLYLINE 5 109 100 AcDbEntity 8 F 62 7 100 AcDbPolyline 90 11 70 0 10 0.000564 20 0.000284 30 0.0 10 0.000564 20 8.081096 30 0.0 10 5.080564 20 8.081096 30 0.0 10 5.080564 20 7.127495 30 0.0 10 0.997046 20 7.127495 30 0.0 10 0.997046 20 4.624974 30 0.0 10 4.530959 20 4.624974 30 0.0 10 4.530959 20 3.671374 30 0.0 10 0.997046 20 3.671374 30 0.0 10 0.997046 20 0.000284 30 0.0 10 0.000564 20 0.000284 30 0.0 0 LWPOLYLINE 5 10a 100 AcDbEntity 8 G 62 7 100 AcDbPolyline 90 30 70 0 10 2.753822 20 3.307561 30 0.0 10 2.753822 20 4.255658 30 0.0 10 5.080282 20 4.261303 30 0.0 10 5.080282 20 1.262692 30 0.0 10 3.975120 20 0.317332 30 0.0 10 2.806270 20 0.000396 30 0.0 10 1.335843 20 0.510259 30 0.0 10 0.337450 20 1.984757 30 0.0 10 0.000282 20 4.140032 30 0.0 10 0.335577 20 6.342127 30 0.0 10 1.300253 20 7.860737 30 0.0 10 2.750076 20 8.356827 30 0.0 10 3.827141 20 8.072940 30 0.0 10 4.582023 20 7.281956 30 0.0 10 4.997863 20 5.959039 30 0.0 10 4.342259 20 5.694456 30 0.0 10 4.035061 20 6.664594 30 0.0 10 3.510577 20 7.229575 30 0.0 10 2.753822 20 7.441806 30 0.0 10 1.892170 20 7.218568 30 0.0 10 1.305872 20 6.631518 30 0.0 10 0.959338 20 5.832265 30 0.0 10 0.749545 20 4.206157 30 0.0 10 1.002421 20 2.398185 30 0.0 10 1.738571 20 1.317810 30 0.0 10 2.765061 20 0.965032 30 0.0 10 3.686654 20 1.232353 30 0.0 10 4.368483 20 1.802865 30 0.0 10 4.368483 20 3.307674 30 0.0 10 2.753822 20 3.307561 30 0.0 0 LWPOLYLINE 5 10b 100 AcDbEntity 8 H 62 7 100 AcDbPolyline 90 13 70 0 10 0.000282 20 0.000284 30 0.0 10 0.000282 20 8.081096 30 0.0 10 0.857256 20 8.081096 30 0.0 10 0.857256 20 4.762784 30 0.0 10 4.223308 20 4.762784 30 0.0 10 4.223308 20 8.081096 30 0.0 10 5.080282 20 8.081096 30 0.0 10 5.080282 20 0.000284 30 0.0 10 4.223308 20 0.000284 30 0.0 10 4.223308 20 3.809183 30 0.0 10 0.857256 20 3.809183 30 0.0 10 0.857256 20 0.000284 30 0.0 10 0.000282 20 0.000284 30 0.0 0 LWPOLYLINE 5 10c 100 AcDbEntity 8 I 62 7 100 AcDbPolyline 90 5 70 0 10 1.975556 20 0.000288 30 0.0 10 1.975556 20 8.081101 30 0.0 10 3.044913 20 8.081101 30 0.0 10 3.044913 20 0.000288 30 0.0 10 1.975556 20 0.000288 30 0.0 0 LWPOLYLINE 5 10d 100 AcDbEntity 8 J 62 7 100 AcDbPolyline 90 15 70 0 10 0.001110 20 2.431153 30 0.0 10 0.965737 20 2.563431 30 0.0 10 1.313003 20 1.295632 30 0.0 10 2.167386 20 0.953889 30 0.0 10 2.861918 20 1.138547 30 0.0 10 3.264305 20 1.640141 30 0.0 10 3.374548 20 2.651625 30 0.0 10 3.374548 20 8.218910 30 0.0 10 4.443906 20 8.218910 30 0.0 10 4.443906 20 2.712275 30 0.0 10 4.198615 20 1.141313 30 0.0 10 3.421401 20 0.292417 30 0.0 10 2.172899 20 0.000288 30 0.0 10 0.544057 20 0.612146 30 0.0 10 0.001110 20 2.431153 30 0.0 0 LWPOLYLINE 5 10e 100 AcDbEntity 8 K 62 7 100 AcDbPolyline 90 13 70 0 10 0.000282 20 0.000284 30 0.0 10 0.000282 20 8.081096 30 0.0 10 0.813418 20 8.081096 30 0.0 10 0.813418 20 4.073766 30 0.0 10 3.864771 20 8.081096 30 0.0 10 4.967114 20 8.081096 30 0.0 10 2.389391 20 4.806867 30 0.0 10 5.080282 20 0.000284 30 0.0 10 4.007279 20 0.000284 30 0.0 10 1.819358 20 4.090304 30 0.0 10 0.813418 20 2.800464 30 0.0 10 0.813418 20 0.000284 30 0.0 10 0.000282 20 0.000284 30 0.0 0 LWPOLYLINE 5 10f 100 AcDbEntity 8 L 62 7 100 AcDbPolyline 90 7 70 0 10 0.000564 20 0.000284 30 0.0 10 0.000564 20 8.081096 30 0.0 10 1.069922 20 8.081096 30 0.0 10 1.069922 20 0.953884 30 0.0 10 5.049696 20 0.953884 30 0.0 10 5.049696 20 0.000284 30 0.0 10 0.000564 20 0.000284 30 0.0 0 LWPOLYLINE 5 110 100 AcDbEntity 8 M 62 7 100 AcDbPolyline 90 16 70 0 10 0.000282 20 0.000284 30 0.0 10 0.000282 20 8.081096 30 0.0 10 1.060582 20 8.081096 30 0.0 10 2.320597 20 2.359492 30 0.0 10 2.574778 20 1.163350 30 0.0 10 2.858009 20 2.458693 30 0.0 10 4.132548 20 8.081096 30 0.0 10 5.080282 20 8.081096 30 0.0 10 5.080282 20 0.000284 30 0.0 10 4.401254 20 0.000284 30 0.0 10 4.401254 20 6.763683 30 0.0 10 2.854378 20 0.000284 30 0.0 10 2.218924 20 0.000284 30 0.0 10 0.679310 20 6.879450 30 0.0 10 0.679310 20 0.000284 30 0.0 10 0.000282 20 0.000284 30 0.0 0 LWPOLYLINE 5 111 100 AcDbEntity 8 N 62 7 100 AcDbPolyline 90 11 70 0 10 0.000564 20 0.000284 30 0.0 10 0.000564 20 8.081096 30 0.0 10 0.875820 20 8.081096 30 0.0 10 4.262486 20 1.736599 30 0.0 10 4.262486 20 8.081096 30 0.0 10 5.080564 20 8.081096 30 0.0 10 5.080564 20 0.000284 30 0.0 10 4.205309 20 0.000284 30 0.0 10 0.818642 20 6.350284 30 0.0 10 0.818642 20 0.000284 30 0.0 10 0.000564 20 0.000284 30 0.0 0 LWPOLYLINE 5 112 100 AcDbEntity 8 O 62 7 100 AcDbPolyline 90 12 70 0 10 0.000282 20 4.073766 30 0.0 10 0.710468 20 7.223959 30 0.0 10 2.543906 20 8.362218 30 0.0 10 3.870068 20 7.827548 30 0.0 10 4.770482 20 6.336511 30 0.0 10 5.080282 20 4.167464 30 0.0 10 4.754177 20 1.968134 30 0.0 10 3.830211 20 0.499140 30 0.0 10 2.540282 20 0.000284 30 0.0 10 1.199626 20 0.551492 30 0.0 10 0.304647 20 2.056329 30 0.0 10 0.000282 20 4.073766 30 0.0 0 LWPOLYLINE 5 113 100 AcDbEntity 8 O 62 7 100 AcDbPolyline 90 10 70 0 10 0.724961 20 4.057115 30 0.0 10 1.241295 20 1.755790 30 0.0 10 2.536659 20 0.915192 30 0.0 10 3.842893 20 1.764060 30 0.0 10 4.355603 20 4.172883 30 0.0 10 4.136388 20 5.895426 30 0.0 10 3.495047 20 7.036422 30 0.0 10 2.547529 20 7.441580 30 0.0 10 1.263035 20 6.661603 30 0.0 10 0.724961 20 4.057115 30 0.0 0 LWPOLYLINE 5 114 100 AcDbEntity 8 P 62 7 100 AcDbPolyline 90 12 70 0 10 0.000282 20 0.000284 30 0.0 10 0.000282 20 8.081096 30 0.0 10 2.510774 20 8.081096 30 0.0 10 3.523142 20 8.003936 30 0.0 10 4.344840 20 7.626351 30 0.0 10 4.878262 20 6.846374 30 0.0 10 5.080282 20 5.743957 30 0.0 10 4.540050 20 3.999344 30 0.0 10 2.587950 20 3.285520 30 0.0 10 0.880997 20 3.285520 30 0.0 10 0.880997 20 0.000284 30 0.0 10 0.000282 20 0.000284 30 0.0 0 LWPOLYLINE 5 115 100 AcDbEntity 8 P 62 7 100 AcDbPolyline 90 9 70 0 10 0.880997 20 4.239120 30 0.0 10 2.601569 20 4.239120 30 0.0 10 3.813687 20 4.624974 30 0.0 10 4.172329 20 5.710881 30 0.0 10 3.961230 20 6.579025 30 0.0 10 3.405108 20 7.055839 30 0.0 10 2.583410 20 7.127495 30 0.0 10 0.880997 20 7.127495 30 0.0 10 0.880997 20 4.239120 30 0.0 0 LWPOLYLINE 5 116 100 AcDbEntity 8 Q 62 7 100 AcDbPolyline 90 16 70 0 10 4.195723 20 1.494086 30 0.0 10 5.080282 20 0.744419 30 0.0 10 4.877793 20 0.000284 30 0.0 10 3.758772 20 0.992464 30 0.0 10 2.479891 20 0.490870 30 0.0 10 1.197457 20 1.020037 30 0.0 10 0.311121 20 2.508308 30 0.0 10 0.000282 20 4.669086 30 0.0 10 0.312898 20 6.846374 30 0.0 10 1.202786 20 8.340176 30 0.0 10 2.494100 20 8.852804 30 0.0 10 3.794296 20 8.320872 30 0.0 10 4.677079 20 6.832601 30 0.0 10 4.980814 20 4.674589 30 0.0 10 4.785429 20 2.880390 30 0.0 10 4.195723 20 1.494086 30 0.0 0 LWPOLYLINE 5 117 100 AcDbEntity 8 Q 62 7 100 AcDbPolyline 90 13 70 0 10 2.678828 20 2.861086 30 0.0 10 3.662856 20 2.089377 30 0.0 10 4.270324 20 4.674589 30 0.0 10 4.055401 20 6.388863 30 0.0 10 3.426618 20 7.527122 30 0.0 10 2.497653 20 7.932280 30 0.0 10 1.218772 20 7.113723 30 0.0 10 0.710772 20 4.669086 30 0.0 10 1.213443 20 2.249228 30 0.0 10 2.497653 20 1.405891 30 0.0 10 3.193933 20 1.620860 30 0.0 10 2.511863 20 2.083874 30 0.0 10 2.678828 20 2.861086 30 0.0 0 LWPOLYLINE 5 118 100 AcDbEntity 8 R 62 7 100 AcDbPolyline 90 20 70 0 10 0.000282 20 0.000284 30 0.0 10 0.000282 20 8.081096 30 0.0 10 2.556010 20 8.081096 30 0.0 10 3.727713 20 7.863362 30 0.0 10 4.368610 20 7.094419 30 0.0 10 4.608456 20 5.876235 30 0.0 10 4.211335 20 4.426544 30 0.0 10 2.984586 20 3.676877 30 0.0 10 3.444617 20 3.274513 30 0.0 10 4.077651 20 2.199641 30 0.0 10 5.080282 20 0.000284 30 0.0 10 4.120901 20 0.000284 30 0.0 10 3.358115 20 1.681481 30 0.0 10 2.807651 20 2.794933 30 0.0 10 2.420360 20 3.335134 30 0.0 10 2.072388 20 3.550103 30 0.0 10 1.647743 20 3.588683 30 0.0 10 0.763069 20 3.588683 30 0.0 10 0.763069 20 0.000284 30 0.0 10 0.000282 20 0.000284 30 0.0 0 LWPOLYLINE 5 119 100 AcDbEntity 8 R 62 7 100 AcDbPolyline 90 9 70 0 10 0.763069 20 4.514738 30 0.0 10 2.402666 20 4.514738 30 0.0 10 3.220499 20 4.666320 30 0.0 10 3.668734 20 5.151375 30 0.0 10 3.822078 20 5.876235 30 0.0 10 3.525220 20 6.818829 30 0.0 10 2.587465 20 7.188117 30 0.0 10 0.763069 20 7.188117 30 0.0 10 0.763069 20 4.514738 30 0.0 0 LWPOLYLINE 5 11a 100 AcDbEntity 8 S 62 7 100 AcDbPolyline 90 36 70 0 10 0.000282 20 2.734311 30 0.0 10 0.796889 20 2.822506 30 0.0 10 1.060248 20 1.827560 30 0.0 10 1.702322 20 1.199164 30 0.0 10 2.681756 20 0.959388 30 0.0 10 3.534952 20 1.141308 30 0.0 10 4.085612 20 1.640136 30 0.0 10 4.266263 20 2.331919 30 0.0 10 4.092142 20 2.996129 30 0.0 10 3.517540 20 3.472943 30 0.0 10 2.381396 20 3.867067 30 0.0 10 1.149485 20 4.371426 30 0.0 10 0.468234 20 5.123830 30 0.0 10 0.244053 20 6.129783 30 0.0 10 0.518294 20 7.273574 30 0.0 10 1.319254 20 8.081096 30 0.0 10 2.490222 20 8.356714 30 0.0 10 3.741722 20 8.067324 30 0.0 10 4.575329 20 7.215690 30 0.0 10 4.888748 20 5.942388 30 0.0 10 4.079082 20 5.865200 30 0.0 10 3.637249 20 7.022763 30 0.0 10 2.525047 20 7.414120 30 0.0 10 1.408491 20 7.058605 30 0.0 10 1.058071 20 6.201468 30 0.0 10 1.306195 20 5.484877 30 0.0 10 2.579460 20 4.908862 30 0.0 10 3.992022 20 4.393468 30 0.0 10 4.814747 20 3.569407 30 0.0 10 5.080282 20 2.420113 30 0.0 10 4.788628 20 1.204695 30 0.0 10 3.950668 20 0.317219 30 0.0 10 2.720933 20 0.000284 30 0.0 10 1.269194 20 0.319985 30 0.0 10 0.350702 20 1.281855 30 0.0 10 0.000282 20 2.734311 30 0.0 0 LWPOLYLINE 5 11b 100 AcDbEntity 8 T 62 7 100 AcDbPolyline 90 9 70 0 10 1.994539 20 0.000284 30 0.0 10 1.994539 20 7.127495 30 0.0 10 0.000282 20 7.127495 30 0.0 10 0.000282 20 8.081096 30 0.0 10 4.798060 20 8.081096 30 0.0 10 4.798060 20 7.127495 30 0.0 10 2.795545 20 7.127495 30 0.0 10 2.795545 20 0.000284 30 0.0 10 1.994539 20 0.000284 30 0.0 0 LWPOLYLINE 5 11c 100 AcDbEntity 8 U 62 7 100 AcDbPolyline 90 18 70 0 10 4.225538 20 8.218905 30 0.0 10 5.080282 20 8.218905 30 0.0 10 5.080282 20 3.550103 30 0.0 10 4.859987 20 1.615357 30 0.0 10 4.064723 20 0.449525 30 0.0 10 2.555703 20 0.000284 30 0.0 10 1.070915 20 0.391641 30 0.0 10 0.247012 20 1.524396 30 0.0 10 0.000282 20 3.550103 30 0.0 10 0.000282 20 8.218905 30 0.0 10 0.855026 20 8.218905 30 0.0 10 0.855026 20 3.555634 30 0.0 10 1.011436 20 2.003948 30 0.0 10 1.548955 20 1.235006 30 0.0 10 2.480803 20 0.964919 30 0.0 10 3.824601 20 1.499589 30 0.0 10 4.225538 20 3.555634 30 0.0 10 4.225538 20 8.218905 30 0.0 0 LWPOLYLINE 5 11d 100 AcDbEntity 8 V 62 7 100 AcDbPolyline 90 10 70 0 10 2.151990 20 0.000284 30 0.0 10 0.000282 20 8.081096 30 0.0 10 0.795808 20 8.081096 30 0.0 10 2.239119 20 2.210648 30 0.0 10 2.530812 20 0.887731 30 0.0 10 2.830081 20 2.210648 30 0.0 10 4.330215 20 8.081096 30 0.0 10 5.080282 20 8.081096 30 0.0 10 2.905845 20 0.000284 30 0.0 10 2.151990 20 0.000284 30 0.0 0 LWPOLYLINE 5 11e 100 AcDbEntity 8 W 62 7 100 AcDbPolyline 90 20 70 0 10 0.907511 20 -0.017355 30 0.0 10 0.000282 20 8.081096 30 0.0 10 0.677690 20 8.063598 30 0.0 10 1.137555 20 2.784067 30 0.0 10 1.304643 20 1.677220 30 0.0 10 1.482510 20 2.624216 30 0.0 10 2.234404 20 8.081237 30 0.0 10 2.865025 20 8.081237 30 0.0 10 3.430967 20 3.991216 30 0.0 10 3.826387 20 1.835970 30 0.0 10 3.934924 20 2.888800 30 0.0 10 4.413654 20 8.081237 30 0.0 10 5.080282 20 8.081237 30 0.0 10 4.279131 20 0.018064 30 0.0 10 3.492951 20 0.000566 30 0.0 10 2.642569 20 5.716666 30 0.0 10 2.518601 20 6.770597 30 0.0 10 2.367440 20 5.716666 30 0.0 10 1.582224 20 0.000566 30 0.0 10 0.907511 20 -0.017355 30 0.0 0 LWPOLYLINE 5 11f 100 AcDbEntity 8 X 62 7 100 AcDbPolyline 90 17 70 0 10 0.000282 20 0.000284 30 0.0 10 2.143407 20 4.211575 30 0.0 10 0.253526 20 8.081096 30 0.0 10 1.126651 20 8.081096 30 0.0 10 2.132068 20 6.008541 30 0.0 10 2.578080 20 5.016332 30 0.0 10 3.016532 20 5.936884 30 0.0 10 4.131562 20 8.081096 30 0.0 10 4.929092 20 8.081096 30 0.0 10 2.982514 20 4.272197 30 0.0 10 5.080282 20 0.000284 30 0.0 10 4.173139 20 0.000284 30 0.0 10 2.778407 20 2.883127 30 0.0 10 2.536503 20 3.423329 30 0.0 10 2.271919 20 2.817002 30 0.0 10 0.880967 20 0.000284 30 0.0 10 0.000282 20 0.000284 30 0.0 0 LWPOLYLINE 5 120 100 AcDbEntity 8 Y 62 7 100 AcDbPolyline 90 12 70 0 10 2.135848 20 0.000288 30 0.0 10 2.135848 20 3.423334 30 0.0 10 0.000282 20 8.081129 30 0.0 10 0.892306 20 8.081129 30 0.0 10 1.984657 20 5.644733 30 0.0 10 2.547842 20 4.277733 30 0.0 10 3.152604 20 5.705382 30 0.0 10 4.226056 20 8.081129 30 0.0 10 5.080282 20 8.081129 30 0.0 10 2.869122 20 3.423334 30 0.0 10 2.869122 20 0.000288 30 0.0 10 2.135848 20 0.000288 30 0.0 0 LWPOLYLINE 5 121 100 AcDbEntity 8 Z 62 7 100 AcDbPolyline 90 13 70 0 10 0.000282 20 0.000284 30 0.0 10 0.000282 20 0.992464 30 0.0 10 3.291982 20 6.168391 30 0.0 10 3.958211 20 7.127495 30 0.0 10 0.372845 20 7.127495 30 0.0 10 0.372845 20 8.081096 30 0.0 10 4.975088 20 8.081096 30 0.0 10 4.975088 20 7.127495 30 0.0 10 1.367806 20 1.521631 30 0.0 10 0.977711 20 0.953884 30 0.0 10 5.080282 20 0.953884 30 0.0 10 5.080282 20 0.000284 30 0.0 10 0.000282 20 0.000284 30 0.0 0 LWPOLYLINE 5 122 100 AcDbEntity 8 1 62 7 100 AcDbPolyline 90 10 70 0 10 3.823229 20 0.000284 30 0.0 10 2.831042 20 0.000284 30 0.0 10 2.831042 20 6.322710 30 0.0 10 1.891220 20 5.639225 30 0.0 10 0.846667 20 5.126596 30 0.0 10 0.846667 20 6.085700 30 0.0 10 2.301875 20 7.033798 30 0.0 10 3.183819 20 8.114172 30 0.0 10 3.823229 20 8.114172 30 0.0 10 3.823229 20 0.000284 30 0.0 0 LWPOLYLINE 5 123 100 AcDbEntity 8 2 62 7 100 AcDbPolyline 90 23 70 0 10 4.798942 20 0.953884 30 0.0 10 4.798942 20 0.000284 30 0.0 10 0.001164 20 0.000284 30 0.0 10 0.105141 20 0.689301 30 0.0 10 0.691866 20 1.764172 30 0.0 10 1.857889 20 2.987860 30 0.0 10 3.457149 20 4.699396 30 0.0 10 3.873055 20 5.892773 30 0.0 10 3.494283 20 6.887719 30 0.0 10 2.506505 20 7.292849 30 0.0 10 1.476642 20 6.862912 30 0.0 10 1.085492 20 5.672301 30 0.0 10 0.169507 20 5.777006 30 0.0 10 0.877538 20 7.516115 30 0.0 10 2.526310 20 8.114172 30 0.0 10 4.180034 20 7.469238 30 0.0 10 4.789039 20 5.870732 30 0.0 10 4.610794 20 4.917131 30 0.0 10 4.019117 20 3.930454 30 0.0 10 2.645141 20 2.508308 30 0.0 10 1.615277 20 1.491320 30 0.0 10 1.238981 20 0.953884 30 0.0 10 4.798942 20 0.953884 30 0.0 0 LWPOLYLINE 5 124 100 AcDbEntity 8 3 62 7 100 AcDbPolyline 90 31 70 0 10 0.000282 20 2.276801 30 0.0 10 0.899866 20 2.409107 30 0.0 10 1.427121 20 1.193660 30 0.0 10 2.334201 20 0.821607 30 0.0 10 3.406205 20 1.306662 30 0.0 10 3.843502 20 2.508308 30 0.0 10 3.438690 20 3.635560 30 0.0 10 2.409166 20 4.079270 30 0.0 10 1.774460 20 3.969034 30 0.0 10 1.874414 20 4.839943 30 0.0 10 2.019347 20 4.828936 30 0.0 10 3.053868 20 5.159644 30 0.0 10 3.513655 20 6.179398 30 0.0 10 3.178810 20 7.083412 30 0.0 10 2.314210 20 7.441693 30 0.0 10 1.439616 20 7.077881 30 0.0 10 0.989824 20 5.986471 30 0.0 10 0.090241 20 6.162860 30 0.0 10 0.839893 20 7.709014 30 0.0 10 2.294220 20 8.257485 30 0.0 10 3.398708 20 7.973598 30 0.0 10 4.170850 20 7.199152 30 0.0 10 4.438227 20 6.157356 30 0.0 10 4.183345 20 5.203756 30 0.0 10 3.428694 20 4.520242 30 0.0 10 4.438227 20 3.833990 30 0.0 10 4.798060 20 2.530349 30 0.0 10 4.098384 20 0.736150 30 0.0 10 2.329204 20 0.000284 30 0.0 10 0.727445 20 0.634183 30 0.0 10 0.000282 20 2.276801 30 0.0 0 LWPOLYLINE 5 125 100 AcDbEntity 8 4 62 7 100 AcDbPolyline 90 12 70 0 10 3.009539 20 0.000284 30 0.0 10 3.009539 20 1.935058 30 0.0 10 0.000282 20 1.935058 30 0.0 10 0.000282 20 2.844547 30 0.0 10 3.165680 20 8.081096 30 0.0 10 3.861216 20 8.081096 30 0.0 10 3.861216 20 2.844547 30 0.0 10 4.798060 20 2.844547 30 0.0 10 4.798060 20 1.935058 30 0.0 10 3.861216 20 1.935058 30 0.0 10 3.861216 20 0.000284 30 0.0 10 3.009539 20 0.000284 30 0.0 0 LWPOLYLINE 5 126 100 AcDbEntity 8 4 62 7 100 AcDbPolyline 90 4 70 0 10 3.009539 20 2.844547 30 0.0 10 3.009539 20 6.488093 30 0.0 10 0.837764 20 2.844547 30 0.0 10 3.009539 20 2.844547 30 0.0 0 LWPOLYLINE 5 127 100 AcDbEntity 8 5 62 7 100 AcDbPolyline 90 23 70 0 10 0.000282 20 2.254736 30 0.0 10 0.933183 20 2.342930 30 0.0 10 1.414442 20 1.199168 30 0.0 10 2.325131 20 0.816080 30 0.0 10 3.411048 20 1.356282 30 0.0 10 3.855287 20 2.789434 30 0.0 10 3.428324 20 4.128889 30 0.0 10 2.310323 20 4.619476 30 0.0 10 1.535374 20 4.401742 30 0.0 10 0.992415 20 3.836733 30 0.0 10 0.158234 20 3.958004 30 0.0 10 0.859144 20 8.108646 30 0.0 10 4.457477 20 8.108646 30 0.0 10 4.457477 20 7.160577 30 0.0 10 1.569926 20 7.160577 30 0.0 10 1.179983 20 4.988764 30 0.0 10 2.547251 20 5.495889 30 0.0 10 4.146510 20 4.762788 30 0.0 10 4.798060 20 2.877629 30 0.0 10 4.225486 20 0.981434 30 0.0 10 2.325131 20 0.000288 30 0.0 10 0.713532 20 0.617650 30 0.0 10 0.000282 20 2.254736 30 0.0 0 LWPOLYLINE 5 128 100 AcDbEntity 8 6 62 7 100 AcDbPolyline 90 20 70 0 10 4.669194 20 6.240048 30 0.0 10 3.782002 20 6.162860 30 0.0 10 3.444968 20 7.011728 30 0.0 10 2.552819 20 7.436190 30 0.0 10 1.804405 20 7.171607 30 0.0 10 1.140250 20 6.173895 30 0.0 10 0.887475 20 4.305273 30 0.0 10 1.675539 20 5.115561 30 0.0 10 2.651947 20 5.380145 30 0.0 10 4.171078 20 4.649782 30 0.0 10 4.798060 20 2.761884 30 0.0 10 4.503155 20 1.348008 30 0.0 10 3.692787 20 0.347558 30 0.0 10 2.523081 20 0.000284 30 0.0 10 0.704088 20 0.912539 30 0.0 10 0.000282 20 3.919419 30 0.0 10 0.778434 20 7.325926 30 0.0 10 2.607339 20 8.251982 30 0.0 10 4.012474 20 7.717283 30 0.0 10 4.669194 20 6.240048 30 0.0 0 LWPOLYLINE 5 129 100 AcDbEntity 8 6 62 7 100 AcDbPolyline 90 10 70 0 10 1.026253 20 2.756353 30 0.0 10 1.222030 20 1.775207 30 0.0 10 1.769711 20 1.061383 30 0.0 10 2.508212 20 0.816075 30 0.0 10 3.479663 20 1.323200 30 0.0 10 3.886086 20 2.701235 30 0.0 10 3.484619 20 4.021386 30 0.0 10 2.473517 20 4.503704 30 0.0 10 1.447546 20 4.021386 30 0.0 10 1.026253 20 2.756353 30 0.0 0 LWPOLYLINE 5 12a 100 AcDbEntity 8 7 62 7 100 AcDbPolyline 90 12 70 0 10 0.000282 20 7.022763 30 0.0 10 0.000282 20 7.976363 30 0.0 10 4.798060 20 7.976363 30 0.0 10 4.798060 20 7.204655 30 0.0 10 3.395127 20 5.021864 30 0.0 10 2.320809 20 2.221683 30 0.0 10 1.971972 20 0.000284 30 0.0 10 1.036683 20 0.000284 30 0.0 10 1.380465 20 2.304374 30 0.0 10 2.323337 20 4.908862 30 0.0 10 3.630213 20 7.022763 30 0.0 10 0.000282 20 7.022763 30 0.0 0 LWPOLYLINE 5 12b 100 AcDbEntity 8 8 62 7 100 AcDbPolyline 90 17 70 0 10 1.385976 20 4.520242 30 0.0 10 0.561513 20 5.165176 30 0.0 10 0.293314 20 6.168391 30 0.0 10 0.864478 20 7.651159 30 0.0 10 2.384271 20 8.251982 30 0.0 10 3.918964 20 7.637358 30 0.0 10 4.500061 20 6.140818 30 0.0 10 4.234346 20 5.162410 30 0.0 10 3.427266 20 4.520242 30 0.0 10 4.447911 20 3.737527 30 0.0 10 4.798060 20 2.447686 30 0.0 10 4.137496 20 0.705839 30 0.0 10 2.399171 20 0.000284 30 0.0 10 0.660846 20 0.708605 30 0.0 10 0.000282 20 2.475231 30 0.0 10 0.360364 20 3.795410 30 0.0 10 1.385976 20 4.520242 30 0.0 0 LWPOLYLINE 5 12c 100 AcDbEntity 8 8 62 7 100 AcDbPolyline 90 9 70 0 10 1.207177 20 6.201468 30 0.0 10 1.539942 20 5.264377 30 0.0 10 2.404138 20 4.900593 30 0.0 10 3.250950 20 5.261640 30 0.0 10 3.581232 20 6.146322 30 0.0 10 3.241017 20 7.064108 30 0.0 10 2.394204 20 7.436190 30 0.0 10 1.544908 20 7.072377 30 0.0 10 1.207177 20 6.201468 30 0.0 0 LWPOLYLINE 5 12d 100 AcDbEntity 8 8 62 7 100 AcDbPolyline 90 10 70 0 10 0.919111 20 2.469728 30 0.0 10 1.100394 20 1.648405 30 0.0 10 1.639275 20 1.033810 30 0.0 10 2.409104 20 0.816075 30 0.0 10 3.467000 20 1.273586 30 0.0 10 3.884198 20 2.436652 30 0.0 10 3.454583 20 3.621759 30 0.0 10 2.379305 20 4.090304 30 0.0 10 1.333826 20 3.627291 30 0.0 10 0.919111 20 2.469728 30 0.0 0 LWPOLYLINE 5 12e 100 AcDbEntity 8 9 62 7 100 AcDbPolyline 90 23 70 0 10 0.134660 20 2.006714 30 0.0 10 0.995672 20 2.094909 30 0.0 10 1.413735 20 1.119238 30 0.0 10 2.205070 20 0.816075 30 0.0 10 2.929216 20 1.025540 30 0.0 10 3.439353 20 1.585018 30 0.0 10 3.772809 20 2.530349 30 0.0 10 3.907186 20 3.743030 30 0.0 10 3.902210 20 3.941460 30 0.0 10 3.168110 20 3.172518 30 0.0 10 2.160278 20 2.877624 30 0.0 10 0.627378 20 3.605221 30 0.0 10 0.000283 20 5.523457 30 0.0 10 0.654751 20 7.502315 30 0.0 10 2.294656 20 8.251982 30 0.0 10 3.596127 20 7.827548 30 0.0 10 4.491978 20 6.617633 30 0.0 10 4.798060 20 4.343853 30 0.0 10 4.494467 20 1.877174 30 0.0 10 3.591150 20 0.479836 30 0.0 10 2.185163 20 0.000284 30 0.0 10 0.786640 20 0.526684 30 0.0 10 0.134660 20 2.006714 30 0.0 0 LWPOLYLINE 5 12f 100 AcDbEntity 8 9 62 7 100 AcDbPolyline 90 9 70 0 10 3.802670 20 5.573072 30 0.0 10 3.392072 20 6.929065 30 0.0 10 2.404148 20 7.430658 30 0.0 10 1.363966 20 6.890485 30 0.0 10 0.921018 20 5.490381 30 0.0 10 1.341570 20 4.236383 30 0.0 10 2.379263 20 3.754065 30 0.0 10 3.402026 20 4.236383 30 0.0 10 3.802670 20 5.573072 30 0.0 0 LWPOLYLINE 5 130 100 AcDbEntity 8 0 62 7 100 AcDbPolyline 90 13 70 0 10 0.000282 20 4.123381 30 0.0 10 0.268777 20 6.430209 30 0.0 10 1.066734 20 7.777933 30 0.0 10 2.399171 20 8.251982 30 0.0 10 3.438020 20 7.990136 30 0.0 10 4.175754 20 7.234994 30 0.0 10 4.632446 20 6.033320 30 0.0 10 4.798060 20 4.123381 30 0.0 10 4.532074 20 1.827560 30 0.0 10 3.736627 20 0.477070 30 0.0 10 2.399171 20 0.000284 30 0.0 10 0.727979 20 0.838117 30 0.0 10 0.000282 20 4.123381 30 0.0 0 LWPOLYLINE 5 131 100 AcDbEntity 8 0 62 7 100 AcDbPolyline 90 9 70 0 10 0.928722 20 4.123381 30 0.0 10 1.352794 20 1.474782 30 0.0 10 2.399171 20 0.816075 30 0.0 10 3.445548 20 1.477548 30 0.0 10 3.869620 20 4.123381 30 0.0 10 3.445548 20 6.774718 30 0.0 10 2.389134 20 7.430658 30 0.0 10 1.395452 20 6.851877 30 0.0 10 0.928722 20 4.123381 30 0.0 0 LWPOLYLINE 5 132 100 AcDbEntity 8 a_ 62 7 100 AcDbPolyline 90 28 70 0 10 4.156446 20 0.854655 30 0.0 10 3.095356 20 0.193211 30 0.0 10 2.001194 20 0.000284 30 0.0 10 0.518425 20 0.471566 30 0.0 10 0.000282 20 1.675978 30 0.0 10 0.195964 20 2.461459 30 0.0 10 0.708594 20 3.031971 30 0.0 10 1.422418 20 3.357176 30 0.0 10 2.304362 20 3.506020 30 0.0 10 4.073763 20 3.847763 30 0.0 10 4.079275 20 4.106843 30 0.0 10 3.798155 20 4.961214 30 0.0 10 2.668164 20 5.297454 30 0.0 10 1.634635 20 5.052174 30 0.0 10 1.141298 20 4.184002 30 0.0 10 0.171159 20 4.316308 30 0.0 10 0.606619 20 5.322261 30 0.0 10 1.483051 20 5.912077 30 0.0 10 2.811480 20 6.118777 30 0.0 10 4.029666 20 5.942388 30 0.0 10 4.718685 20 5.498650 30 0.0 10 5.027365 20 4.823405 30 0.0 10 5.076975 20 3.908412 30 0.0 10 5.076975 20 2.585496 30 0.0 10 5.140365 20 0.835379 30 0.0 10 5.391167 20 0.132561 30 0.0 10 4.354883 20 0.132561 30 0.0 10 4.156446 20 0.854655 30 0.0 0 LWPOLYLINE 5 133 100 AcDbEntity 8 a_ 62 7 100 AcDbPolyline 90 11 70 0 10 4.073763 20 3.070551 30 0.0 10 2.453190 20 2.695732 30 0.0 10 1.587782 20 2.497301 30 0.0 10 1.196419 20 2.174834 30 0.0 10 1.058616 20 1.703551 30 0.0 10 1.359028 20 1.042079 30 0.0 10 2.238216 20 0.777495 30 0.0 10 3.257965 20 1.028306 30 0.0 10 3.913911 20 1.714558 30 0.0 10 4.073763 20 2.706738 30 0.0 10 4.073763 20 3.070551 30 0.0 0 LWPOLYLINE 5 134 100 AcDbEntity 8 b_ 62 7 100 AcDbPolyline 90 14 70 0 10 0.920812 20 0.132561 30 0.0 10 0.000282 20 0.132561 30 0.0 10 0.000282 20 8.213402 30 0.0 10 0.992470 20 8.213402 30 0.0 10 0.992470 20 5.330530 30 0.0 10 2.596506 20 6.118777 30 0.0 10 3.619011 20 5.901042 30 0.0 10 4.412761 20 5.289184 30 0.0 10 4.900586 20 4.338350 30 0.0 10 5.076975 20 3.147710 30 0.0 10 4.332834 20 0.821607 30 0.0 10 2.546897 20 0.000284 30 0.0 10 0.920812 20 0.865690 30 0.0 10 0.920812 20 0.132561 30 0.0 0 LWPOLYLINE 5 135 100 AcDbEntity 8 b_ 62 7 100 AcDbPolyline 90 9 70 0 10 0.909787 20 3.103627 30 0.0 10 1.196419 20 1.582280 30 0.0 10 2.464214 20 0.816075 30 0.0 10 3.588694 20 1.381084 30 0.0 10 4.062739 20 3.065048 30 0.0 10 3.607986 20 4.757280 30 0.0 10 2.508312 20 5.302985 30 0.0 10 1.383832 20 4.737976 30 0.0 10 0.909787 20 3.103627 30 0.0 0 LWPOLYLINE 5 136 100 AcDbEntity 8 c_ 62 7 100 AcDbPolyline 90 20 70 0 10 4.123372 20 2.276801 30 0.0 10 5.099023 20 2.150027 30 0.0 10 4.280469 20 0.570796 30 0.0 10 2.662652 20 0.000284 30 0.0 10 0.730642 20 0.785764 30 0.0 10 0.000282 20 3.037474 30 0.0 10 0.314475 20 4.696631 30 0.0 10 1.270833 20 5.763233 30 0.0 10 2.668164 20 6.118777 30 0.0 10 4.228103 20 5.636459 30 0.0 10 5.005317 20 4.266693 30 0.0 10 4.040690 20 4.117849 30 0.0 10 3.552865 20 5.005325 30 0.0 10 2.706749 20 5.302985 30 0.0 10 1.488563 20 4.765549 30 0.0 10 1.020031 20 3.065048 30 0.0 10 1.472027 20 1.350773 30 0.0 10 2.651628 20 0.816075 30 0.0 10 3.627279 20 1.174384 30 0.0 10 4.123372 20 2.276801 30 0.0 0 LWPOLYLINE 5 137 100 AcDbEntity 8 d_ 62 7 100 AcDbPolyline 90 15 70 0 10 4.156446 20 0.132561 30 0.0 10 4.156446 20 0.871193 30 0.0 10 2.519336 20 0.000284 30 0.0 10 1.232248 20 0.386138 30 0.0 10 0.322743 20 1.463747 30 0.0 10 0.000282 20 3.054013 30 0.0 10 0.292426 20 4.644278 30 0.0 10 1.168859 20 5.738426 30 0.0 10 2.475239 20 6.118777 30 0.0 10 3.417817 20 5.895539 30 0.0 10 4.090300 20 5.313992 30 0.0 10 4.090300 20 8.213402 30 0.0 10 5.076975 20 8.213402 30 0.0 10 5.076975 20 0.132561 30 0.0 10 4.156446 20 0.132561 30 0.0 0 LWPOLYLINE 5 138 100 AcDbEntity 8 d_ 62 7 100 AcDbPolyline 90 9 70 0 10 1.020031 20 3.054013 30 0.0 10 1.494076 20 1.372815 30 0.0 10 2.613043 20 0.816075 30 0.0 10 3.718229 20 1.348008 30 0.0 10 4.172982 20 2.971322 30 0.0 10 3.709961 20 4.735210 30 0.0 10 2.568945 20 5.297454 30 0.0 10 1.463759 20 4.757280 30 0.0 10 1.020031 20 3.054013 30 0.0 0 LWPOLYLINE 5 139 100 AcDbEntity 8 e_ 62 7 100 AcDbPolyline 90 16 70 0 10 4.338347 20 2.017721 30 0.0 10 5.363607 20 1.890947 30 0.0 10 4.465126 20 0.496374 30 0.0 10 2.789432 20 0.000284 30 0.0 10 0.752691 20 0.791268 30 0.0 10 0.000282 20 3.009930 30 0.0 10 0.760959 20 5.302985 30 0.0 10 2.734310 20 6.118777 30 0.0 10 4.652539 20 5.319523 30 0.0 10 5.396680 20 3.070551 30 0.0 10 5.391168 20 2.805968 30 0.0 10 1.025543 20 2.805968 30 0.0 10 1.571246 20 1.328704 30 0.0 10 2.794944 20 0.816075 30 0.0 10 3.726498 20 1.102700 30 0.0 10 4.338347 20 2.017721 30 0.0 0 LWPOLYLINE 5 13a 100 AcDbEntity 8 e_ 62 7 100 AcDbPolyline 90 6 70 0 10 1.080664 20 3.621759 30 0.0 10 4.349371 20 3.621759 30 0.0 10 3.974544 20 4.729707 30 0.0 10 2.745334 20 5.302985 30 0.0 10 1.596050 20 4.845475 30 0.0 10 1.080664 20 3.621759 30 0.0 0 LWPOLYLINE 5 13b 100 AcDbEntity 8 f_ 62 7 100 AcDbPolyline 90 20 70 0 10 2.287543 20 0.000288 30 0.0 10 2.287543 20 5.082490 30 0.0 10 1.411111 20 5.082490 30 0.0 10 1.411111 20 5.854198 30 0.0 10 2.287543 20 5.854198 30 0.0 10 2.287543 20 6.477063 30 0.0 10 2.392274 20 7.353504 30 0.0 10 2.896636 20 7.979134 30 0.0 10 3.908116 20 8.218910 30 0.0 10 4.834158 20 8.119681 30 0.0 10 4.685330 20 7.254274 30 0.0 10 4.101042 20 7.309392 30 0.0 10 3.461632 20 7.116465 30 0.0 10 3.274219 20 6.394372 30 0.0 10 3.274219 20 5.854198 30 0.0 10 4.415234 20 5.854198 30 0.0 10 4.415234 20 5.082490 30 0.0 10 3.274219 20 5.082490 30 0.0 10 3.274219 20 0.000288 30 0.0 10 2.287543 20 0.000288 30 0.0 0 LWPOLYLINE 5 13c 100 AcDbEntity 8 g_ 62 7 100 AcDbPolyline 90 22 70 0 10 0.198720 20 -0.367113 30 0.0 10 1.163346 20 -0.510426 30 0.0 10 1.499588 20 -1.160863 30 0.0 10 2.508312 20 -1.436453 30 0.0 10 3.572157 20 -1.160863 30 0.0 10 4.079275 20 -0.389155 30 0.0 10 4.150933 20 0.884147 30 0.0 10 2.530360 20 0.117970 30 0.0 10 0.661741 20 0.988880 30 0.0 10 0.000282 20 3.077973 30 0.0 10 0.303451 20 4.624156 30 0.0 10 1.182639 20 5.718303 30 0.0 10 2.535873 20 6.104158 30 0.0 10 4.244640 20 5.266324 30 0.0 10 4.244640 20 5.971880 30 0.0 10 5.159657 20 5.971880 30 0.0 10 5.159657 20 0.911720 30 0.0 10 4.881294 20 -1.025820 30 0.0 10 3.999349 20 -1.927040 30 0.0 10 2.513824 20 -2.257776 30 0.0 10 0.821593 20 -1.786494 30 0.0 10 0.198720 20 -0.367113 30 0.0 0 LWPOLYLINE 5 13d 100 AcDbEntity 8 g_ 62 7 100 AcDbPolyline 90 9 70 0 10 1.020030 20 3.149658 30 0.0 10 1.477539 20 1.468432 30 0.0 10 2.624067 20 0.939265 30 0.0 10 3.770595 20 1.465694 30 0.0 10 4.233616 20 3.116581 30 0.0 10 3.756814 20 4.737158 30 0.0 10 2.607531 20 5.282834 30 0.0 10 1.483051 20 4.745399 30 0.0 10 1.020030 20 3.149658 30 0.0 0 LWPOLYLINE 5 13e 100 AcDbEntity 8 h_ 62 7 100 AcDbPolyline 90 18 70 0 10 0.000282 20 0.000284 30 0.0 10 0.000282 20 8.081096 30 0.0 10 0.992470 20 8.081096 30 0.0 10 0.992470 20 5.181714 30 0.0 10 2.745334 20 5.986471 30 0.0 10 3.875326 20 5.730157 30 0.0 10 4.561589 20 5.021864 30 0.0 10 4.768294 20 3.709954 30 0.0 10 4.768294 20 0.000284 30 0.0 10 3.776107 20 0.000284 30 0.0 10 3.776107 20 3.709954 30 0.0 10 3.453646 20 4.793094 30 0.0 10 2.541385 20 5.132100 30 0.0 10 1.711806 20 4.903330 30 0.0 10 1.157834 20 4.283232 30 0.0 10 0.992470 20 3.202857 30 0.0 10 0.992470 20 0.000284 30 0.0 10 0.000282 20 0.000284 30 0.0 0 LWPOLYLINE 5 13f 100 AcDbEntity 8 i_ 62 7 100 AcDbPolyline 90 5 70 0 10 2.257778 20 6.940072 30 0.0 10 2.257778 20 8.081096 30 0.0 10 3.249965 20 8.081096 30 0.0 10 3.249965 20 6.940072 30 0.0 10 2.257778 20 6.940072 30 0.0 0 LWPOLYLINE 5 140 100 AcDbEntity 8 i_ 62 7 100 AcDbPolyline 90 5 70 0 10 2.257778 20 0.000284 30 0.0 10 2.257778 20 5.854193 30 0.0 10 3.249965 20 5.854193 30 0.0 10 3.249965 20 0.000284 30 0.0 10 2.257778 20 0.000284 30 0.0 0 LWPOLYLINE 5 141 100 AcDbEntity 8 j_ 62 7 100 AcDbPolyline 90 5 70 0 10 2.667882 20 9.304788 30 0.0 10 2.667882 20 10.456848 30 0.0 10 3.660069 20 10.456848 30 0.0 10 3.660069 20 9.304788 30 0.0 10 2.667882 20 9.304788 30 0.0 0 LWPOLYLINE 5 142 100 AcDbEntity 8 j_ 62 7 100 AcDbPolyline 90 11 70 0 10 1.411111 20 0.105021 30 0.0 10 1.598524 20 0.948386 30 0.0 10 2.067057 20 0.871198 30 0.0 10 2.519054 20 1.072394 30 0.0 10 2.667882 20 2.078375 30 0.0 10 2.667882 20 8.229945 30 0.0 10 3.660069 20 8.229945 30 0.0 10 3.660069 20 2.056334 30 0.0 10 3.378950 20 0.551497 30 0.0 10 2.188325 20 0.000288 30 0.0 10 1.411111 20 0.105021 30 0.0 0 LWPOLYLINE 5 143 100 AcDbEntity 8 k_ 62 7 100 AcDbPolyline 90 13 70 0 10 0.000282 20 0.000284 30 0.0 10 0.000282 20 8.081096 30 0.0 10 0.992470 20 8.081096 30 0.0 10 0.992470 20 3.472943 30 0.0 10 3.340647 20 5.854193 30 0.0 10 4.624978 20 5.854193 30 0.0 10 2.387044 20 3.682409 30 0.0 10 4.850977 20 0.000284 30 0.0 10 3.627279 20 0.000284 30 0.0 10 1.692513 20 2.993391 30 0.0 10 0.992470 20 2.320912 30 0.0 10 0.992470 20 0.000284 30 0.0 10 0.000282 20 0.000284 30 0.0 0 LWPOLYLINE 5 144 100 AcDbEntity 8 l_ 62 7 100 AcDbPolyline 90 5 70 0 10 2.257778 20 0.000284 30 0.0 10 2.257778 20 8.081096 30 0.0 10 3.249965 20 8.081096 30 0.0 10 3.249965 20 0.000284 30 0.0 10 2.257778 20 0.000284 30 0.0 0 LWPOLYLINE 5 145 100 AcDbEntity 8 m_ 62 7 100 AcDbPolyline 90 29 70 0 10 0.000282 20 0.000288 30 0.0 10 0.000282 20 5.854198 30 0.0 10 0.600225 20 5.854198 30 0.0 10 0.600225 20 5.032875 30 0.0 10 1.095830 20 5.724658 30 0.0 10 1.800111 20 5.986476 30 0.0 10 2.521160 20 5.716389 30 0.0 10 2.918017 20 4.961219 30 0.0 10 4.140261 20 5.986476 30 0.0 10 5.045764 20 5.504158 30 0.0 10 5.362504 20 4.018653 30 0.0 10 5.362504 20 0.000288 30 0.0 10 4.446036 20 0.000288 30 0.0 10 4.396145 20 3.638020 30 0.0 10 4.430715 20 4.445260 30 0.0 10 4.194091 20 4.866957 30 0.0 10 3.791645 20 4.777379 30 0.0 10 3.198324 20 4.316821 30 0.0 10 3.022355 20 3.401292 30 0.0 10 3.022355 20 0.000288 30 0.0 10 2.251830 20 -0.049608 30 0.0 10 2.152050 20 3.654022 30 0.0 10 2.037981 20 4.596306 30 0.0 10 1.651057 20 4.827248 30 0.0 10 1.327065 20 4.556879 30 0.0 10 0.928761 20 4.211298 30 0.0 10 0.970368 20 2.987582 30 0.0 10 1.020258 20 0.050185 30 0.0 10 0.000282 20 0.000288 30 0.0 0 LWPOLYLINE 5 146 100 AcDbEntity 8 n_ 62 7 100 AcDbPolyline 90 19 70 0 10 0.000564 20 0.000284 30 0.0 10 0.000564 20 5.854193 30 0.0 10 0.893533 20 5.854193 30 0.0 10 0.893533 20 5.021864 30 0.0 10 2.756641 20 5.986471 30 0.0 10 3.729536 20 5.796310 30 0.0 10 4.393750 20 5.297454 30 0.0 10 4.702431 20 4.564353 30 0.0 10 4.757552 20 3.599718 30 0.0 10 4.757552 20 0.000284 30 0.0 10 3.765365 20 0.000284 30 0.0 10 3.765365 20 3.561138 30 0.0 10 3.649610 20 4.467890 30 0.0 10 3.238954 20 4.947442 30 0.0 10 2.547179 20 5.126596 30 0.0 10 1.453017 20 4.724204 30 0.0 10 0.992752 20 3.197325 30 0.0 10 0.992752 20 0.000284 30 0.0 10 0.000564 20 0.000284 30 0.0 0 LWPOLYLINE 5 147 100 AcDbEntity 8 o_ 62 7 100 AcDbPolyline 90 10 70 0 10 0.000282 20 3.059516 30 0.0 10 0.904275 20 5.468339 30 0.0 10 2.745334 20 6.118777 30 0.0 10 4.718685 20 5.327764 30 0.0 10 5.484874 20 3.142207 30 0.0 10 5.145877 20 1.364546 30 0.0 10 4.159201 20 0.358565 30 0.0 10 2.745334 20 0.000284 30 0.0 10 0.758203 20 0.788530 30 0.0 10 0.000282 20 3.059516 30 0.0 0 LWPOLYLINE 5 148 100 AcDbEntity 8 o_ 62 7 100 AcDbPolyline 90 9 70 0 10 1.020031 20 3.059516 30 0.0 10 1.510612 20 1.375552 30 0.0 10 2.745334 20 0.816075 30 0.0 10 3.974544 20 1.378318 30 0.0 10 4.465126 20 3.092592 30 0.0 10 3.971788 20 4.737976 30 0.0 10 2.745334 20 5.297454 30 0.0 10 1.510612 20 4.740742 30 0.0 10 1.020031 20 3.059516 30 0.0 0 LWPOLYLINE 5 149 100 AcDbEntity 8 p_ 62 7 100 AcDbPolyline 90 16 70 0 10 0.000282 20 -2.257772 30 0.0 10 0.000282 20 5.839579 30 0.0 10 0.904275 20 5.839579 30 0.0 10 0.904275 20 5.078906 30 0.0 10 1.626367 20 5.748619 30 0.0 10 2.602018 20 5.971885 30 0.0 10 3.924935 20 5.586031 30 0.0 10 4.790343 20 4.497358 30 0.0 10 5.082487 20 2.956736 30 0.0 10 4.760026 20 1.338897 30 0.0 10 3.822960 20 0.236480 30 0.0 10 2.530360 20 -0.146608 30 0.0 10 1.640148 20 0.062857 30 0.0 10 0.992470 20 0.592024 30 0.0 10 0.992470 20 -2.257772 30 0.0 10 0.000282 20 -2.257772 30 0.0 0 LWPOLYLINE 5 14a 100 AcDbEntity 8 p_ 62 7 100 AcDbPolyline 90 9 70 0 10 0.898763 20 2.879548 30 0.0 10 1.356272 20 1.209385 30 0.0 10 2.464214 20 0.669183 30 0.0 10 3.596962 20 1.228661 30 0.0 10 4.068251 20 2.962239 30 0.0 10 3.607986 20 4.637933 30 0.0 10 2.508312 20 5.194645 30 0.0 10 1.386589 20 4.602091 30 0.0 10 0.898763 20 2.879548 30 0.0 0 LWPOLYLINE 5 14b 100 AcDbEntity 8 q_ 62 7 100 AcDbPolyline 90 14 70 0 10 4.079275 20 -2.257776 30 0.0 10 4.079275 20 0.608557 30 0.0 10 3.431597 20 0.068356 30 0.0 10 2.546897 20 -0.146613 30 0.0 10 0.752691 20 0.685717 30 0.0 10 0.000282 20 2.967737 30 0.0 10 0.306207 20 4.549734 30 0.0 10 1.193663 20 5.610833 30 0.0 10 2.469727 20 5.971880 30 0.0 10 4.178494 20 5.056859 30 0.0 10 4.178494 20 5.839574 30 0.0 10 5.071463 20 5.839574 30 0.0 10 5.071463 20 -2.257776 30 0.0 10 4.079275 20 -2.257776 30 0.0 0 LWPOLYLINE 5 14c 100 AcDbEntity 8 q_ 62 7 100 AcDbPolyline 90 9 70 0 10 1.020031 20 2.929158 30 0.0 10 1.494076 20 1.234187 30 0.0 10 2.629579 20 0.669178 30 0.0 10 3.720985 20 1.206614 30 0.0 10 4.178494 20 2.840963 30 0.0 10 3.696181 20 4.599349 30 0.0 10 2.563433 20 5.189137 30 0.0 10 1.469271 20 4.640694 30 0.0 10 1.020031 20 2.929158 30 0.0 0 LWPOLYLINE 5 14d 100 AcDbEntity 8 r_ 62 7 100 AcDbPolyline 90 14 70 0 10 1.693333 20 0.000284 30 0.0 10 1.693333 20 5.854193 30 0.0 10 2.586302 20 5.854193 30 0.0 10 2.586302 20 4.966746 30 0.0 10 3.217444 20 5.788040 30 0.0 10 3.854097 20 5.986471 30 0.0 10 4.873845 20 5.666770 30 0.0 10 4.532092 20 4.746245 30 0.0 10 3.804488 20 4.961214 30 0.0 10 3.220200 20 4.765549 30 0.0 10 2.850885 20 4.222582 30 0.0 10 2.685521 20 3.065048 30 0.0 10 2.685521 20 0.000284 30 0.0 10 1.693333 20 0.000284 30 0.0 0 LWPOLYLINE 5 14e 100 AcDbEntity 8 s_ 62 7 100 AcDbPolyline 90 34 70 0 10 0.000282 20 1.879940 30 0.0 10 0.981445 20 2.034259 30 0.0 10 1.441710 20 1.130273 30 0.0 10 2.497287 20 0.816075 30 0.0 10 3.511523 20 1.094431 30 0.0 10 3.842253 20 1.747634 30 0.0 10 3.550109 20 2.276801 30 0.0 10 2.535872 20 2.613040 30 0.0 10 1.022787 20 3.089855 30 0.0 10 0.383377 20 3.646566 30 0.0 10 0.165647 20 4.432047 30 0.0 10 0.344792 20 5.156907 30 0.0 10 0.832617 20 5.710881 30 0.0 10 1.463759 20 6.000272 30 0.0 10 2.320899 20 6.118777 30 0.0 10 3.530816 20 5.920346 30 0.0 10 4.299761 20 5.382910 30 0.0 10 4.641515 20 4.476159 30 0.0 10 3.671376 20 4.343853 30 0.0 10 3.288281 20 5.049408 30 0.0 10 2.392557 20 5.302985 30 0.0 10 1.416906 20 5.076982 30 0.0 10 1.124761 20 4.547815 30 0.0 10 1.246029 20 4.200540 30 0.0 10 1.626367 20 3.935957 30 0.0 10 2.502800 20 3.682409 30 0.0 10 3.971788 20 3.222132 30 0.0 10 4.624978 20 2.701235 30 0.0 10 4.862001 20 1.852367 30 0.0 10 4.572613 20 0.918042 30 0.0 10 3.737522 20 0.240060 30 0.0 10 2.502800 20 0.000284 30 0.0 10 0.763715 20 0.474332 30 0.0 10 0.000282 20 1.879940 30 0.0 0 LWPOLYLINE 5 14f 100 AcDbEntity 8 t_ 62 7 100 AcDbPolyline 90 21 70 0 10 4.123090 20 0.964896 30 0.0 10 4.266406 20 0.088483 30 0.0 10 3.516753 20 0.000288 30 0.0 10 2.678906 20 0.171146 30 0.0 10 2.259983 20 0.620387 30 0.0 10 2.138715 20 1.791722 30 0.0 10 2.138715 20 5.159649 30 0.0 10 1.411111 20 5.159649 30 0.0 10 1.411111 20 5.931358 30 0.0 10 2.138715 20 5.931358 30 0.0 10 2.138715 20 7.381049 30 0.0 10 3.125391 20 7.976368 30 0.0 10 3.125391 20 5.931358 30 0.0 10 4.123090 20 5.931358 30 0.0 10 4.123090 20 5.159649 30 0.0 10 3.125391 20 5.159649 30 0.0 10 3.125391 20 1.736604 30 0.0 10 3.177756 20 1.190899 30 0.0 10 3.348633 20 0.997972 30 0.0 10 3.687630 20 0.926316 30 0.0 10 4.123090 20 0.964896 30 0.0 0 LWPOLYLINE 5 150 100 AcDbEntity 8 u_ 62 7 100 AcDbPolyline 90 21 70 0 10 3.858789 20 0.132566 30 0.0 10 3.858789 20 0.992469 30 0.0 10 3.104444 20 0.282228 30 0.0 10 2.001194 20 0.000288 30 0.0 10 1.033811 20 0.198719 30 0.0 10 0.366840 20 0.697575 30 0.0 10 0.060916 20 1.433441 30 0.0 10 0.000282 20 2.359469 30 0.0 10 0.000282 20 5.986476 30 0.0 10 0.992470 20 5.986476 30 0.0 10 0.992470 20 2.739820 30 0.0 10 1.053103 20 1.692521 30 0.0 10 1.449978 20 1.077898 30 0.0 10 2.199631 20 0.854660 30 0.0 10 3.037478 20 1.083429 30 0.0 10 3.591450 20 1.706294 30 0.0 10 3.754058 20 2.850056 30 0.0 10 3.754058 20 5.986476 30 0.0 10 4.746246 20 5.986476 30 0.0 10 4.746246 20 0.132566 30 0.0 10 3.858789 20 0.132566 30 0.0 0 LWPOLYLINE 5 151 100 AcDbEntity 8 v_ 62 7 100 AcDbPolyline 90 10 70 0 10 2.227192 20 0.000288 30 0.0 10 0.000282 20 5.854198 30 0.0 10 1.047591 20 5.854198 30 0.0 10 2.304362 20 2.348490 30 0.0 10 2.679188 20 1.168886 30 0.0 10 3.048503 20 2.282337 30 0.0 10 4.349371 20 5.854198 30 0.0 10 5.369119 20 5.854198 30 0.0 10 3.153234 20 0.000288 30 0.0 10 2.227192 20 0.000288 30 0.0 0 LWPOLYLINE 5 152 100 AcDbEntity 8 w_ 62 7 100 AcDbPolyline 90 19 70 0 10 1.190788 20 0.000288 30 0.0 10 0.000282 20 5.854198 30 0.0 10 0.681618 20 5.854198 30 0.0 10 1.300681 20 2.475264 30 0.0 10 1.531456 20 1.218472 30 0.0 10 1.732926 20 2.425650 30 0.0 10 2.351989 20 5.854198 30 0.0 10 3.029662 20 5.854198 30 0.0 10 3.612094 20 2.458726 30 0.0 10 3.806238 20 1.339743 30 0.0 10 4.029687 20 2.469733 30 0.0 10 4.696370 20 5.854198 30 0.0 10 5.337412 20 5.854198 30 0.0 10 4.121264 20 0.000288 30 0.0 10 3.436266 20 0.000288 30 0.0 10 2.817202 20 3.506025 30 0.0 10 2.667016 20 4.503737 30 0.0 10 1.879450 20 0.000288 30 0.0 10 1.190788 20 0.000288 30 0.0 0 LWPOLYLINE 5 153 100 AcDbEntity 8 x_ 62 7 100 AcDbPolyline 90 16 70 0 10 0.000282 20 0.000288 30 0.0 10 2.138997 20 3.042983 30 0.0 10 0.160135 20 5.854198 30 0.0 10 1.400369 20 5.854198 30 0.0 10 2.298850 20 4.481667 30 0.0 10 2.706749 20 3.825726 30 0.0 10 3.153234 20 4.470632 30 0.0 10 4.139909 20 5.854198 30 0.0 10 5.325022 20 5.854198 30 0.0 10 3.302062 20 3.098101 30 0.0 10 5.479362 20 0.000288 30 0.0 10 4.261176 20 0.000288 30 0.0 10 3.059527 20 1.819295 30 0.0 10 2.739822 20 2.309882 30 0.0 10 1.201932 20 0.000288 30 0.0 10 0.000282 20 0.000288 30 0.0 0 LWPOLYLINE 5 154 100 AcDbEntity 8 y_ 62 7 100 AcDbPolyline 90 19 70 0 10 0.518425 20 -2.136501 30 0.0 10 0.408182 20 -1.204970 30 0.0 10 0.975933 20 -1.293164 30 0.0 10 1.505100 20 -1.182900 30 0.0 10 1.830317 20 -0.874234 30 0.0 10 2.133485 20 -0.135602 30 0.0 10 2.221680 20 0.106940 30 0.0 10 0.000282 20 5.971857 30 0.0 10 1.069640 20 5.971857 30 0.0 10 2.287826 20 2.581888 30 0.0 10 2.712261 20 1.225895 30 0.0 10 3.120161 20 2.559846 30 0.0 10 4.371419 20 5.971857 30 0.0 10 5.363607 20 5.971857 30 0.0 10 3.136697 20 0.018746 30 0.0 10 2.579970 20 -1.309702 30 0.0 10 1.973633 20 -2.029030 30 0.0 10 1.157834 20 -2.257772 30 0.0 10 0.518425 20 -2.136501 30 0.0 0 LWPOLYLINE 5 155 100 AcDbEntity 8 z_ 62 7 100 AcDbPolyline 90 14 70 0 10 0.000282 20 0.000288 30 0.0 10 0.000282 20 0.805073 30 0.0 10 3.726497 20 5.082518 30 0.0 10 2.607531 20 5.049442 30 0.0 10 0.220768 20 5.049442 30 0.0 10 0.220768 20 5.854198 30 0.0 10 5.005317 20 5.854198 30 0.0 10 5.005317 20 5.198257 30 0.0 10 1.835829 20 1.483084 30 0.0 10 1.223980 20 0.805073 30 0.0 10 2.475239 20 0.854688 30 0.0 10 5.181706 20 0.854688 30 0.0 10 5.181706 20 0.000288 30 0.0 10 0.000282 20 0.000288 30 0.0 0 LWPOLYLINE 5 156 100 AcDbEntity 8 ~ 62 7 100 AcDbPolyline 90 17 70 0 10 0.056224 20 3.176129 30 0.0 10 0.056224 20 4.306122 30 0.0 10 1.360019 20 4.967578 30 0.0 10 1.950948 20 4.871117 30 0.0 10 2.832651 20 4.488021 30 0.0 10 3.318056 20 4.278561 30 0.0 10 3.644005 20 4.228952 30 0.0 10 4.274798 20 4.443925 30 0.0 10 4.854002 20 4.984116 30 0.0 10 4.854002 20 3.815540 30 0.0 10 4.246659 20 3.335982 30 0.0 10 3.554897 20 3.187153 30 0.0 10 3.017902 20 3.264323 30 0.0 10 2.206548 20 3.633639 30 0.0 10 1.280290 20 3.925782 30 0.0 10 0.715156 20 3.774199 30 0.0 10 0.056224 20 3.176129 30 0.0 0 LWPOLYLINE 5 157 100 AcDbEntity 8 ! 62 7 100 AcDbPolyline 90 7 70 0 10 2.278724 20 1.752150 30 0.0 10 1.975556 20 5.491707 30 0.0 10 1.975556 20 7.055839 30 0.0 10 3.204766 20 7.055839 30 0.0 10 3.204766 20 5.491707 30 0.0 10 2.918134 20 1.752150 30 0.0 10 2.278724 20 1.752150 30 0.0 0 LWPOLYLINE 5 158 100 AcDbEntity 8 ! 62 7 100 AcDbPolyline 90 5 70 0 10 2.019653 20 0.000284 30 0.0 10 2.019653 20 0.986904 30 0.0 10 3.160668 20 0.986904 30 0.0 10 3.160668 20 0.000284 30 0.0 10 2.019653 20 0.000284 30 0.0 0 LWPOLYLINE 5 159 100 AcDbEntity 8 @ 62 7 100 AcDbPolyline 90 50 70 0 10 2.660085 20 2.178562 30 0.0 10 2.291512 20 1.736674 30 0.0 10 1.882409 20 1.569818 30 0.0 10 1.444175 20 1.760511 30 0.0 10 1.098401 20 2.347251 30 0.0 10 0.965411 20 3.216361 30 0.0 10 1.171862 20 4.384342 30 0.0 10 1.684824 20 5.262618 30 0.0 10 2.280113 20 5.555987 30 0.0 10 2.700615 20 5.389133 30 0.0 10 3.045123 20 4.881238 30 0.0 10 3.131250 20 5.449641 30 0.0 10 3.584683 20 5.449641 30 0.0 10 3.219910 20 2.988996 30 0.0 10 3.143916 20 2.420593 30 0.0 10 3.195845 20 2.250072 30 0.0 10 3.321236 20 2.178562 30 0.0 10 3.673343 20 2.402256 30 0.0 10 4.130576 20 3.188857 30 0.0 10 4.299030 20 4.206486 30 0.0 10 4.082446 20 5.350630 30 0.0 10 3.436494 20 6.201403 30 0.0 10 2.487831 20 6.520443 30 0.0 10 1.404911 20 6.118894 30 0.0 10 0.644968 20 4.967415 30 0.0 10 0.375188 20 3.359378 30 0.0 10 0.644968 20 1.811849 30 0.0 10 1.425177 20 0.852895 30 0.0 10 2.556226 20 0.543021 30 0.0 10 3.668277 20 0.865729 30 0.0 10 4.339560 20 1.650495 30 0.0 10 4.798060 20 1.650495 30 0.0 10 4.354759 20 0.865729 30 0.0 10 3.607481 20 0.233151 30 0.0 10 2.563825 20 0.000287 30 0.0 10 1.526502 20 0.209314 30 0.0 10 0.717162 20 0.838225 30 0.0 10 0.213066 20 1.804514 30 0.0 10 0.000282 20 3.300705 30 0.0 10 0.253597 20 5.005918 30 0.0 10 1.131332 20 6.527778 30 0.0 10 2.510629 20 7.055843 30 0.0 10 3.639146 20 6.683629 30 0.0 10 4.428220 20 5.574324 30 0.0 10 4.673936 20 4.195484 30 0.0 10 4.157174 20 2.306913 30 0.0 10 3.148982 20 1.566153 30 0.0 10 2.866536 20 1.643163 30 0.0 10 2.708215 20 1.863189 30 0.0 10 2.660085 20 2.178562 30 0.0 0 LWPOLYLINE 5 15a 100 AcDbEntity 8 @ 62 7 100 AcDbPolyline 90 13 70 0 10 1.434043 20 3.172355 30 0.0 10 1.598697 20 2.391257 30 0.0 10 1.976136 20 2.112555 30 0.0 10 2.275047 20 2.235403 30 0.0 10 2.575224 20 2.600281 30 0.0 10 2.809540 20 3.214525 30 0.0 10 2.900734 20 3.960788 30 0.0 10 2.729746 20 4.734551 30 0.0 10 2.313044 20 5.009585 30 0.0 10 2.007800 20 4.890405 30 0.0 10 1.730421 20 4.507189 30 0.0 10 1.515103 20 3.865441 30 0.0 10 1.434043 20 3.172355 30 0.0 0 LWPOLYLINE 5 15b 100 AcDbEntity 8 # 62 7 100 AcDbPolyline 90 29 70 0 10 0.360555 20 0.000312 30 0.0 10 0.742795 20 1.982931 30 0.0 10 0.000282 20 1.982931 30 0.0 10 0.000282 20 2.676394 30 0.0 10 0.874603 20 2.676394 30 0.0 10 1.199727 20 4.365815 30 0.0 10 0.000282 20 4.365815 30 0.0 10 0.000282 20 5.059249 30 0.0 10 1.331534 20 5.059249 30 0.0 10 1.713774 20 7.055854 30 0.0 10 2.372810 20 7.055854 30 0.0 10 1.990569 20 5.059249 30 0.0 10 3.374544 20 5.059249 30 0.0 10 3.756784 20 7.055854 30 0.0 10 4.420213 20 7.055854 30 0.0 10 4.037973 20 5.059249 30 0.0 10 4.798060 20 5.059249 30 0.0 10 4.798060 20 4.365815 30 0.0 10 3.906166 20 4.365815 30 0.0 10 3.576648 20 2.676394 30 0.0 10 4.798060 20 2.676394 30 0.0 10 4.798060 20 1.982931 30 0.0 10 3.444841 20 1.982931 30 0.0 10 3.062600 20 0.000312 30 0.0 10 2.403565 20 0.000312 30 0.0 10 2.781412 20 1.982931 30 0.0 10 1.401831 20 1.982931 30 0.0 10 1.019590 20 0.000312 30 0.0 10 0.360555 20 0.000312 30 0.0 0 LWPOLYLINE 5 15c 100 AcDbEntity 8 # 62 7 100 AcDbPolyline 90 5 70 0 10 1.533638 20 2.676394 30 0.0 10 2.913219 20 2.676394 30 0.0 10 3.242737 20 4.365815 30 0.0 10 1.858762 20 4.365815 30 0.0 10 1.533638 20 2.676394 30 0.0 0 LWPOLYLINE 5 15d 100 AcDbEntity 8 $ 62 7 100 AcDbPolyline 90 31 70 0 10 2.161755 20 0.000281 30 0.0 10 2.161755 20 0.701166 30 0.0 10 1.076073 20 0.936747 30 0.0 10 0.353933 20 1.483833 30 0.0 10 0.000282 20 2.406651 30 0.0 10 0.895538 20 2.539041 30 0.0 10 1.261554 20 1.709673 30 0.0 10 2.161755 20 1.293024 30 0.0 10 2.161755 20 3.524185 30 0.0 10 1.038976 20 3.859052 30 0.0 10 0.383610 20 4.376915 30 0.0 10 0.153613 20 5.128407 30 0.0 10 0.826291 20 6.339392 30 0.0 10 2.161755 20 6.720984 30 0.0 10 2.161755 20 7.055851 30 0.0 10 2.686049 20 7.055851 30 0.0 10 2.686049 20 6.720984 30 0.0 10 3.917643 20 6.362755 30 0.0 10 4.619998 20 5.315309 30 0.0 10 3.700012 20 5.206283 30 0.0 10 3.371092 20 5.839032 30 0.0 10 2.686049 20 6.129126 30 0.0 10 2.686049 20 4.108255 30 0.0 10 3.576358 20 3.901871 30 0.0 10 4.253982 20 3.551429 30 0.0 10 4.657094 20 3.060810 30 0.0 10 4.798060 20 2.445589 30 0.0 10 4.209467 20 1.230723 30 0.0 10 2.686049 20 0.708953 30 0.0 10 2.686049 20 0.000281 30 0.0 10 2.161755 20 0.000281 30 0.0 0 LWPOLYLINE 5 15e 100 AcDbEntity 8 $ 62 7 100 AcDbPolyline 90 6 70 0 10 2.161755 20 6.136914 30 0.0 10 1.343165 20 5.809835 30 0.0 10 1.043923 20 5.182920 30 0.0 10 1.298650 20 4.583274 30 0.0 10 2.161755 20 4.197800 30 0.0 10 2.161755 20 6.136914 30 0.0 0 LWPOLYLINE 5 15f 100 AcDbEntity 8 $ 62 7 100 AcDbPolyline 90 6 70 0 10 2.686049 20 1.293024 30 0.0 10 3.544208 20 1.647372 30 0.0 10 3.883020 20 2.398864 30 0.0 10 3.643131 20 3.012131 30 0.0 10 2.686049 20 3.426828 30 0.0 10 2.686049 20 1.293024 30 0.0 0 LWPOLYLINE 5 160 100 AcDbEntity 8 % 62 7 100 AcDbPolyline 90 9 70 0 10 0.000282 20 5.334189 30 0.0 10 0.240780 20 6.553498 30 0.0 10 0.937919 20 7.055837 30 0.0 10 1.633536 20 6.606018 30 0.0 10 1.909043 20 5.283957 30 0.0 10 1.630492 20 3.975595 30 0.0 10 0.944008 20 3.516643 30 0.0 10 0.269701 20 3.968747 30 0.0 10 0.000282 20 5.334189 30 0.0 0 LWPOLYLINE 5 161 100 AcDbEntity 8 % 62 7 100 AcDbPolyline 90 9 70 0 10 0.953140 20 6.489565 30 0.0 10 0.613704 20 6.224698 30 0.0 10 0.478233 20 5.251990 30 0.0 10 0.615226 20 4.345497 30 0.0 10 0.953140 20 4.082912 30 0.0 10 1.295621 20 4.347782 30 0.0 10 1.431092 20 5.315924 30 0.0 10 1.294099 20 6.226980 30 0.0 10 0.953140 20 6.489565 30 0.0 0 LWPOLYLINE 5 162 100 AcDbEntity 8 % 62 7 100 AcDbPolyline 90 5 70 0 10 0.956185 20 0.000281 30 0.0 10 3.397693 20 7.055837 30 0.0 10 3.842158 20 7.055837 30 0.0 10 1.409782 20 0.000281 30 0.0 10 0.956185 20 0.000281 30 0.0 0 LWPOLYLINE 5 163 100 AcDbEntity 8 % 62 7 100 AcDbPolyline 90 9 70 0 10 2.886255 20 1.817829 30 0.0 10 3.126753 20 3.039424 30 0.0 10 3.826936 20 3.539474 30 0.0 10 4.522553 20 3.089655 30 0.0 10 4.798060 20 1.767594 30 0.0 10 4.519509 20 0.459236 30 0.0 10 3.829980 20 0.000281 30 0.0 10 3.155673 20 0.454669 30 0.0 10 2.886255 20 1.817829 30 0.0 0 LWPOLYLINE 5 164 100 AcDbEntity 8 % 62 7 100 AcDbPolyline 90 9 70 0 10 3.842158 20 2.973205 30 0.0 10 3.499677 20 2.708335 30 0.0 10 3.364206 20 1.735628 30 0.0 10 3.501199 20 0.831419 30 0.0 10 3.839113 20 0.566553 30 0.0 10 4.184638 20 0.831419 30 0.0 10 4.320109 20 1.799561 30 0.0 10 4.183116 20 2.710620 30 0.0 10 3.842158 20 2.973205 30 0.0 0 LWPOLYLINE 5 165 100 AcDbEntity 8 ^ 62 7 100 AcDbPolyline 90 8 70 0 10 1.299766 20 3.009647 30 0.0 10 0.280017 20 3.009647 30 0.0 10 2.225807 20 7.424873 30 0.0 10 3.025069 20 7.424873 30 0.0 10 4.981884 20 3.009647 30 0.0 10 3.984184 20 3.009647 30 0.0 10 2.622682 20 6.300387 30 0.0 10 1.299766 20 3.009647 30 0.0 0 LWPOLYLINE 5 166 100 AcDbEntity 8 & 62 7 100 AcDbPolyline 90 21 70 0 10 3.449538 20 0.958006 30 0.0 10 2.693430 20 0.270957 30 0.0 10 1.808705 20 0.041942 30 0.0 10 0.417311 20 0.745183 30 0.0 10 0.000282 20 2.026749 30 0.0 10 0.341310 20 3.162580 30 0.0 10 1.360497 20 4.053197 30 0.0 10 0.846032 20 4.909116 30 0.0 10 0.717416 20 5.542960 30 0.0 10 1.120803 20 6.604763 30 0.0 10 2.136092 20 7.055857 30 0.0 10 3.092920 20 6.630211 30 0.0 10 3.465128 20 5.607733 30 0.0 10 2.385530 20 3.956039 30 0.0 10 3.410563 20 2.406130 30 0.0 10 3.683385 20 3.349955 30 0.0 10 4.412211 20 3.164892 30 0.0 10 3.905541 20 1.702888 30 0.0 10 4.798060 20 0.661906 30 0.0 10 4.326467 20 0.000302 30 0.0 10 3.449538 20 0.958006 30 0.0 0 LWPOLYLINE 5 167 100 AcDbEntity 8 & 62 7 100 AcDbPolyline 90 10 70 0 10 2.023066 20 4.492723 30 0.0 10 2.613532 20 5.052542 30 0.0 10 2.747994 20 5.584601 30 0.0 10 2.562865 20 6.151357 30 0.0 10 2.101015 20 6.371120 30 0.0 10 1.627473 20 6.153672 30 0.0 10 1.438446 20 5.621613 30 0.0 10 1.506652 20 5.290813 30 0.0 10 1.711269 20 4.922996 30 0.0 10 2.023066 20 4.492723 30 0.0 0 LWPOLYLINE 5 168 100 AcDbEntity 8 & 62 7 100 AcDbPolyline 90 8 70 0 10 3.009124 20 1.614983 30 0.0 10 1.722961 20 3.507261 30 0.0 10 0.955161 20 2.760066 30 0.0 10 0.756390 20 2.077642 30 0.0 10 1.033110 20 1.221722 30 0.0 10 1.816500 20 0.777568 30 0.0 10 2.469325 20 1.011211 30 0.0 10 3.009124 20 1.614983 30 0.0 0 LWPOLYLINE 5 169 100 AcDbEntity 8 * 62 7 100 AcDbPolyline 90 16 70 0 10 0.723194 20 5.292769 30 0.0 10 0.976753 20 6.075512 30 0.0 10 2.250061 20 5.540814 30 0.0 10 2.139818 20 6.913345 30 0.0 10 2.939080 20 6.913345 30 0.0 10 2.812300 20 5.546345 30 0.0 10 4.113168 20 6.075512 30 0.0 10 4.366727 20 5.292769 30 0.0 10 2.994201 20 4.984102 30 0.0 10 3.942292 20 3.942307 30 0.0 10 3.280833 20 3.473762 30 0.0 10 2.525668 20 4.658869 30 0.0 10 1.809089 20 3.473762 30 0.0 10 1.158654 20 3.942307 30 0.0 10 2.073672 20 4.984102 30 0.0 10 0.723194 20 5.292769 30 0.0 0 LWPOLYLINE 5 16a 100 AcDbEntity 8 ( 62 7 100 AcDbPolyline 90 11 70 0 10 3.067408 20 0.000298 30 0.0 10 1.891871 20 1.854548 30 0.0 10 1.411393 20 4.054406 30 0.0 10 1.770585 20 5.976093 30 0.0 10 3.067408 20 8.100065 30 0.0 10 3.669171 20 8.100065 30 0.0 10 2.922798 20 6.848429 30 0.0 10 2.474975 20 5.634723 30 0.0 10 2.274387 20 4.050168 30 0.0 10 3.669171 20 0.000298 30 0.0 10 3.067408 20 0.000298 30 0.0 0 LWPOLYLINE 5 16b 100 AcDbEntity 8 ) 62 7 100 AcDbPolyline 90 11 70 0 10 2.013156 20 0.000295 30 0.0 10 1.411393 20 0.000295 30 0.0 10 2.806178 20 4.050165 30 0.0 10 2.605590 20 5.622086 30 0.0 10 2.162431 20 6.835792 30 0.0 10 1.411393 20 8.100062 30 0.0 10 2.013156 20 8.100062 30 0.0 10 3.309979 20 5.976090 30 0.0 10 3.669171 20 4.054403 30 0.0 10 3.186361 20 1.854545 30 0.0 10 2.013156 20 0.000295 30 0.0 0 LWPOLYLINE 5 16c 100 AcDbEntity 8 _ 62 7 100 AcDbPolyline 90 5 70 0 10 0.000282 20 -0.722902 30 0.0 10 0.000282 20 -0.006323 30 0.0 10 5.080282 20 -0.006323 30 0.0 10 5.080282 20 -0.722902 30 0.0 10 0.000282 20 -0.722902 30 0.0 0 LWPOLYLINE 5 16d 100 AcDbEntity 8 + 62 7 100 AcDbPolyline 90 13 70 0 10 1.988621 20 1.623870 30 0.0 10 1.988621 20 3.614287 30 0.0 10 0.011024 20 3.614287 30 0.0 10 0.011024 20 4.446102 30 0.0 10 1.988621 20 4.446102 30 0.0 10 1.988621 20 6.421654 30 0.0 10 2.831206 20 6.421654 30 0.0 10 2.831206 20 4.446102 30 0.0 10 4.808802 20 4.446102 30 0.0 10 4.808802 20 3.614287 30 0.0 10 2.831206 20 3.614287 30 0.0 10 2.831206 20 1.623870 30 0.0 10 1.988621 20 1.623870 30 0.0 0 LWPOLYLINE 5 16e 100 AcDbEntity 8 - 62 7 100 AcDbPolyline 90 5 70 0 10 0.799262 20 3.607155 30 0.0 10 0.799262 20 4.453821 30 0.0 10 3.847483 20 4.453821 30 0.0 10 3.847483 20 3.607155 30 0.0 10 0.799262 20 3.607155 30 0.0 0 LWPOLYLINE 5 16f 100 AcDbEntity 8 = 62 7 100 AcDbPolyline 90 5 70 0 10 4.826441 20 4.626115 30 0.0 10 0.028663 20 4.626115 30 0.0 10 0.028663 20 5.438278 30 0.0 10 4.826441 20 5.438278 30 0.0 10 4.826441 20 4.626115 30 0.0 0 LWPOLYLINE 5 170 100 AcDbEntity 8 = 62 7 100 AcDbPolyline 90 5 70 0 10 4.826441 20 2.474923 30 0.0 10 0.028663 20 2.474923 30 0.0 10 0.028663 20 3.287058 30 0.0 10 4.826441 20 3.287058 30 0.0 10 4.826441 20 2.474923 30 0.0 0 LWPOLYLINE 5 171 100 AcDbEntity 8 , 62 7 100 AcDbPolyline 90 10 70 0 10 2.026267 20 0.017640 30 0.0 10 2.026267 20 1.147630 30 0.0 10 3.156259 20 1.147630 30 0.0 10 3.156259 20 0.017640 30 0.0 10 2.935773 20 -0.988313 30 0.0 10 2.235729 20 -1.580866 30 0.0 10 1.960122 20 -1.156432 30 0.0 10 2.423142 20 -0.751302 30 0.0 10 2.588507 20 0.017640 30 0.0 10 2.026267 20 0.017640 30 0.0 0 LWPOLYLINE 5 172 100 AcDbEntity 8 . 62 7 100 AcDbPolyline 90 5 70 0 10 2.030677 20 0.000001 30 0.0 10 2.030677 20 1.129991 30 0.0 10 3.160668 20 1.129991 30 0.0 10 3.160668 20 0.000001 30 0.0 10 2.030677 20 0.000001 30 0.0 0 LWPOLYLINE 5 173 100 AcDbEntity 8 < 62 7 100 AcDbPolyline 90 8 70 0 10 0.458611 20 2.922511 30 0.0 10 0.458611 20 3.848554 30 0.0 10 4.691944 20 6.108536 30 0.0 10 4.691944 20 5.121861 30 0.0 10 1.334924 20 3.380019 30 0.0 10 4.691944 20 1.621644 30 0.0 10 4.691944 20 0.634968 30 0.0 10 0.458611 20 2.922511 30 0.0 0 LWPOLYLINE 5 174 100 AcDbEntity 8 > 62 7 100 AcDbPolyline 90 8 70 0 10 4.550834 20 2.922557 30 0.0 10 0.317500 20 0.635013 30 0.0 10 0.317500 20 1.621689 30 0.0 10 3.670161 20 3.380064 30 0.0 10 0.317500 20 5.121906 30 0.0 10 0.317500 20 6.108581 30 0.0 10 4.550834 20 3.848599 30 0.0 10 4.550834 20 2.922557 30 0.0 0 LWPOLYLINE 5 175 100 AcDbEntity 8 ? 62 7 100 AcDbPolyline 90 22 70 0 10 1.937651 20 1.708584 30 0.0 10 1.932580 20 1.964103 30 0.0 10 2.084729 20 2.830079 30 0.0 10 2.444816 20 3.383725 30 0.0 10 3.101594 20 3.977608 30 0.0 10 3.717799 20 4.599870 30 0.0 10 3.859805 20 5.106218 30 0.0 10 3.443930 20 5.979282 30 0.0 10 2.424529 20 6.355485 30 0.0 10 1.450773 20 6.014776 30 0.0 10 0.938537 20 4.950066 30 0.0 10 0.000282 20 5.054177 30 0.0 10 0.753422 20 6.540043 30 0.0 10 2.409314 20 7.055851 30 0.0 10 4.148889 20 6.502177 30 0.0 10 4.798060 20 5.163003 30 0.0 10 4.569836 20 4.325433 30 0.0 10 3.677226 20 3.393185 30 0.0 10 3.093987 20 2.848998 30 0.0 10 2.891121 20 2.446788 30 0.0 10 2.815046 20 1.708584 30 0.0 10 1.937651 20 1.708584 30 0.0 0 LWPOLYLINE 5 176 100 AcDbEntity 8 ? 62 7 100 AcDbPolyline 90 5 70 0 10 1.881863 20 0.000294 30 0.0 10 1.881863 20 0.970354 30 0.0 10 2.921551 20 0.970354 30 0.0 10 2.921551 20 0.000294 30 0.0 10 1.881863 20 0.000294 30 0.0 0 LWPOLYLINE 5 177 100 AcDbEntity 8 / 62 7 100 AcDbPolyline 90 5 70 0 10 1.093611 20 0.003312 30 0.0 10 3.436276 20 7.058881 30 0.0 10 4.230026 20 7.058881 30 0.0 10 1.892873 20 0.003312 30 0.0 10 1.093611 20 0.003312 30 0.0 0 LWPOLYLINE 5 178 100 AcDbEntity 8 ; 62 7 100 AcDbPolyline 90 5 70 0 10 2.026267 20 4.761457 30 0.0 10 2.026267 20 5.677466 30 0.0 10 3.156259 20 5.677466 30 0.0 10 3.156259 20 4.761457 30 0.0 10 2.026267 20 4.761457 30 0.0 0 LWPOLYLINE 5 179 100 AcDbEntity 8 ; 62 7 100 AcDbPolyline 90 10 70 0 10 2.026267 20 0.932040 30 0.0 10 2.026267 20 1.848049 30 0.0 10 3.156259 20 1.848049 30 0.0 10 3.156259 20 0.932040 30 0.0 10 2.935773 20 0.116559 30 0.0 10 2.235729 20 -0.363783 30 0.0 10 1.960122 20 -0.019726 30 0.0 10 2.423142 20 0.308696 30 0.0 10 2.588507 20 0.932040 30 0.0 10 2.026267 20 0.932040 30 0.0 0 LWPOLYLINE 5 17a 100 AcDbEntity 8 : 62 7 100 AcDbPolyline 90 5 70 0 10 2.025165 20 4.572948 30 0.0 10 2.025165 20 5.430519 30 0.0 10 3.155156 20 5.430519 30 0.0 10 3.155156 20 4.572948 30 0.0 10 2.025165 20 4.572948 30 0.0 0 LWPOLYLINE 5 17b 100 AcDbEntity 8 : 62 7 100 AcDbPolyline 90 5 70 0 10 2.025165 20 0.987792 30 0.0 10 2.025165 20 1.845388 30 0.0 10 3.155156 20 1.845388 30 0.0 10 3.155156 20 0.987792 30 0.0 10 2.025165 20 0.987792 30 0.0 0 LWPOLYLINE 5 17c 100 AcDbEntity 8 ' 62 7 100 AcDbPolyline 90 7 70 0 10 1.582933 20 5.625122 30 0.0 10 1.359888 20 6.404476 30 0.0 10 1.359888 20 7.074890 30 0.0 10 2.274372 20 7.074890 30 0.0 10 2.274372 20 6.404476 30 0.0 10 2.073632 20 5.625122 30 0.0 10 1.582933 20 5.625122 30 0.0 0 LWPOLYLINE 5 17d 100 AcDbEntity 8 ' 62 7 100 AcDbPolyline 90 7 70 0 10 3.059490 20 5.625122 30 0.0 10 2.840906 20 6.404476 30 0.0 10 2.840906 20 7.074890 30 0.0 10 3.755390 20 7.074890 30 0.0 10 3.755390 20 6.404476 30 0.0 10 3.541267 20 5.625122 30 0.0 10 3.059490 20 5.625122 30 0.0 0 LWPOLYLINE 5 17e 100 AcDbEntity 8 ` 62 7 100 AcDbPolyline 90 7 70 0 10 1.600572 20 5.625122 30 0.0 10 1.377527 20 6.404476 30 0.0 10 1.377527 20 7.074890 30 0.0 10 2.292011 20 7.074890 30 0.0 10 2.292011 20 6.404476 30 0.0 10 2.091270 20 5.625122 30 0.0 10 1.600572 20 5.625122 30 0.0 0 LWPOLYLINE 5 17f 100 AcDbEntity 8 " 62 7 100 AcDbPolyline 90 7 70 0 10 1.640770 20 5.608059 30 0.0 10 1.417725 20 6.387413 30 0.0 10 1.417725 20 7.057827 30 0.0 10 2.332210 20 7.057827 30 0.0 10 2.332210 20 6.387413 30 0.0 10 2.131469 20 5.608059 30 0.0 10 1.640770 20 5.608059 30 0.0 0 LWPOLYLINE 5 180 100 AcDbEntity 8 " 62 7 100 AcDbPolyline 90 7 70 0 10 3.117328 20 5.608059 30 0.0 10 2.898744 20 6.387413 30 0.0 10 2.898744 20 7.057827 30 0.0 10 3.813228 20 7.057827 30 0.0 10 3.813228 20 6.387413 30 0.0 10 3.599105 20 5.608059 30 0.0 10 3.117328 20 5.608059 30 0.0 0 LWPOLYLINE 5 181 100 AcDbEntity 8 [ 62 7 100 AcDbPolyline 90 9 70 0 10 1.260078 20 -0.020971 30 0.0 10 1.260078 20 8.078826 30 0.0 10 3.235634 20 8.078826 30 0.0 10 3.235634 20 7.434463 30 0.0 10 2.155796 20 7.434463 30 0.0 10 2.155796 20 0.623392 30 0.0 10 3.235634 20 0.623392 30 0.0 10 3.235634 20 -0.020971 30 0.0 10 1.260078 20 -0.020971 30 0.0 0 LWPOLYLINE 5 182 100 AcDbEntity 8 ] 62 7 100 AcDbPolyline 90 9 70 0 10 3.848585 20 0.000279 30 0.0 10 1.873030 20 0.000279 30 0.0 10 1.873030 20 0.644621 30 0.0 10 2.952867 20 0.644621 30 0.0 10 2.952867 20 7.455707 30 0.0 10 1.873030 20 7.455707 30 0.0 10 1.873030 20 8.100048 30 0.0 10 3.848585 20 8.100048 30 0.0 10 3.848585 20 0.000279 30 0.0 0 LWPOLYLINE 5 183 100 AcDbEntity 8 { 62 7 100 AcDbPolyline 90 33 70 0 10 0.719887 20 4.330412 30 0.0 10 1.331612 20 4.505288 30 0.0 10 1.646005 20 4.962526 30 0.0 10 1.728868 20 5.957093 30 0.0 10 1.758114 20 6.884244 30 0.0 10 1.921403 20 7.453168 30 0.0 10 2.216298 20 7.796622 30 0.0 10 2.664734 20 7.992570 30 0.0 10 3.269148 20 8.034714 30 0.0 10 3.542109 20 8.034714 30 0.0 10 3.542109 20 7.373078 30 0.0 10 3.391006 20 7.373078 30 0.0 10 2.718352 20 7.215049 30 0.0 10 2.552625 20 6.509169 30 0.0 10 2.499008 20 5.114257 30 0.0 10 2.199238 20 4.418900 30 0.0 10 1.533896 20 3.984833 30 0.0 10 2.311347 20 3.392738 30 0.0 10 2.552625 20 2.088412 30 0.0 10 2.572123 20 1.110719 30 0.0 10 2.769532 20 0.710373 30 0.0 10 3.391006 20 0.596588 30 0.0 10 3.542109 20 0.596588 30 0.0 10 3.542109 20 -0.065048 30 0.0 10 3.269148 20 -0.065048 30 0.0 10 2.576997 20 0.002367 30 0.0 10 2.060321 20 0.316325 30 0.0 10 1.794671 20 0.866302 30 0.0 10 1.728868 20 1.957780 30 0.0 10 1.646005 20 3.007140 30 0.0 10 1.331612 20 3.466477 30 0.0 10 0.719887 20 3.643479 30 0.0 10 0.719887 20 4.330412 30 0.0 0 LWPOLYLINE 5 184 100 AcDbEntity 8 } 62 7 100 AcDbPolyline 90 33 70 0 10 4.608689 20 4.395757 30 0.0 10 4.608689 20 3.708824 30 0.0 10 3.996964 20 3.531823 30 0.0 10 3.682571 20 3.074584 30 0.0 10 3.599708 20 2.082143 30 0.0 10 3.570464 20 1.154992 30 0.0 10 3.407174 20 0.583969 30 0.0 10 3.112279 20 0.242615 30 0.0 10 2.663843 20 0.046667 30 0.0 10 2.059429 20 0.000297 30 0.0 10 1.786468 20 0.000297 30 0.0 10 1.786468 20 0.661933 30 0.0 10 1.937572 20 0.661933 30 0.0 10 2.610226 20 0.819962 30 0.0 10 2.775952 20 1.530067 30 0.0 10 2.819821 20 2.865988 30 0.0 10 3.131776 20 3.614012 30 0.0 10 3.794682 20 4.050178 30 0.0 10 3.005044 20 4.663346 30 0.0 10 2.775952 20 5.950798 30 0.0 10 2.751580 20 6.932716 30 0.0 10 2.559045 20 7.326764 30 0.0 10 1.937572 20 7.438449 30 0.0 10 1.786468 20 7.438449 30 0.0 10 1.786468 20 8.100086 30 0.0 10 2.059429 20 8.100086 30 0.0 10 2.751580 20 8.032644 30 0.0 10 3.268257 20 7.720786 30 0.0 10 3.533906 20 7.168736 30 0.0 10 3.599709 20 6.077231 30 0.0 10 3.682573 20 5.029997 30 0.0 10 3.996965 20 4.572759 30 0.0 10 4.608689 20 4.395757 30 0.0 0 LWPOLYLINE 5 185 100 AcDbEntity 8 | 62 7 100 AcDbPolyline 90 5 70 0 10 3.224609 20 0.000275 30 0.0 10 0.881944 20 7.055818 30 0.0 10 1.681207 20 7.055818 30 0.0 10 4.018359 20 0.000275 30 0.0 10 3.224609 20 0.000275 30 0.0 0 ENDSEC 0 SECTION 2 OBJECTS 0 DICTIONARY 5 C 330 0 100 AcDbDictionary 3 ACAD_GROUP 350 D 3 ACAD_MLINESTYLE 350 17 0 DICTIONARY 5 D 330 C 100 AcDbDictionary 0 DICTIONARY 5 1A 330 C 100 AcDbDictionary 0 DICTIONARY 5 17 330 C 100 AcDbDictionary 3 STANDARD 350 18 0 DICTIONARY 5 19 330 C 100 AcDbDictionary 0 ENDSEC 0 EOF ================================================ FILE: brackets/Write.scad ================================================ /* Version 4 Added bold property bold=0 (not bold) bold=1(bolder by 1.1) bold=2(bolder by 1.2) Added support for font selection (default is Letters.dxf) Added WriteCube module Added Rotate for text (rotates on the plane of the text) Added writesphere Added space= (spacing between characters in char widths) def=1 Added writecylinder() By Harlan Martin harlan@sutlog.com January 2012 (The file TestWrite.scad gives More usage examples) (This module requires the file Letters.dxf to reside in the same folder) (The file Letters.dfx was created with inkscape..Each letter is in its own layer) (This module seperates each letter in the string and imports it from Letters.dfx) */ pi=3.1415926535897932384626433832795028841971693993751058209; pi2=pi*2; // These control the default values for write() writesphere() writecube() // if the parameters are not included in the call. Feel free to set your own // defaults. //default settings bold=0; center=false; h = 4; //mm letter height t = 1; //mm letter thickness space =1; //extra space between characters in (character widths) rotate=0; // text rotation (clockwise) font = "Letters.dxf"; //default for aditional fonts // write cube defaults face = "front"; // default face (top,bottom,left,right,back,front) up =0; //mm up from center on face of cube down=0; right =0; //mm left from center on face of cube left=0; // write sphere defaults rounded=false; //default for rounded letters on writesphere north=0; // intial text position (I suggest leave these 0 defaults) south=0; east=0; west=0; spin=0; // writecylinder defaults middle=0; //(mm toward middle of circle) ccw=false; //write on top or bottom in a ccw direction r1=0; //(not implimented yet) r2=0; //(not implimented yet) // Contact me if your interested in how to make your own font files // Its tedious and time consuming, but not very hard module writecylinder(text,where,radius,height){ wid=(.125* h *5.5 * space); widall=wid*(len(text)-1)/2; //angle that measures width of letters on sphere function NAngle(radius)=(wid/(pi2*radius))*360; //angle of half width of text function mmangle(radius)=(widall/(pi2*radius)*360); if ((face=="top")||(face=="bottom") ){ if (face=="top" ){ if (center==true){ writecircle(text,where+[0,0,height/2],radius-h,rotate=rotate,font=font,h=h,t=t, space=space,east=east,west=west,middle=middle,ccw=ccw,bold=bold); }else{ writecircle(text,where+[0,0,height],radius-h,rotate=rotate,font=font,h=h,t=t, space=space,east=east,west=west,middle=middle,ccw=ccw,bold=bold); } }else{ rotate(180,[1,0,0]) if (center==true){ writecircle(text,where+[0,0,height/2],radius-h,rotate=rotate,font=font,h=h,t=t, space=space,east=east,west=west,middle=middle,ccw=ccw,bold=bold); }else{ writecircle(text,where+[0,0,0],radius-h,rotate=rotate,font=font,h=h,t=t, space=space,east=east,west=west,middle=middle,ccw=ccw,bold=bold); } } }else{ // if (radius>0){ if (center==true) { rotate(-mmangle(radius)*(1-abs(rotate)/90),[0,0,1]) translate(where) writethecylinder(text,where,radius,height,r1=radius,r2=radius,h=h, rotate=rotate,t=t,font=font,face=face,up=up,down=down, east=east,west=west,center=center,space=space,rounded=rounded,bold=bold); } else{ rotate(-mmangle(radius)*(1-abs(rotate)/90),[0,0,1]) translate(where+[0,0,height/2]) writethecylinder(text,where,radius,height,r1=radius,r2=radius,h=h, rotate=rotate,t=t,font=font,face=face,up=up,down=down, east=east,west=west,center=center,space=space,rounded=rounded,bold=bold); } // the remarked out code is for cone shaped cylinders (not complete) // }else{ // if (center==true) { // rotate(-mmangle(radius)*(1-abs(rotate)/90),[0,0,1]) // translate(where) // writethecylinder(text,where,radius,height,r1=r1,r2=r2,h=h, // rotate=rotate,t=t,font=font,face=face,up=up,down=down, // east=east,west=west,center=center,space=space,rounded=rounded); // } else{ // rotate(-mmangle(radius)*(1-abs(rotate)/90),[0,0,1]) // translate(where+[0,0,height/2]) // writethecylinder(text,where,radius,height,r1=r1,r2=r2,h=h, // rotate=rotate,t=t,font=font,face=face,up=up,down=down, // east=east,west=west,center=center,space=space,rounded=rounded); // } // } } } module writecircle(text,where,radius){ wid=(.125* h *5.5 * space); widall=wid*(len(text)-1)/2; //angle that measures width of letters on sphere function NAngle(radius)=(wid/(pi2*radius))*360; //angle of half width of text function mmangle(radius)=(widall/(pi2*radius)*360); if (ccw==true){ rotate(-rotate+east-west,[0,0,1]){ rotate(-mmangle(radius-middle),[0,0,1]){ translate(where) for (r=[0:len(text)-1]){ rotate(-90+r*NAngle(radius-middle),[0,0,1]) // bottom out=-270+r translate([radius-middle,0,0]) //rotate(90,[1,0,0]) //rotate(90,[0,1,0]) rotate(-270,[0,0,1]) // flip text (botom out = -270) write(text[r],center=true,h=h,t=t,font=font,bold=bold); } } } }else{ rotate(-rotate-east+west,[0,0,1]){ rotate(mmangle(radius-middle),[0,0,1]){ translate(where) for (r=[0:len(text)-1]){ rotate(90-r*NAngle(radius-middle),[0,0,1]) // bottom out=-270+r translate([radius-middle,0,0]) //rotate(90,[1,0,0]) //rotate(90,[0,1,0]) rotate(270,[0,0,1]) // flip text (botom out = -270) write(text[r],center=true,h=h,t=t,font=font,bold=bold); } } } } } module writethecylinder(text,where,radius,height,r1,r2){ wid=(.125* h *5.5 * space); widall=wid*(len(text)-1)/2; //angle that measures width of letters on sphere function NAngle(radius)=(wid/(pi2*radius))*360*(1-abs(rotate)/90); //angle of half width of text function mmangle(radius)=(widall/(pi2*radius)*360); translate([0,0,up-down]) rotate(east-west,[0,0,1]) for (r=[0:len(text)-1]){ rotate(-90+(r*NAngle(radius)),[0,0,1]) translate([radius,0,-r*((rotate)/90*wid)+(len(text)-1)/2*((rotate)/90*wid)]) rotate(90,[1,0,0]) rotate(90,[0,1,0]) write(text[r],center=true,h=h,rotate=rotate,t=t,font=font,bold=bold); //echo("zloc=",height/2-r*((rotate)/90*wid)+(len(text)-1)/2*((rotate)/90*wid)); } } module writesphere(text,where,radius){ wid=(.125* h *5.5 * space); widall=wid*(len(text)-1)/2; echo("-----------------",widall,wid,mmangle(radius)); //angle that measures width of letters on sphere function NAngle(radius)=(wid/(pi2*radius))*360; //angle of half width of text function mmangle(radius)=(widall/(pi2*radius)*360); rotate(east-west,[0,0,1]){ rotate(south-north,[1,0,0]){ rotate(spin,[0,1,0]){ rotate(-mmangle(radius),[0,0,1]){ if ( rounded== false ){ translate(where) for (r=[0:len(text)-1]){ rotate(-90+r*NAngle(radius),[0,0,1]) translate([radius,0,0]) rotate(90,[1,0,0]) rotate(90,[0,1,0]) write(text[r],center=true,h=h,rotate=rotate,t=t,font=font,bold=bold); } }else{ difference(){ translate(where) for (r=[0:len(text)-1]){ rotate(-90+r*NAngle(radius),[0,0,1]) translate([radius,0,0]) rotate(90,[1,0,0]) rotate(90,[0,1,0]) write(text[r],center=true,h=h,rotate=rotate,t=t*2+h,font=font,bold=bold); } difference(){ //rounded outside sphere(radius+(t*2+h)*2); sphere(radius+t/2); } sphere(radius-t/2); // rounded inside for indented text } } } }}} } module writecube(text,where,size){ if (str(size)[0] != "["){ // its a square cube (size was not a matrix so make it one) writethecube(text,where,[size,size,size],h=h,rotate=rotate,space=space, t=t,font=font,face=face,up=up,down=down,right=right,left=left,bold=bold); }else{ // its not square writethecube(text,where,size,h=h,rotate=rotate,space=space, t=t,font=font,face=face,up=up,down=down,right=right,left=left,bold=bold); } } // I split the writecube module into 2 pieces.. easier to add features later module writethecube(text,where,size){ if (face=="front") { translate([where[0]+right-left,where[1]-size[1]/2,where[2]+up-down]) rotate(90,[1,0,0]) write(text,center=true,h=h,rotate=rotate,t=t,font=font,space=space,bold=bold); } if (face=="back") { translate([where[0]+right-left,where[1]+size[1]/2,where[2]+up-down]) rotate(90,[1,0,0]) // rotate around the x axis rotate(180,[0,1,0]) // rotate around the y axis (z before rotation) write(text,center=true,h=h,rotate=rotate,t=t,font=font,space=space,bold=bold); } if (face=="left") { translate([where[0]-size[0]/2,where[1]-right+left,where[2]+up-down ]) rotate(90,[1,0,0]) // rotate around the x axis rotate(90,[0,-1,0]) // rotate around the y axis (z before rotation) write(text,center=true,h=h,rotate=rotate,t=t,font=font,space=space,bold=bold); } if (face=="right") { translate([where[0]+size[0]/2,where[1]+right-left,where[2] +up-down]) rotate(90,[1,0,0]) // rotate around the x axis rotate(90,[0,1,0]) // rotate around the y axis (z before rotation) write(text,center=true,h=h,rotate=rotate,t=t,font=font,space=space,bold=bold); } if (face=="top") { translate([where[0]+right-left,where[1]+up-down,where[2]+size[2]/2 ]) write(text,center=true,h=h,rotate=rotate,t=t,font=font,space=space,bold=bold); } if (face=="bottom") { translate([where[0]+right-left,where[1]-up+down,where[2]-size[2]/2 ]) rotate(180,[1,0,0]) write(text,center=true,h=h,rotate=rotate,t=t,font=font,space=space,bold=bold); } } module write(word){ echo (h); echo (word); echo ("There are " ,len(word) ," letters in this string"); // echo ("The second letter is ",word[1]); // echo (str(word[0],"_")); minkowski() { rotate(rotate,[0,0,-1]){ for (r = [0:len(word)]){ // count off each character // if the letter is lower case, add an underscore to the end for file lookup if ((word[r] == "a" ) || (word[r]== "b") || (word[r]== "c") || (word[r]== "d") || (word[r]== "e") || (word[r]== "f") || (word[r]== "g") || (word[r]== "h") || (word[r]== "i") || (word[r]== "j") || (word[r]== "k") || (word[r]== "l") || (word[r]== "m") || (word[r]== "n") || (word[r]== "o") || (word[r]== "p") || (word[r]== "q") || (word[r]== "r") || (word[r]== "s") || (word[r]== "t") || (word[r]== "u") || (word[r]== "v") || (word[r]== "w") || (word[r]== "x") || (word[r]== "y" )|| (word[r]== "z")){ if (center == true) { translate([0,-h/2,0]){ scale([.125*h,.125*h,t]){ translate([ (-len(word)*5.5*space/2) + (r*5.5*space),0,0]) //offset(delta = 20, join_type = "round") { linear_extrude(height=1,convexity=10,center=true){ import(file = font,layer=str(word[r],"_")); }//} } } }else{ translate([0,0,t/2]){ scale([.125*h,.125*h,t]){ translate([r*5.5*space,0,0]) //offset(delta = 20, join_type = "round") { linear_extrude(height=1,convexity=10,center=true){ import(file = font,layer=str(word[r],"_")); }//} } } } }else{ if (center == true) { translate([0,-h/2,0]){ scale([.125*h,.125*h,t]){ translate([ (-len(word)*5.5*space/2) + (r*5.5*space),0,0]) //offset(delta = 20, join_type = "round") { linear_extrude(height=1,convexity=10,center=true){ import(file = font,layer=str(word[r])); }//} } } }else{ translate([0,0,t/2]){ scale([.125*h,.125*h,t]){ translate([r*5.5*space,0,0]) //offset(delta = 20, join_type = "round") { linear_extrude(height=1,convexity=10,center=true){ import(file = font,layer=str(word[r])); }//} } } } } } } cube([bold*.1*h,bold*.1*h,.00001]); } } /*writecylinder test translate([0,0,0]) %cylinder(r=20,h=40,center=true); color([1,0,0]) writecylinder("rotate=90",[0,0,0],20,40,center=true,down=0,rotate=90); writecylinder("rotate = 30,east = 90",[0,0,0],20,40,center=true,down=0,rotate=30,east=90); writecylinder("ccw = true",[0,0,0],20,40,center=true,down=0,face="top",ccw=true); writecylinder("middle = 8",[0,0,0],20,40,h=3,center=true,down=0,face="top",middle=8); writecylinder("face = top",[0,0,0],20,40,center=true,down=0,face="top"); writecylinder("east=90",[0,0,0],20,40,h=3,center=true,down=0,face="top",east=90); writecylinder("west=90",[0,0,0],20,40,h=3,center=true,down=0,face="top",ccw=true,west=90); writecylinder("face = bottom",[0,0,0],20,40,center=true,down=0,face="bottom"); */ /*writesphere test sphere(20); color([1,0,0]) writesphere("Hello World",[0,0,0],20,t=1,h=6); */ /* writecube test translate([30,30,30]) cube([10,15,30],center=true); write("hello",center=true,rotate =30); color([1,0,0]) writecube( "front",[30,30,30],[10,15,30],h=5,rotate=-90); color([0,1,0]) writecube( "back",[30,30,30],size=[10,15,30],h=5,face="back",rotate=90,t=4); color([0,0,1]) writecube( "left",[30,30,30],[10,15,30],h=5,face="left",up=5); color([1,1,0]) writecube( "right",where=[30,30,30],size=[10,15,30],h=5,face="right",rotate=55); color([1,0,1]) writecube( "top",where=[30,30,30],size=[10,15,30],h=5,face="top"); color([1,1,1]) writecube( "bttm",where=[30,30,30],size=[10,15,30],h=5,face="bottom",rotate=90); */ ================================================ FILE: brackets/flat-bracket.scad ================================================ /** \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(); ================================================ FILE: brackets/matrix-bracket.scad ================================================ /** \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); ================================================ FILE: brackets/octoscroller.scad ================================================ /** \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(); } ================================================ FILE: brackets/spiral.scad ================================================ /** \file * 3D printed brackets for spiral matrix display * * Horizontal or vertical connections are possible. * The spacing between the holes differs for each. */ use // vertical has only 10mm module vertical_bracket(sides, depth) { render() difference() { union() { 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); cylinder(r=6/2+0.4,h=3, $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); cylinder(r=6/2+0.4,h=3, $fs=1); } } } translate([0,4.5,10]) rotate([0,0,180]) scale(1.5) write(str(sides), center=true); } } for (i=[0:23]) { translate([(i%6)*35, floor(i/6)*30, 0]) { translate([0,-6,0]) vertical_bracket(i+5, 8); translate([0,+6,0]) vertical_bracket(i+5, 8); } } %translate([0,0,-0.5]) cube([285,153,1]); ================================================ FILE: default.config ================================================ 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 ================================================ FILE: dts/LEDscape.dts ================================================ /** \file * Try to play nice with the Beagle Bone device tree. * * But it really sucks. This is a waste of time; we can just use * a shell script to poke the gpio export and config files since this * is so borked. */ /dts-v1/; /plugin/; / { compatible = "ti,beaglebone-black"; /* identification */ part-number = "BB-LEDSCAPE"; version = "00A0"; dtbo = "cape-ledscape-00A0.dtbo"; /* state the resources this cape uses or prepare to get winged! */ exclusive-use = /* 32 IO pins for the PRU to use */ "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", "P9.11", "P9.12", "P9.13", "P9.14", "P9.15", "P9.16", "P9.17", "P9.18", "P9.19", "P9.20", // overrides the i2c bus "P9.21", "P9.22", "P9.23", "P9.24", "P9.26", "P9.27", "P9.41", "P9.42", // And we need the PRU "pruss"; fragment@0 { target = <&am33xx_pinmux>; __overlay__ { pruicss_ws281x_pins: pinmux_pruicss_ws281x_pins { // Mode 7 is GPIO output // GPIO0: 2 3 4 5 7 12 13 14 15 20 22 23 26 27 30 31 pinctrl-single,pins = < 0x090 0x7 /* P8.7 gpio2.2 */ 0x094 0x7 // P8.8 gpio2.3 0x09c 0x7 // P8.9 gpio2.5 0x098 0x7 // P8.10 gpio 2.4 0x034 0x7 // P8.11 gpio1.13 0x030 0x7 // P8.12 gpio1.12 0x024 0x7 // P8.13 gpio0.23 0x028 0x7 // P8.14 gpio0.26 0x03c 0x7 // P8.15 gpio1.15 0x038 0x7 // P8.16 gpio1.14 0x02c 0x7 // P8.17 gpio0.27 0x08c 0x7 // P8.18 gpio2.1 0x020 0x7 // P8.19 gpio0.22 0x07c 0x7 // P8.26 gpio1.29 0x070 0x7 // P9.11 gpio0.30 0x078 0x7 // P9.12 gpio1.28 0x074 0x7 // P9.13 gpio0.31 0x048 0x7 // P9.14 gpio1.18 0x040 0x7 // P9.15 gpio1.16 0x04c 0x7 // P9.16 gpio1.19 0x15c 0x7 // P9.17 gpio0.5 0x158 0x7 // P9.18 gpio0.4 0x17e 0x7 // P9.19 gpio0.13, overrides i2c 0x178 0x7 // P9.20 gpio0.12, overrides i2c 0x154 0x7 // P9.21 gpio0.3 0x150 0x7 // P9.22 gpio0.2 0x044 0x7 // P9.23 gpio1.17 0x184 0x7 // P9.24 gpio0.15 0x180 0x7 // P9.26 gpio0.14 //0x1a4 0x7 // P9.27 gpio3.19 //0x198 0x7 // P9.30 gpio3.16 0x1b4 0x7 // P9.41 gpio0.20 0x164 0x7 // P9.42 gpio0.7 >; }; }; }; /* fragment@1 { target = <&ocp>; __overlay__ { ws281x_pinmux_helper: helper { compatible = "bone-pinmux-helper"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ws281x>; status = "okay"; }; }; }; */ fragment@1{ target = <&pruss>; __overlay__{ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pruicss_ws281x_pins>; led_strips { pin-names = "s:0", "s:1", "s:2", "s:3", "s:4", "s:5", "s:6", "s:7", "s:8", "s:9", "s:10", "s:11", "s:12", "s:13", "s:14", "s:15", "s:16", "s:17", "s:18", "s:19", "s:20", "s:21", "s:22", "s:23", "s:24", "s:25", "s:26", "s:27", "s:28", "s:29", "s:30", "s:31"; gpios = < &gpio0 2 0 &gpio0 3 0 &gpio0 4 0 &gpio0 5 0 &gpio0 7 0 &gpio0 12 0 &gpio0 13 0 &gpio0 14 0 &gpio0 15 0 &gpio0 20 0 &gpio0 22 0 &gpio0 23 0 &gpio0 26 0 &gpio0 27 0 &gpio0 30 0 &gpio0 31 0 &gpio1 12 0 &gpio1 13 0 &gpio1 14 0 &gpio1 15 0 &gpio1 16 0 &gpio1 17 0 &gpio1 18 0 &gpio1 19 0 &gpio1 28 0 &gpio1 29 0 &gpio2 1 0 &gpio2 2 0 &gpio2 3 0 &gpio2 4 0 &gpio2 5 0 &gpio2 29 0 //&gpio3 16 0 //&gpio3 19 0 >; }; }; }; }; ================================================ FILE: dts/README.md ================================================ 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 ================================================ FILE: dts/angstrom.dts ================================================ /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"; }; }; ================================================ FILE: dts/cape-bone-octo.dts ================================================ /* * 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", "pruss", "ehrpwm1B"; 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 // 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 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"; }; }; /* // 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"; }; }; */ }; ================================================ FILE: dts/ubuntu-3.8.13-bone32.dts ================================================ /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 = "okay"; 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"; }; }; ================================================ FILE: fonts/json2bmp ================================================ #!/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 <<""; print< 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. ================================================ FILE: pcb/LEDscape.lbr ================================================ >NAME >VALUE >NAME >VALUE P8 P9 >NAME >VALUE <b>RJ45 Low Profile</b> Shield Type 1<p> For all RJ45 N and Z Series Models<br> Source: www.tycoelectronics.com .. ENG_DS_1654001_1099_RJ_L_0507.pdf >NAME >VALUE <b>RJ45 Low Profile</b> No Shield<p> For all RJ45 N and Z Series Models<br> Source: www.tycoelectronics.com .. ENG_DS_1654001_1099_RJ_L_0507.pdf >NAME >VALUE For Amphenol RJE73-188 >NAME >VALUE >NAME >VALUE <b>Small Outline Transistor</b><p> package type OT >NAME >VALUE >NAME >VALUE >NAME >VALUE P8 P9 >VALUE >NAME >NAME >VALUE >NAME >VALUE >NAME >VALUE >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. <b>CORCOM Modular RJ Jacks</b> No Shield<p> Source: www.tycoelectronics.com .. ENG_DS_1654001_1099_RJ_L_0507.pdf ================================================ FILE: pcb/LEDscape.sch ================================================ <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). ================================================ FILE: pcb/TODO ================================================ 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 ================================================ FILE: pcb/flat-20mm.scad ================================================ /** \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); } } ================================================ FILE: pcb/lightbuddy-transmitter.brd ================================================ Blinkinlabs USB-to-RS485 RJ45 signals: 1. D0+ 2. D0- 3. D1+ 4. N/C 5. N/C 6. D1- 7. GND 8. GND - D1 D0 + >NAME >VALUE <b>RESISTOR</b><p> chip >NAME >VALUE <b>CAPACITOR</b><p> chip >NAME >VALUE <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 Library of parts that we use for our Blinkinlabs designs. Some parts copied (and modified) from the excellent Sparkfun libraries. This is one we found in the parts drawer, need to get details for it. <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. ================================================ FILE: pcb/lightbuddy-transmitter.sch ================================================ >NAME >VALUE For Amphenol RJE73-188 >NAME >VALUE >NAME >VALUE <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 >NAME >VALUE <B>RESISTOR</B>, American symbol <B>CAPACITOR</B>, American symbol <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> Library of parts that we use for our Blinkinlabs designs. Some parts copied (and modified) from the excellent Sparkfun libraries. This is one we found in the parts drawer, need to get details for it. >VALUE >NAME >NAME >VALUE <b>PIN HEADER</b> ================================================ FILE: pcb/octoscroller.brd ================================================ 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. ================================================ FILE: pcb/octoscroller.sch ================================================ >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> ================================================ FILE: pcb/receiver-2x.brd ================================================ LEDscape 2x Receiver RevA 2015-08-17 Blinkinlabs, LLC RJ45 signals: 1. D0+ 2. D0- 3. D1+ 4. N/C 5. N/C 6. D1- 7. GND 8. GND + - + D - - D + - + - D + + D - >NAME >VALUE >NAME >VALUE <b>Small Outline Transistor</b><p> package type OT >NAME >VALUE >NAME >VALUE <b>RESISTOR</b><p> chip >NAME >VALUE <b>CAPACITOR</b><p> chip >NAME >VALUE <b>Zetex Power MOS FETs, Bridges, Diodes</b><p> http://www.zetex.com<p> <author>Created by librarian@cadsoft.de</author> <b>Small Outline Transistor</b> >VALUE >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>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. ================================================ FILE: pcb/receiver-2x.sch ================================================ <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> 5V supply symbol >NAME >VALUE >NAME >VALUE For Amphenol RJE73-188 >NAME >VALUE <b>Small Outline Transistor</b><p> package type OT >NAME >VALUE >NAME >VALUE >VALUE >NAME >NAME >VALUE >NAME >VALUE >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 >NAME >VALUE >NAME >VALUE >NAME >VALUE <B>RESISTOR</B>, American symbol <B>CAPACITOR</B>, American symbol <b>Zetex Power MOS FETs, Bridges, Diodes</b><p> http://www.zetex.com<p> <author>Created by librarian@cadsoft.de</author> <b>Small Outline Transistor</b> >VALUE >NAME >VALUE >NAME <b>MOS FET</b> ================================================ FILE: pcb/receiver-4x.brd ================================================ + - 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. ================================================ FILE: pcb/receiver-4x.sch ================================================ <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. ================================================ FILE: pcb/receiver.brd ================================================ - + 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. ================================================ FILE: pcb/receiver.sch ================================================ <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. ================================================ FILE: radials.config ================================================ ws2812 135,32 ================================================ FILE: src/demos/Makefile ================================================ ######### # # 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 ================================================ FILE: src/demos/cube-image.c ================================================ /** \file * Draw six images on the cube faces */ #include #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; } ================================================ FILE: src/demos/cube-life.c ================================================ /** \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; } ================================================ FILE: src/demos/fire.c ================================================ /** \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 512 #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; } ================================================ FILE: src/demos/identify.c ================================================ /** \file */ #include #include #include #include #include #include #include #include #include "ledscape.h" int main( int argc, char ** argv ) { int width = 256; 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 %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); int h = 4; const uint32_t colors[] = { 0xFF0000, 0x00FF00, 0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFF00, }; while (1) { if (h++ == 2*width) h = 10; for(int y = 0 ; y < height ; y++) { uint32_t * const row_ptr = &p[width*y]; const int scale = 63; for(int x = 5 ; x < width ; x++) { uint32_t color = row_ptr[x]; int r = (color >> 16) & 0xFF; int g = (color >> 8) & 0xFF; int b = (color >> 0) & 0xFF; r = (r * scale) / (scale+1); g = (g * scale) / (scale+1); b = (b * scale) / (scale+1); if (r < 10) r = 10; if (g < 10) g = 10; if (b < 10) b = 10; row_ptr[x] = r << 16 | g << 8 | b << 0; } } for(int y = 0 ; y < height ; y++) { uint32_t * const row_ptr = &p[width*y]; uint32_t color = colors[y % 6]; row_ptr[0] = y & 1 ? 0xFFFFFF : 0x040404; row_ptr[1] = y & 2 ? 0xFFFFFF : 0x040404; row_ptr[2] = y & 4 ? 0xFFFFFF : 0x040404; row_ptr[3] = y & 8 ? 0xFFFFFF : 0x040404; row_ptr[4] = y & 16 ? 0xFFFFFF : 0x040404; row_ptr[5] = color; row_ptr[h/2] = color; } 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; } ================================================ FILE: src/demos/life.c ================================================ /** \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; } ================================================ FILE: src/demos/lightcycles.c ================================================ /** \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); } } } ================================================ FILE: src/demos/matrix-test.c ================================================ /** \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; } ================================================ FILE: src/ledscape/Makefile ================================================ ######### # # Build the PRU and LEDscape libraries as well as the PRU firmware. # # TARGETS-y += $(LIBDIR)/matrix.bin TARGETS-y += $(LIBDIR)/ws281x.bin LIB-y += libledscape.a libledscape.srcs += \ ledscape.c \ pru.c \ util.c \ config.c \ fixed-font.c \ include ../../Makefile.common ================================================ FILE: src/ledscape/bitpattern.h ================================================ /** \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 ================================================ FILE: src/ledscape/config.c ================================================ /** \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_config_t * ledscape_matrix_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_matrix_config_t * const config = &config_union->matrix_config; 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++; 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_union; fail: fprintf(stderr, "%s: read or parse error on line %d\n", filename, line_num); fclose(file); 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; 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; } 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; } ================================================ FILE: src/ledscape/fixed-font.c ================================================ /** \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__, ________, ________, }, }; ================================================ FILE: src/ledscape/ledscape.c ================================================ /** \file * Userspace interface to the WS281x LED strip driver. * */ #include #include #include #include #include #include #include #include #include "ledscape.h" #include "pru.h" #define CONFIG_LED_MATRIX /** 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! * * 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[] = { 23, 27, 22, 10, 9, 8, 26, 11, 30, 31, 5, 3, 20, 4, 2, 14, 7, 15 }; static const uint8_t gpios1[] = { 13, 15, 12, 14, 29, 16, 17, 28, 18, 19 }; 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 gpios3[] = { 21, 19, 15, 14, 17, 16 }; #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 * 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; #if 0 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; #endif struct ledscape { ws281x_command_t * ws281x; pru_t * pru; unsigned width; unsigned height; unsigned frame_size; ledscape_config_t * config; }; #if 0 /** 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 * frame); } #endif static uint8_t bright_map( uint8_t val ) { return val; } static uint8_t * ledscape_remap( ledscape_t * const leds, uint8_t * const frame, unsigned x, unsigned y ) { #undef 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 (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*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 ; 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; // 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 //printf("%d,%d => %p %p %08x\n", x, y, pix, col_ptr, col); } } } static void ledscape_matrix_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; // 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. // while there are eight output chains, there are two simultaneous // per output chain. 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++) { const ledscape_matrix_panel_t * const panel = &config->panels[i][j]; // 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. uint8_t * const op = &out[6*i + j*panel_stride]; // copy the top half of this matrix ledscape_matrix_panel_copy( op, ip, config, panel->rot ); } } leds->ws281x->pixels_dma = leds->pru->ddr_addr + leds->frame_size * frame; // disable double buffering for now //frame = (frame + 1) & 1; } /** 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; 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 = ledscape_remap(leds, out, x, y); uint32_t p = row_in[x]; row_out[0*pru_stride] = (p >> 8) & 0xFF; // green row_out[1*pru_stride] = (p >> 16) & 0xFF; // red row_out[2*pru_stride] = (p >> 0) & 0xFF; // blue } } // 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; __asm__ __volatile__("":::"memory"); // 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; } } static ledscape_t * ledscape_matrix_init( ledscape_config_t * const config_union, int no_pru_init ) { ledscape_matrix_config_t * const config = &config_union->matrix_config; pru_t * const pru = pru_init(0); 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 = config->leds_width, .height = config->leds_height, .ws281x = pru->data_ram, .frame_size = frame_size, }; *(leds->ws281x) = (ws281x_command_t) { .pixels_dma = 0, // will be set in draw routine .num_pixels = (config->leds_width * 3) * 16, .command = 0, .response = 0, }; ledscape_gpio_init(); // Initiate the PRU program 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 printf("waiting for response\n"); while (!leds->ws281x->response) ; printf("got response\n"); return leds; } static ledscape_t * ledscape_strip_init( ledscape_config_t * const config_union, int no_pru_init ) { ledscape_strip_config_t * const config = &config_union->strip_config; pru_t * const pru = pru_init(0); 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 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) { .config = config_union, .pru = pru, .width = config->leds_width, .height = 48, // only 48 are supported, config->leds_height, .ws281x = pru->data_ram, .frame_size = frame_size, }; // LED strips, not matrix output *(leds->ws281x) = (ws281x_command_t) { .pixels_dma = 0, // will be set in draw routine .num_pixels = config->leds_width, // * leds->height, .command = 0, .response = 0, }; printf("pixels: %d\n", leds->ws281x->num_pixels); ledscape_gpio_init(); // Initiate the PRU program 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 printf("waiting for response\n"); while (!leds->ws281x->response) ; printf("got response\n"); return leds; } ledscape_t * ledscape_init( ledscape_config_t * const config, int no_pru_init ) { switch (config->type) { case LEDSCAPE_MATRIX: return ledscape_matrix_init(config, no_pru_init); case LEDSCAPE_STRIP: return ledscape_strip_init(config, no_pru_init); default: fprintf(stderr, "unknown config type %d\n", config->type); return NULL; } } void ledscape_draw( ledscape_t * const leds, const void * const 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; } } 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; } 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); (void) len; uint32_t * start = px; //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; } } /** 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 }, \ } \ ledscape_config_t ledscape_matrix_default = { .matrix_config = { .type = LEDSCAPE_MATRIX, .width = 256, .height = 128, .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), }, }, }; ================================================ FILE: src/ledscape/ledscape.h ================================================ /** \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 #define LEDSCAPE_MATRIX 1 #define LEDSCAPE_STRIP 2 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 type; 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; 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 * 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; #ifdef __cplusplus extern "C" { #endif extern ledscape_config_t ledscape_matrix_default; extern ledscape_t * ledscape_init( ledscape_config_t * config, int no_init_pru ); extern void ledscape_draw( ledscape_t * const leds, const void * const rgb // 4-byte rgb data ); 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 ); /** Flip a rectangular frame buffer to map the LED matrices */ void ledscape_matrix_remap( uint32_t * leds_out, const uint32_t * fb_in, const ledscape_matrix_config_t * config ); /** Write with a fixed-width 8px font */ void ledscape_printf( uint32_t * px, const size_t width, const uint32_t color, const char * fmt, ... ); /** Parse a config file */ ledscape_config_t * ledscape_config( const char * filename ); #ifdef __cplusplus }; #endif #endif ================================================ FILE: src/ledscape/matrix.p ================================================ // \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. */ #if 1 #define MATRIX_HEIGHT 8 // 32x16 matrices #else #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 #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 #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 #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 #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. * * \todo wtf "parameter too long": only 128 chars allowed? */ #define GPIO1_SEL_MASK (0\ |(1< #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_offset = ddr_addr; const size_t ddr_filelen = ddr_size; /* 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: %s", strerror(errno)); *pru = (pru_t) { .pru_num = pru_num, .data_ram = pru_data_mem, .data_ram_size = 8192, // how to determine? .ddr_addr = ddr_addr, .ddr = (void*)(ddr_mem), .ddr_size = ddr_size, }; fprintf(stderr, "%s: PRU %d: data %p @ %zu bytes, DMA %p / %"PRIxPTR" @ %zu bytes\n", __func__, pru_num, pru->data_ram, pru->data_ram_size, pru->ddr, pru->ddr_addr, pru->ddr_size ); return pru; } void pru_exec( pru_t * const pru, const char * const program ) { char * program_unconst = (char*)(uintptr_t) program; if (prussdrv_exec_program(pru->pru_num, program_unconst) < 0) 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(); } 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/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/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; } ================================================ FILE: src/ledscape/pru.h ================================================ /** \file * Simplified interface to the ARM PRU. * */ #ifndef _pru_h_ #define _pru_h_ #include #include #include "util.h" /** 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 ); /** 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 ================================================ FILE: src/ledscape/util.c ================================================ /** \file * Various utility functions */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "util.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; attr.c_oflag &= ~OPOST; tcsetattr(fd, TCSANOW, &attr); return fd; } void hexdump( FILE * const outfile, 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) fprintf(outfile, "%s%04zu:", i == 0 ? "": "\n", i); fprintf(outfile, " %02x", p[i]); } fprintf(outfile, "\n"); } ================================================ FILE: src/ledscape/util.h ================================================ /** \file * Utility functions. */ #ifndef _util_h_ #define _util_h_ #include #include #include #include #include #include #define warn(fmt, ...) \ do { \ fprintf(stderr, "%s:%d: " fmt, \ __func__, __LINE__, ## __VA_ARGS__); \ } 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) extern void hexdump( FILE * const outfile, const void * const buf, const size_t len ); 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 ================================================ FILE: src/ledscape/ws281x.hp ================================================ #ifndef _ws281x_HP_ #define _ws281x_HP_ #define AM33XX // *************************************** // * Global Macro definitions * // *************************************** #ifdef AM33XX // Refer to this mapping in the file - \prussdrv\include\pruss_intc_mapping.h #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 #define CONST_PRUDRAM C24 #define CONST_SHAREDRAM C28 #define CONST_L3RAM C30 #define CONST_DDR C31 // Address for the Constant table Programmable Pointer Register 0(CTPPR_0) #define CTBIR_0 0x22020 // Address for the Constant table Programmable Pointer Register 0(CTPPR_0) #define CTBIR_1 0x22024 // Address for the Constant table Programmable Pointer Register 0(CTPPR_0) #define CTPPR_0 0x22028 // Address for the Constant table Programmable Pointer Register 1(CTPPR_1) #define CTPPR_1 0x2202C #else // Refer to this mapping in the file - \prussdrv\include\pruss_intc_mapping.h #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 #define CONST_PRUDRAM C3 #define CONST_HPI C15 #define CONST_DSPL2 C28 #define CONST_L3RAM C30 #define CONST_DDR C31 // Address for the Constant table Programmable Pointer Register 0(CTPPR_0) #define CTPPR_0 0x7028 // Address for the Constant table Programmable Pointer Register 1(CTPPR_1) #define CTPPR_1 0x702C #endif .macro LD32 .mparam dst,src LBBO dst,src,#0x00,4 .endm .macro LD16 .mparam dst,src LBBO dst,src,#0x00,2 .endm .macro LD8 .mparam dst,src LBBO dst,src,#0x00,1 .endm .macro ST32 .mparam src,dst SBBO src,dst,#0x00,4 .endm .macro ST16 .mparam src,dst SBBO src,dst,#0x00,2 .endm .macro ST8 .mparam src,dst SBBO src,dst,#0x00,1 .endm #define sp r0 #define lr r23 #define STACK_TOP (0x2000 - 4) #define STACK_BOTTOM (0x2000 - 0x200) .macro stack_init mov sp, STACK_BOTTOM .endm .macro push .mparam reg, cnt sbbo reg, sp, 0, 4*cnt add sp, sp, 4*cnt .endm .macro pop .mparam reg, cnt sub sp, sp, 4*cnt lbbo reg, sp, 0, 4*cnt .endm // *************************************** // * Global Structure Definitions * // *************************************** // *************************************** // * Global Register Assignments * // *************************************** #endif //_ws281x_HP_ ================================================ FILE: src/ledscape/ws281x.p ================================================ // \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 * 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 // 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: //* ____ //* | | |______| //* 0 250 600 1250 offset //* 250 350 650 delta //* //*/ #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 1 #define r12_pin 15 #define g12_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 3 #define r31_pin 16 #define g31_gpio 0 #define g31_pin 20 #define b31_gpio 0 #define b31_pin 14 #define r32_gpio 3 #define r32_pin 19 #define g32_gpio 0 #define g32_pin 15 #define b32_gpio 3 #define b32_pin 21 #define r41_gpio 0 #define r41_pin 2 #define g41_gpio 1 #define g41_pin 17 #define b41_gpio 2 #define b41_pin 22 #define r42_gpio 0 #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 28 #define b52_gpio 0 #define b52_pin 31 #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 #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 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 1 #define b82_gpio 0 #define b82_pin 1 .origin 0 .entrypoint START #include "ws281x.hp" /** Mappings of the GPIO devices */ #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 /** 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 // 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. * * 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 #ifdef CONFIG_WS2812 MOV sleep_counter, (ns/5)-1-inst // ws2812 -- low speed #else MOV sleep_counter, (ns/10)-1-inst // ws2811 -- high speed #endif lab: 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 lab: LBBO r9, r8, 0xC, 4 // read the cycle counter SUB r9, r9, sleep_counter #ifdef CONFIG_WS2812 QBGT lab, r9, 2*(ns)/5 #else QBGT lab, r9, (ns)/5 #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) // 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; \ 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 // 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 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 // 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 // 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 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. 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 // 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 #ifdef AM33XX // Send notification to Host for program completion MOV R31.b0, PRU0_ARM_INTERRUPT+16 #else MOV R31.b0, PRU0_ARM_INTERRUPT #endif HALT ================================================ FILE: src/mta/Makefile ================================================ ######### # # Build the MTA sign demo # # BIN-y += mta-sign mta-sign.srcs += mta-sign.c mta-sign.srcs += mta-font.c include ../../Makefile.common ================================================ FILE: src/mta/mta-font.c ================================================ /** 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, }, }; ================================================ FILE: src/mta/mta-sign.c ================================================ /** \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; } ================================================ FILE: src/net/Makefile ================================================ ######### # # 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 ================================================ FILE: src/net/matrix-tcp-rx.c ================================================ /** \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; } ================================================ FILE: src/net/matrix-udp-rx.c ================================================ /** \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, 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++) { uint32_t * out = &fb[(height*frame_part/2 + 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, 0); 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; } ================================================ FILE: src/net/opc-rx.c ================================================ /** \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; } ================================================ FILE: src/perlin/Makefile ================================================ #============================================================================================== # 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 ================================================ FILE: src/perlin/gammalut.h ================================================ //============================================================================================= // 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 ================================================ FILE: src/perlin/globals.h ================================================ //============================================================================================= // 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 ================================================ FILE: src/perlin/knobs/knobs.ino ================================================ /** \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); } ================================================ FILE: src/perlin/pattern.cpp ================================================ //============================================================================================= // 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); } ================================================ FILE: src/perlin/pattern.h ================================================ //============================================================================================= // 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 ================================================ FILE: src/perlin/perlin-ledscape.cpp ================================================ //============================================================================================= // 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); } ================================================ FILE: src/perlin/pf2.cpp ================================================ //============================================================================================= // 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; } ================================================ FILE: src/perlin/pf2.h ================================================ //============================================================================================= // 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 ================================================ FILE: src/script/Makefile ================================================ SCRIPTDIR = ../src/script/ BINDIR = ../../bin/ scripts = bbb-network-setup \ find-serial \ install \ ledscape.service \ python-test \ run-ledscape \ run-videoplayer \ twitter-scroller \ videoplayer \ videoplayer.service all: $(scripts) .PHONY: $(scripts) $(scripts): if test ! -e $(BINDIR)$@; \ then ln -s $(SCRIPTDIR)$@ $(BINDIR); \ fi ================================================ FILE: src/script/bbb-network-setup ================================================ #!/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 ================================================ FILE: src/script/find-serial ================================================ #!/bin/sh # 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` SERIAL=`cat $DIR/../../serial` echo "/dev/$TTY: $SERIAL" done ================================================ FILE: src/script/install ================================================ #!/bin/sh -x # # Install the device tree fragment, the angstrom service file, # and make it runable. # DIRNAME="`dirname $0`" cd "$DIRNAME/.." die() { echo >&2 "$*" exit 1 } cp dts/CAPE-BONE-OCTO-00A0.dtbo /lib/firmware if [ ! -d /etc/systemd ]; then die "/etc/systemd does not exist? Is this not angstrom?" fi BOOT=/media/BEAGLEBONE UENV="$BOOT/uEnv.txt" 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/ systemctl enable ledscape.service systemctl status ledscape.service ================================================ FILE: src/script/ledscape.service ================================================ # # 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=/opt/LEDscape/ ExecStart=/opt/LEDscape/bin/run-ledscape KillMode=process [Install] WantedBy=multi-user.target ================================================ FILE: src/script/python-test ================================================ #!/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) #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) #font_sm = ImageFont.truetype("fonts/pf_tempesta_seven.ttf", 8) logo = Image.open("fonts/nycr.png") #logo.resize((64,64)) 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) 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") 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), t1, font=font_sm, fill=rainbow(i)) im_draw.text((256+60, 4), d, font=font, 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)) # 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) ================================================ FILE: src/script/run-ledscape ================================================ #!/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 exec ./bin/matrix-udp-rx -W 120 -H 32 -c "$CONFIGFILE" >/dev/null ================================================ FILE: src/script/run-videoplayer ================================================ #!/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 ./videoplayer --screenGeometry 120x32 -w 120 -l "$video" break done ================================================ FILE: src/script/twitter-scroller ================================================ #!/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) ================================================ FILE: src/script/videoplayer ================================================ #!/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 ================================================ FILE: src/script/videoplayer.service ================================================ # # 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 ================================================ FILE: strips.config ================================================ ws2812 240,32 ================================================ FILE: tall-cylinder.config ================================================ 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 ================================================ FILE: ubuntu/ledscape.conf ================================================ # # 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