Compare commits
	
		
			1 Commits
		
	
	
		
			master
			...
			tag-060926
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 01f957019f | 
| @@ -1,9 +0,0 @@ | ||||
| $Id: Changelog.txt,v 1.3 2007/01/02 21:03:54 rschaten Exp $ | ||||
|  | ||||
| * Release | ||||
|  | ||||
| - short delay before initialization | ||||
|  | ||||
| * Release 061002 | ||||
|  | ||||
| - initial release | ||||
							
								
								
									
										61
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								Makefile
									
									
									
									
									
								
							| @@ -1,61 +0,0 @@ | ||||
| # $Id: Makefile,v 1.3 2006/11/08 06:36:07 rschaten Exp $ | ||||
| # | ||||
| # Creates documentation and tarball for shipping. | ||||
|  | ||||
| TODAY=`date "+%y%m%d"` | ||||
| DIR=`basename \`pwd\`` | ||||
| PACKETNAME=$(DIR)_$(TODAY) | ||||
|  | ||||
| all: usage | ||||
|  | ||||
| usage: | ||||
| 	@echo "Usage of this makefile:" | ||||
| 	@echo "make docs       create documentation" | ||||
| 	@echo "make tarball    packs a tarball for shipping" | ||||
| 	@echo | ||||
| 	@echo "For further information, consult the documentation in Readme.txt." | ||||
|  | ||||
| # doc generation | ||||
| docs: readme pdf | ||||
| 	@echo "documentation created" | ||||
|  | ||||
| readme: doxygen | ||||
| 	echo "This file is auto-generated from the content of common/usbledfader.h" > Readme.txt | ||||
| 	echo "You'll have more fun if you read the HTML-content in htmldoc or the PDF." >> Readme.txt | ||||
| 	echo >> Readme.txt | ||||
| 	lynx -dump htmldoc/main.html >> Readme.txt | ||||
|  | ||||
| pdf: doxygen | ||||
| 	make -C latexdoc | ||||
| 	mv latexdoc/refman.pdf . | ||||
| 	rm -rf latexdoc | ||||
|  | ||||
| doxygen: | ||||
| 	doxygen common/usbledfader.doxygen | ||||
|  | ||||
| clean: | ||||
| 	rm -rf htmldoc latexdoc Readme.txt refman.pdf | ||||
| 	rm -f $(PACKETNAME).tar.gz | ||||
| 	make -C commandline clean | ||||
| 	make -C firmware clean | ||||
|  | ||||
| fw: | ||||
| 	make -C firmware | ||||
| 	mv -v firmware/main.hex firmware/main_$(TODAY).hex | ||||
|  | ||||
| tarball: fw clean docs | ||||
| 	@echo | ||||
| 	@echo | ||||
| 	@echo "I assume you updated the Changelog...? Press Enter to continue..." | ||||
| 	@read | ||||
| 	[ -e "firmware/main_$(TODAY).hex" ] || exit | ||||
| 	rm --force $(PACKETNAME).tar.gz;            \ | ||||
| 	tar --directory=..                          \ | ||||
| 	    --exclude=$(DIR)/Makefile               \ | ||||
| 	    --exclude=CVS                           \ | ||||
| 	    --exclude=*.ps                          \ | ||||
| 	    --create                                \ | ||||
| 	    --gzip                                  \ | ||||
| 	    --verbose                               \ | ||||
| 	    --file ../$(PACKETNAME).tar.gz $(DIR) | ||||
|  | ||||
							
								
								
									
										297
									
								
								Readme.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										297
									
								
								Readme.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,297 @@ | ||||
| $Id: Readme.txt,v 1.1 2006/09/26 18:18:27 rschaten Exp $ | ||||
|  | ||||
| For full documentation and examples, take a look at htmldoc/index.html. | ||||
|  | ||||
|  | ||||
| Introduction | ||||
| ============ | ||||
|  | ||||
| The USB-LED-Fader is a device to control a number of LEDs via USB. I built it | ||||
| to display the online-status of my internet-connection, the recording-status of | ||||
| my videorecorder, and warnings if the available disc-space is low. You can | ||||
| imagine an endless number of applications for this. | ||||
|  | ||||
| The LEDs are controlled with pulse width modulation (PWM). That way, they are | ||||
| not only on or off, it is possible to control the brightness. Included in the | ||||
| device is a number of 'waveforms' that can be displayed on the LEDs. That way, | ||||
| one LED can display some kind of a sinus- or triangular wave without any | ||||
| interaction with the controlling host. | ||||
|  | ||||
| Every LED can be controlled individually, each one can display it's own | ||||
| waveforms. | ||||
|  | ||||
| You can assign three different waves to every LED: two 'eternal' waves (0 & 1). | ||||
| They are displayed alternating until anything different is required. The third | ||||
| wave (2) is only displayed once, afterwards the device will switch back to | ||||
| alternating between the first two waves. | ||||
|  | ||||
| One wave is described by three parameters: the waveform, the duration for one | ||||
| repetition of the wave and the number of repetitions before switching to the | ||||
| next wave. | ||||
|  | ||||
| This version supports four LEDs, it should be quite easy to change that number | ||||
| between one and eight. I have not tested any number greater than four, but I | ||||
| can imagine that the load on the controller can be too high to reliably | ||||
| communicate via USB. | ||||
|  | ||||
| There are three parts included in the distribution: The firmware for an ATmega8 | ||||
| microcontroller, a commandline-client that can be run under Linux, and the | ||||
| circuits needed to build the device. | ||||
|  | ||||
| This project is based on the PowerSwitch example application by Objective | ||||
| Development. Like that, it uses Objective Development's firmware-only USB | ||||
| driver for Atmel's AVR microcontrollers. | ||||
|  | ||||
| Objective Development's USB driver is a firmware-only implementation of the USB | ||||
| 1.1 standard (low speed device) on cheap single chip microcomputers of Atmel's | ||||
| AVR series, such as the ATtiny2313 or even some of the small 8 pin devices. It | ||||
| implements the standard to the point where useful applications can be | ||||
| implemented. See the file "firmware/usbdrv/usbdrv.h" for features and | ||||
| limitations. | ||||
|  | ||||
|  | ||||
| Building and installing | ||||
| ======================= | ||||
|  | ||||
| Both, the firmware and Unix command line tool are built with "make". You may | ||||
| need to customize both makefiles. | ||||
|  | ||||
|  | ||||
| Firmware | ||||
| -------- | ||||
|  | ||||
| The firmware for this project requires avr-gcc and avr-libc (a C-library for | ||||
| the AVR controller). Please read the instructions at | ||||
| http://www.nongnu.org/avr-libc/user-manual/install_tools.html for how to | ||||
| install the GNU toolchain (avr-gcc, assembler, linker etc.) and avr-libc. | ||||
|  | ||||
| Once you have the GNU toolchain for AVR microcontrollers installed, you can run | ||||
| "make" in the subdirectory "firmware". You may have to edit the Makefile to use | ||||
| your preferred downloader with "make program". The current version is built for | ||||
| avrdude with a parallel connection to an stk200-compatible programmer. | ||||
|  | ||||
| If working with a brand-new controller, you may have to set the fuse-bits to | ||||
| use the external crystal: | ||||
|  | ||||
|  avrdude -p atmega8 -P /dev/parport0 -c sp12 -U hfuse:w:0xC9:m \ | ||||
|                                              -U lfuse:w:0x9F:m | ||||
|  | ||||
| Afterwards, you can compile and flash to the device: | ||||
|  | ||||
|  make program | ||||
|  | ||||
|  | ||||
| Commandline client | ||||
| ------------------ | ||||
|  | ||||
| The command line tool requires libusb. Please download libusb from | ||||
| http://libusb.sourceforge.net/ and install it before you compile. Change to | ||||
| directory "commandline", check the Makefile and edit the settings if required | ||||
| and type | ||||
|  | ||||
|  make | ||||
|  | ||||
| This will build the unix executable "usb-led-fader" which can be used to | ||||
| control the device. | ||||
|  | ||||
|  | ||||
| Usage | ||||
| ===== | ||||
|  | ||||
| Connect the device to the USB-port. All LED should flash up to indicate that | ||||
| the device is initialized. | ||||
|  | ||||
| Then use the commandline-client as follows: | ||||
|  | ||||
|  usb-led-fader status | ||||
|  usb-led-fader set <ledId> <waveId> <waveformId> <periodDuration> <repetitionCount> | ||||
|  usb-led-fader clear <ledId> | ||||
|  usb-led-fader reset | ||||
|  usb-led-fader show <waveformId> | ||||
|  usb-led-fader test | ||||
|  | ||||
| When using the set-function, it is possible to define several waves at once. | ||||
| You simply have to give the parameters for all waves. See examples below. | ||||
|  | ||||
|  | ||||
| Parameters | ||||
| ---------- | ||||
|  | ||||
| - ledId: ID of the LED (0-n, depending on the number of LEDs in your circuit). | ||||
| - waveId: ID of the wave (0-1: constant waves, 2: override). | ||||
| - waveformId: ID of the waveform (0-31: brightness, 32-37: patterns). For a | ||||
|   reference to the patterns, consult the function fade_calculateWaveform() in | ||||
|   the file "firmware/main.c". | ||||
| - periodDuration: Time in sec/10 for one repetition of the waveform. A value of | ||||
|   0 can be used to reset the wave. | ||||
| - repetitionCount: Number of repetitions before switching to the next wave. A | ||||
|   value of 0 can be used to repeat this forever. | ||||
|  | ||||
|  | ||||
| Examples | ||||
| -------- | ||||
|  | ||||
| -> Get the status of all LEDs: | ||||
|  usb-led-fader status | ||||
| This will result in an output similar to this: | ||||
|  LED 0           curid   curvalue     curpos     currep    nextupd | ||||
|                      0          2         26          0         23 | ||||
|        wave   waveform     length     repeat   duration    updtime | ||||
|           0         38         32          1         20         45 | ||||
|           1          0          1          1          0          1 | ||||
|           2          0          1          1          0          1 | ||||
|  LED 1           curid   curvalue     curpos     currep    nextupd | ||||
|                      0         14         19          0         19 | ||||
|        wave   waveform     length     repeat   duration    updtime | ||||
|           0         38         32          1         20         45 | ||||
|           1          0          1          1          0          1 | ||||
|           2          0          1          1          0          1 | ||||
|  LED 2           curid   curvalue     curpos     currep    nextupd | ||||
|                      0         31         16          0         43 | ||||
|        wave   waveform     length     repeat   duration    updtime | ||||
|           0         38         32          1         20         45 | ||||
|           1          0          1          1          0          1 | ||||
|           2          0          1          1          0          1 | ||||
|  LED 3           curid   curvalue     curpos     currep    nextupd | ||||
|                      0          6          9          0         39 | ||||
|        wave   waveform     length     repeat   duration    updtime | ||||
|           0         38         32          1         20         45 | ||||
|           1          0          1          1          0          1 | ||||
|           2          0          1          1          0          1 | ||||
| In this output, the values curvalue, curpos, nextupd and updtime are for | ||||
| debugging purposes only. They shouldn't be of interest to the common user. The | ||||
| meaning of the other values should be clear. | ||||
|  | ||||
| -> Set the first LED to keep a middle brightness: | ||||
|  usb-led-fader set 0 0 15 10 1 | ||||
| So, on LED 0 the wave 0 is set to waveform 15. It will stay there for one | ||||
| second and will be repeated once before switching to the next wave. There is no | ||||
| next wave because we didn't define one, so this waveform will stay forever. | ||||
|  | ||||
| -> Now set a second wave on the first LED, a little brighter than the one | ||||
|    before: | ||||
|  usb-led-fader set 0 1 25 10 1 | ||||
| This is wave 1 on LED 0, waveform 25 indicates a constant level of brightness. | ||||
| After setting the second wave, it will alternate with the first one after every | ||||
| second, because both waves have the same duration and the same number of | ||||
| repetitions. | ||||
|  | ||||
| -> Set a third wave on the first LED: | ||||
|  usb-led-fader set 0 2 36 20 5 | ||||
| This sets the third wave (wave 2) on the first LED. Waveform 36 is a nice | ||||
| sinus-like wave, so the LED starts to fade. One period of the fading takes 2 | ||||
| seconds, it is repeated for 5 times. Since this is the third wave, after the | ||||
| repetitions the LED returns to alternating between wave 0 and wave 1, this wave | ||||
| is discarded. | ||||
|  | ||||
| -> Set multiple waves at once: | ||||
|  usb-led-fader set 0 0 15 10 1 0 1 25 10 1 0 2 36 20 5 | ||||
| This will set all of the above waves at once. Thus, the first LED will first | ||||
| fade the sinus-wave five times, then start alternating between the two | ||||
| brightnesses in one-second-rhythm. | ||||
|  | ||||
| Clear the first LED: | ||||
|  usb-led-fader clear 0 | ||||
| This will clear all three waves on the first LED. | ||||
|  | ||||
| -> Reset the device: | ||||
|  usb-led-fader reset | ||||
| All LEDs will flash once, to indicate that the device is reset and the LEDs are | ||||
| working. | ||||
|  | ||||
| -> Show a waveform on the screen: | ||||
|  usb-led-fader show 36 | ||||
| This will lead to an output like the following: | ||||
|  wave 36 - length 64 | ||||
|  31:                              ***** | ||||
|  30:                            ********* | ||||
|  29:                           *********** | ||||
|  28:                         *************** | ||||
|  27:                        ***************** | ||||
|  26:                       ******************* | ||||
|  25:                       ******************* | ||||
|  24:                      ********************* | ||||
|  23:                     *********************** | ||||
|  22:                    ************************* | ||||
|  21:                    ************************* | ||||
|  20:                   *************************** | ||||
|  19:                  ***************************** | ||||
|  18:                  ***************************** | ||||
|  17:                 ******************************* | ||||
|  16:                ********************************* | ||||
|  15:               *********************************** | ||||
|  14:               *********************************** | ||||
|  13:              ************************************* | ||||
|  12:             *************************************** | ||||
|  11:             *************************************** | ||||
|  10:            ***************************************** | ||||
|   9:           ******************************************* | ||||
|   8:          ********************************************* | ||||
|   7:          ********************************************* | ||||
|   6:         *********************************************** | ||||
|   5:        ************************************************* | ||||
|   4:      ***************************************************** | ||||
|   3:     ******************************************************* | ||||
|   2:   *********************************************************** | ||||
|   1: **************************************************************** | ||||
|      ================================================================ | ||||
| Keep in mind that the width of the displayed wave corresponds to the length of | ||||
| the waveform. If you display a very simple one like the constant brightness | ||||
| levels (0-31), the length is 1. Therefore only one column is displayed. | ||||
|  | ||||
| -> Test the device: | ||||
|  usb-led-fader test | ||||
| This function sends many random numbers to the device. The device returns the | ||||
| packages, and the client looks for differences in the sent and the received | ||||
| numbers. | ||||
|  | ||||
|  | ||||
| Drawbacks | ||||
| ========= | ||||
|  | ||||
| As mentioned above, controlling the PWM for several LEDs is a lot of work for | ||||
| one small microcontroller. Speaking the USB protocol is so, either. Both | ||||
| combined result in a lot of load on the device, so the communication with the | ||||
| device is not 100% reliable. More than 99% though, at least in our tests. | ||||
|  | ||||
| SO BE WARNED: You should not use this device to control the state of your | ||||
| nuclear reactor. If you intend to use it in that way despite of this warning, | ||||
| please let me know... ;-) | ||||
|  | ||||
|  | ||||
| Files in the distribution | ||||
| ========================= | ||||
|  | ||||
| - Readme.txt: The file you are currently reading. | ||||
| - firmware: Source code of the controller firmware. | ||||
| - firmware/usbdrv: USB driver -- See Readme.txt in this directory for info | ||||
| - commandline: Source code of the host software (needs libusb). | ||||
| - common: Files needed by the firmware and the commandline-client. | ||||
| - circuit: Circuit diagrams in PDF and EAGLE 4 format. A free version of EAGLE | ||||
|   is available for Linux, Mac OS X and Windows from http://www.cadsoft.de/. | ||||
| - License.txt: Public license for all contents of this project, except for the | ||||
|   USB driver. Look in firmware/usbdrv/License.txt for further info. | ||||
| - Changelog.txt: Logfile documenting changes in soft-, firm- and hardware. | ||||
|  | ||||
|  | ||||
| Thanks! | ||||
| ======= | ||||
|  | ||||
| I'd like to thank Objective Development for the possibility to use their driver | ||||
| for my project. In fact, this project wouldn't exist without the driver. | ||||
|  | ||||
| And I'd like to give special credits to Thomas Stegemann. He wrote the | ||||
| PWM-stuff, and I guess it would have been nearly to impossible to me to write | ||||
| the rest of the project without his help since C isn't my natural language. | ||||
|  | ||||
|  | ||||
| About the license | ||||
| ================= | ||||
|  | ||||
| Our work - all contents except for the USB driver - are licensed under the GNU | ||||
| General Public License (GPL). A copy of the GPL is included in License.txt. The | ||||
| driver itself is licensed under a special license by Objective Development. See | ||||
| firmware/usbdrv/License.txt for further info. | ||||
|  | ||||
|  | ||||
| (c) 2006 by Ronald Schaten - http://www.schatenseite.de | ||||
							
								
								
									
										
											BIN
										
									
								
								circuit/circuit.brd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								circuit/circuit.brd
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 27 KiB | 
| @@ -1,30 +1,30 @@ | ||||
| Partlist | ||||
|  | ||||
| Exported from circuit.sch at  9/29/2006 20:55:14  | ||||
| Exported from circuit.sch at  9/15/2006 14:21:25  | ||||
|  | ||||
| EAGLE Version 4.16 Copyright (c) 1988-2005 CadSoft | ||||
|  | ||||
| Part     Value          Device             Package      Library  Sheet | ||||
| Part     Value          Device          Package      Library  Sheet | ||||
|  | ||||
| C1       100n           C-EU025-024X044    C025-024X044 rcl      1 | ||||
| C2       10u            CPOL-EUE2.5-5      E2,5-5       rcl      1 | ||||
| C3       22p            C-EU025-024X044    C025-024X044 rcl      1 | ||||
| C4       22p            C-EU025-024X044    C025-024X044 rcl      1 | ||||
| D1       3.6V           ZENER-DIODEDO35Z10 DO35Z10      diode    1 | ||||
| D2       3.6V           ZENER-DIODEDO35Z10 DO35Z10      diode    1 | ||||
| IC1      MEGA8-P        MEGA8-P            DIL28-3      avr      1 | ||||
| JP1      ISP            JP5Q               JP5Q         jumper   1 | ||||
| LED1                    LED5MM             LED5MM       led      1 | ||||
| LED2                    LED5MM             LED5MM       led      1 | ||||
| LED3                    LED5MM             LED5MM       led      1 | ||||
| LED4                    LED5MM             LED5MM       led      1 | ||||
| Q1       12MHz          CRYTALHC18U-V      HC18U-V      crystal  1 | ||||
| R1       2k2            R-EU_0207/10       0207/10      rcl      1 | ||||
| R2       4k7            R-EU_0207/10       0207/10      rcl      1 | ||||
| R4       68             R-EU_0207/10       0207/10      rcl      1 | ||||
| R5       68             R-EU_0207/10       0207/10      rcl      1 | ||||
| R6       470            R-EU_0207/10       0207/10      rcl      1 | ||||
| R7       470            R-EU_0207/10       0207/10      rcl      1 | ||||
| R8       470            R-EU_0207/10       0207/10      rcl      1 | ||||
| R9       470            R-EU_0207/10       0207/10      rcl      1 | ||||
| X1                      PN61729            PN61729      con-berg 1 | ||||
| C1       4,7u           CPOL-EUE2.5-5   E2,5-5       rcl      1 | ||||
| C2       100n           C-EU025-024X044 C025-024X044 rcl      1 | ||||
| C3       22p            C-EU025-024X044 C025-024X044 rcl      1 | ||||
| C4       22p            C-EU025-024X044 C025-024X044 rcl      1 | ||||
| IC1      MEGA8-P        MEGA8-P         DIL28-3      avr      1 | ||||
| IC2      LM317LZ        LM317LZ         TO92         linear   1 | ||||
| JP1      ISP            JP5Q            JP5Q         jumper   1 | ||||
| LED1                    LED5MM          LED5MM       led      1 | ||||
| LED2                    LED5MM          LED5MM       led      1 | ||||
| LED3                    LED5MM          LED5MM       led      1 | ||||
| LED4                    LED5MM          LED5MM       led      1 | ||||
| Q1       12MHz          CRYTALHC18U-V   HC18U-V      crystal  1 | ||||
| R1       432            R-EU_0207/10    0207/10      rcl      1 | ||||
| R2       240            R-EU_0207/10    0207/10      rcl      1 | ||||
| R3       1k5            R-EU_0207/10    0207/10      rcl      1 | ||||
| R4       68             R-EU_0207/10    0207/10      rcl      1 | ||||
| R5       68             R-EU_0207/10    0207/10      rcl      1 | ||||
| R6       1k             R-EU_0207/10    0207/10      rcl      1 | ||||
| R7       1k             R-EU_0207/10    0207/10      rcl      1 | ||||
| R8       1k             R-EU_0207/10    0207/10      rcl      1 | ||||
| R9       1k             R-EU_0207/10    0207/10      rcl      1 | ||||
| X1                      PN61729         PN61729      con-berg 1 | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * \file usb-led-fader.c | ||||
|  * \brief Commandline-tool for the USB-LED-Fader. | ||||
|  * \author Ronald Schaten | ||||
|  * \version $Id: usb-led-fader.c,v 1.2 2006/10/01 16:28:38 rschaten Exp $ | ||||
|  * \version $Id: usb-led-fader.c,v 1.1 2006/09/26 18:18:27 rschaten Exp $ | ||||
|  * | ||||
|  * License: See documentation. | ||||
|  */ | ||||
| @@ -348,7 +348,7 @@ void dev_reset(usb_dev_handle *handle, int argc, char** argv) { | ||||
|  * \param argc Number of arguments. | ||||
|  * \param argv Arguments. | ||||
|  */ | ||||
| void dev_show(usb_dev_handle *handle, int argc, char** argv) { | ||||
| int dev_show(int argc, char **argv) { | ||||
|     if (argc != 3) { | ||||
|         usage(argv[0]); | ||||
|         exit(1); | ||||
| @@ -415,7 +415,7 @@ int main(int argc, char **argv) | ||||
|     } else if (strcmp(argv[1], "reset") == 0) { | ||||
|         dev_reset(handle, argc, argv); | ||||
|     } else if (strcmp(argv[1], "show") == 0) { | ||||
|         dev_show(handle, argc, argv); | ||||
|         dev_reset(handle, argc, argv); | ||||
|     } else { | ||||
|         usage(argv[0]); | ||||
|         exit(1); | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  * \file usbledfader.h | ||||
|  * \brief Global definitions and datatypes, used by the firmware and the commandline-client. Also contains the main doxygen-documentation. | ||||
|  * \author Ronald Schaten & Thomas Stegemann | ||||
|  * \version $Id: usbledfader.h,v 1.4 2006/10/02 17:29:47 rschaten Exp $ | ||||
|  * \version $Id: usbledfader.h,v 1.1 2006/09/26 18:18:27 rschaten Exp $ | ||||
|  * | ||||
|  * License: See documentation. | ||||
|  */ | ||||
| @@ -19,17 +19,17 @@ | ||||
|  * it to display the online-status of my internet-connection, the | ||||
|  * recording-status of my videorecorder, and warnings if the available | ||||
|  * disc-space is low. You can imagine an endless number of applications for | ||||
|  * this. | ||||
|  * this.   | ||||
|  * | ||||
|  * The LEDs are controlled with pulse width modulation (PWM). That way, they | ||||
|  * are not only on or off, it is possible to control the brightness. Included | ||||
|  * in the device is a number of 'waveforms' that can be displayed on the LEDs. | ||||
|  * That way, one LED can display some kind of a sinus- or triangular wave | ||||
|  * without any interaction with the controlling host. | ||||
|  * | ||||
|  *  | ||||
|  * Every LED can be controlled individually, each one can display it's own | ||||
|  * waveforms. | ||||
|  * | ||||
|  *  | ||||
|  * You can assign three different waves to every LED: two 'eternal' waves (0 & | ||||
|  * 1). They are displayed alternating until anything different is required. The | ||||
|  * third wave (2) is only displayed once, afterwards the device will switch | ||||
| @@ -38,50 +38,50 @@ | ||||
|  * One wave is described by three parameters: the waveform, the duration for | ||||
|  * one repetition of the wave and the number of repetitions before switching to | ||||
|  * the next wave. | ||||
|  * | ||||
|  *  | ||||
|  * This version supports four LEDs, it should be quite easy to change that | ||||
|  * number between one and eight. I have not tested any number greater than | ||||
|  * four, but I can imagine that the load on the controller can be too high to | ||||
|  * reliably communicate via USB. | ||||
|  * | ||||
|  *  | ||||
|  * There are three parts included in the distribution: The firmware for an | ||||
|  * ATmega8 microcontroller, a commandline-client that can be run under Linux, | ||||
|  * and the circuits needed to build the device. | ||||
|  * | ||||
|  *  | ||||
|  * This project is based on the PowerSwitch example application by Objective | ||||
|  * Development. Like that, it uses Objective Development's firmware-only USB | ||||
|  * driver for Atmel's AVR microcontrollers. | ||||
|  * | ||||
|  *  | ||||
|  * Objective Development's USB driver is a firmware-only implementation of the | ||||
|  * USB 1.1 standard (low speed device) on cheap single chip microcomputers of | ||||
|  * Atmel's AVR series, such as the ATtiny2313 or even some of the small 8 pin | ||||
|  * devices. It implements the standard to the point where useful applications | ||||
|  * can be implemented. See the file "firmware/usbdrv/usbdrv.h" for features and | ||||
|  * limitations. | ||||
|  * | ||||
|  *  | ||||
|  * \section sec_install Building and installing | ||||
|  * | ||||
|  *  | ||||
|  * Both, the firmware and Unix command line tool are built with "make". You may | ||||
|  * need to customize both makefiles. | ||||
|  * | ||||
|  *  | ||||
|  * \subsection sec_fw Firmware | ||||
|  * | ||||
|  * The firmware for this project requires avr-gcc and avr-libc (a C-library for | ||||
|  * the AVR controller). Please read the instructions at | ||||
|  * http://www.nongnu.org/avr-libc/user-manual/install_tools.html for how to | ||||
|  * install the GNU toolchain (avr-gcc, assembler, linker etc.) and avr-libc. | ||||
|  * | ||||
|  *  | ||||
|  * Once you have the GNU toolchain for AVR microcontrollers installed, you can | ||||
|  * run "make" in the subdirectory "firmware". You may have to edit the Makefile | ||||
|  * to use your preferred downloader with "make program". The current version is | ||||
|  * built for avrdude with a parallel connection to an stk200-compatible | ||||
|  * programmer. | ||||
|  * | ||||
|  *  | ||||
|  * If working with a brand-new controller, you may have to set the fuse-bits to | ||||
|  * use the external crystal: | ||||
|  * | ||||
|  * \code | ||||
|  * avrdude -p atmega8 -P /dev/parport0 -c stk200 -U hfuse:w:0xC9:m -U lfuse:w:0x9F:m | ||||
|  * avrdude -p atmega8 -P /dev/parport0 -c sp12 -U hfuse:w:0xC9:m -U lfuse:w:0x9F:m | ||||
|  * \endcode | ||||
|  * | ||||
|  * Afterwards, you can compile and flash to the device: | ||||
| @@ -96,7 +96,7 @@ | ||||
|  * system's distribution or download libusb from http://libusb.sourceforge.net/ | ||||
|  * and install it before you compile. Change to directory "commandline", check | ||||
|  * the Makefile and edit the settings if required and type | ||||
|  * | ||||
|  *  | ||||
|  * \code | ||||
|  * make | ||||
|  * \endcode | ||||
| @@ -129,7 +129,8 @@ | ||||
|  *   circuit). | ||||
|  * - \e waveId: ID of the wave (0-1: constant waves, 2: override). | ||||
|  * - \e waveformId: ID of the waveform (0-31: brightness, 32-37: patterns). For | ||||
|  *   a reference to the patterns, use the show-function. | ||||
|  *   a reference to the patterns, consult the function fade_calculateWaveform() | ||||
|  *   in the file "firmware/main.c". | ||||
|  * - \e periodDuration: Time in sec/10 for one repetition of the waveform. A | ||||
|  *   value of 0 can be used to reset the wave. | ||||
|  * - \e repetitionCount: Number of repetitions before switching to the next | ||||
| @@ -282,15 +283,15 @@ | ||||
|  * combined result in a lot of load on the device, so the communication with | ||||
|  * the device is not 100% reliable. More than 99% though, at least in our | ||||
|  * tests. | ||||
|  * | ||||
|  *  | ||||
|  * <b>SO BE WARNED:</b> You should not use this device to control the state of | ||||
|  * your nuclear reactor. If you intend to use it in that way despite of this | ||||
|  * warning, please let me know... ;-) | ||||
|  * | ||||
|  * | ||||
|  *  | ||||
|  *  | ||||
|  * \section sec_files Files in the distribution | ||||
|  * | ||||
|  * - \e Readme.txt: Documentation, created from the htmldoc-directory. | ||||
|  *  | ||||
|  * - \e Readme.txt: The file you are currently reading. | ||||
|  * - \e firmware: Source code of the controller firmware. | ||||
|  * - \e firmware/usbdrv: USB driver -- See Readme.txt in this directory for | ||||
|  *   info | ||||
| @@ -303,26 +304,25 @@ | ||||
|  *   for the USB driver. Look in firmware/usbdrv/License.txt for further info. | ||||
|  * - \e Changelog.txt: Logfile documenting changes in soft-, firm- and | ||||
|  *   hardware. | ||||
|  * - \e refman.pdf: Full documentation of the software. | ||||
|  * | ||||
|  *  | ||||
|  * \section sec_thanks Thanks! | ||||
|  * | ||||
|  *  | ||||
|  * I'd like to thank <b>Objective Development</b> for the possibility to use | ||||
|  * their driver for my project. In fact, this project wouldn't exist without | ||||
|  * the driver. | ||||
|  * | ||||
|  *  | ||||
|  * And I'd like to give special credits to <b>Thomas Stegemann</b>. He wrote | ||||
|  * the PWM-stuff, and I guess it would have been nearly to impossible to me to | ||||
|  * write the rest of the project without his help since C isn't my natural | ||||
|  * language. | ||||
|  * | ||||
|  *  | ||||
|  * \section sec_license About the license | ||||
|  * | ||||
|  *  | ||||
|  * Our work - all contents except for the USB driver - are licensed under the | ||||
|  * GNU General Public License (GPL). A copy of the GPL is included in | ||||
|  * License.txt. The driver itself is licensed under a special license by | ||||
|  * Objective Development. See firmware/usbdrv/License.txt for further info. | ||||
|  * | ||||
|  *  | ||||
|  * <b>(c) 2006 by Ronald Schaten - http://www.schatenseite.de</b> | ||||
|  */ | ||||
|  | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| # $Id: Makefile,v 1.2 2007/11/15 14:42:07 rschaten Exp $ | ||||
| # $Id: Makefile,v 1.1 2006/09/26 18:18:27 rschaten Exp $ | ||||
|  | ||||
| AVRDUDE = avrdude -p atmega8 -P /dev/parport0 -c stk200 | ||||
|  | ||||
| @@ -46,25 +46,3 @@ disasm:	main.bin | ||||
|  | ||||
| cpp: | ||||
| 	$(COMPILE) -E main.c | ||||
|  | ||||
| # Fuse high byte: | ||||
| # 0xc9 = 1 1 0 0   1 0 0 1 | ||||
| #        ^ ^ ^ ^   ^ \-+-/ | ||||
| #        | | | |   |   +------ BOOT | ||||
| #        | | | |   +---------- EESAVE (preserve EEPROM on Chip Erase -> not preserved) | ||||
| #        | | | +-------------- CKOPT | ||||
| #        | | +---------------- SPIEN (enable serial programming -> enabled) | ||||
| #        | +------------------ WDTON (watchdog timer always on -> disable) | ||||
| #        +-------------------- RSTDISBL (disable external reset -> enabled) | ||||
| # | ||||
| # Fuse low byte: | ||||
| # 0x9f = 1 0 0 1   1 1 1 1 | ||||
| #        ^ ^ \+/   \--+--/ | ||||
| #        | |  |       +------- CKSEL 3..0 (clock selection -> HF PLL) | ||||
| #        | |  +--------------- SUT 1..0 (BOD enabled, fast rising power) | ||||
| #        | +------------------ BODEN | ||||
| #        +-------------------- BODLEVEL | ||||
| # external Crystal ===> CKSEL = 1111 | ||||
|  | ||||
| fuses: | ||||
|          $(AVRDUDE) -U hfuse:w:0xc9:m -U lfuse:w:0x9f:m | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * \file main.c | ||||
|  * \brief Firmware for the USB-LED-Fader. | ||||
|  * \author Ronald Schaten & Thomas Stegemann | ||||
|  * \version $Id: main.c,v 1.3 2007/01/02 21:04:47 rschaten Exp $ | ||||
|  * \version $Id: main.c,v 1.1 2006/09/26 18:18:27 rschaten Exp $ | ||||
|  * | ||||
|  * License: See documentation. | ||||
|  */ | ||||
| @@ -10,7 +10,6 @@ | ||||
| #include <avr/io.h> | ||||
| #include <avr/interrupt.h> | ||||
| #include <avr/pgmspace.h> | ||||
| #include <util/delay.h> | ||||
|  | ||||
| #include "usbdrv.h" | ||||
| #include "oddebug.h" | ||||
| @@ -248,26 +247,20 @@ uchar usbFunctionSetup(uchar data[8]) { | ||||
| int main(void) { | ||||
|     uchar i, j; | ||||
|     odDebugInit(); | ||||
|     DDRD = ~0;                  /* output SE0 for USB reset */ | ||||
|     PORTD = 0x00;               /* no pullups on USB pins */ | ||||
|     DDRB = ~0;                  /* output SE0 for USB reset */ | ||||
|     PORTB = 0x00;               /* no pullups on USB pins */ | ||||
|     DDRC = 0xff;                /* all outputs */ | ||||
|     PORTC = 0x00; | ||||
|     DDRD = 0x00;                /* all inputs */ | ||||
|     PORTD = 0x00; | ||||
|  | ||||
|     j = 0; | ||||
|     while (--j) {               /* USB Reset by device only required on Watchdog Reset */ | ||||
|         i = 0; | ||||
|         while (--i);            /* delay >10ms for USB reset */ | ||||
|     } | ||||
|     DDRD = ~USBMASK;            /* all outputs except USB data */ | ||||
|     DDRB = ~USBMASK;            /* all outputs except USB data */ | ||||
|     TCCR0 = 3;                  /* set prescaler to 1/64 */ | ||||
|  | ||||
|     for (i = 0; i < 10; i++) {  /* wait one second to prevent strange | ||||
|                                    effects when the USB-bus isn't | ||||
|                                    initialized (e. g. when the host system | ||||
|                                    is on standby. */ | ||||
|         _delay_ms(100); | ||||
|     } | ||||
|  | ||||
|     usbInit(); | ||||
|     sei(); | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * \file message_queue.c | ||||
|  * \brief A message queue used to exchange messages between two concurrent threads. | ||||
|  * \author Thomas Stegemann | ||||
|  * \version $Id: message_queue.c,v 1.2 2006/09/29 22:30:03 rschaten Exp $ | ||||
|  * \version $Id: message_queue.c,v 1.1 2006/09/26 18:18:27 rschaten Exp $ | ||||
|  * | ||||
|  * License: See documentation. | ||||
|  */ | ||||
| @@ -13,23 +13,22 @@ | ||||
|  | ||||
| /** Structure of the global data of the queue */ | ||||
| typedef struct S_messageQueue_GlobalData { | ||||
|     messageQueue_QueuedMessage queue[messageQueue_Size]; /**< the data elements of the queue */ | ||||
|     messageQueue_QueuedMessage queue[messageQueue_Size]; /**< the queue itself */ | ||||
|     messageQueue_SizeType begin; /**< the current start of the queue */ | ||||
|     messageQueue_SizeType end; /**< the current end of the queue, behind the last element */ | ||||
|     messageQueue_SizeType end; /**< the current end of the queue */ | ||||
| } messageQueue_GlobalData; | ||||
|  | ||||
| /** Global data of the queue */ | ||||
| static volatile messageQueue_GlobalData m_data; | ||||
|  | ||||
| /** | ||||
|  * increments an messageQueue index | ||||
|  * \param value position within the messageQueue | ||||
|  * \return the following position within the messageQueue | ||||
|  * Get the next entry fron the queue. | ||||
|  * \param value Number of the current entry. | ||||
|  * \return 0 if the value is larger than the queue, otherwise the next entry. | ||||
|  */ | ||||
| static inline messageQueue_SizeType messageQueue_next(messageQueue_SizeType value) { | ||||
|     value++; | ||||
|     if(value >= messageQueue_Size) { | ||||
|         /* messageQueue is used circular */ | ||||
|         value= 0; | ||||
|     } | ||||
|     return value; | ||||
| @@ -58,7 +57,8 @@ Boolean messageQueue_isEmpty(void) { | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Test if the queue is full. | ||||
|  * Test if the queue is full. If it is full, new entries will overwrite the | ||||
|  * first entries. | ||||
|  * \return True if it is full, otherwise false. | ||||
|  */ | ||||
| Boolean messageQueue_isFull(void) { | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * \file pwm_channels.c | ||||
|  * \brief Manages the values of the displayed channels. | ||||
|  * \author Thomas Stegemann | ||||
|  * \version $Id: pwm_channels.c,v 1.2 2006/09/29 22:30:03 rschaten Exp $ | ||||
|  * \version $Id: pwm_channels.c,v 1.1 2006/09/26 18:18:27 rschaten Exp $ | ||||
|  * | ||||
|  * License: See documentation. | ||||
|  */ | ||||
| @@ -41,10 +41,9 @@ void pwm_Channels_cleanup(void) { | ||||
|  * \return Current message. | ||||
|  */ | ||||
| static pwm_Channels_Message pwm_Channels_Message_get(pwm_Channels_ChannelBrightness channels[CHANNELS]) { | ||||
|     int j; /* index of the current channel */ | ||||
|     pwm_Channels_StepCounter i= 0; /* index of the current step */ | ||||
|     int j; | ||||
|     pwm_Channels_StepCounter i= 0; | ||||
|     pwm_Channels_Message message; | ||||
|     /* first step: switch on all channels at cycle 0 */ | ||||
|     message.step[i].field = 0; | ||||
|     for (j = 0; j < CHANNELS; j++) { | ||||
|         message.step[i].field |= channels[j].field; | ||||
| @@ -53,22 +52,14 @@ static pwm_Channels_Message pwm_Channels_Message_get(pwm_Channels_ChannelBrightn | ||||
|  | ||||
|     for (j = 0; j < CHANNELS; j++) { | ||||
|         if(channels[j].cycle == message.step[i].cycle) { | ||||
|             /* if cycle for this channel is reached | ||||
|                switch off channel in current step */ | ||||
|             message.step[i].field&= ~channels[j].field; | ||||
|         } else { | ||||
|             /* need another step for this channel: | ||||
|                set end of the current step | ||||
|                use copy of current step for next step | ||||
|                and switch off this channel | ||||
|             */ | ||||
|             message.step[i].cycle= channels[j].cycle; | ||||
|             i++; | ||||
|             message.step[i]= message.step[i-1]; | ||||
|             message.step[i].field&= ~channels[j].field; | ||||
|         } | ||||
|     } | ||||
|     /* last step ends at pwm_Timer_Cycles_Max */ | ||||
|     message.step[i].cycle= pwm_Timer_Cycles_Max; | ||||
|     return message; | ||||
| } | ||||
| @@ -104,7 +95,7 @@ void pwm_Channels_show(pwm_Channels channels) { | ||||
|     pwm_Channels_Message message; | ||||
|     pwm_Channels_ChannelBrightness channel_brightness[CHANNELS]; | ||||
|     for (i = 0; i < CHANNELS; i++) { | ||||
|         channel_brightness[i].field = 1 << i; // 1 << i equals 2^i: the channel i, uses the bit i | ||||
|         channel_brightness[i].field = 1 << i; // 1 << i equals 2^i | ||||
|         channel_brightness[i].cycle = pwm_Channels_BrightnessToCycles(channels.channel[i]); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  * \file pwm_timer.c | ||||
|  * \brief Controls the actual PWM-output. | ||||
|  * \author Thomas Stegemann | ||||
|  * \version $Id: pwm_timer.c,v 1.2 2006/09/29 22:30:03 rschaten Exp $ | ||||
|  * \version $Id: pwm_timer.c,v 1.1 2006/09/26 18:18:27 rschaten Exp $ | ||||
|  * | ||||
|  * License: See documentation. | ||||
|  */ | ||||
| @@ -106,14 +106,7 @@ SIGNAL(SIG_OUTPUT_COMPARE1A) { | ||||
|     sei(); | ||||
|     do { | ||||
|         if((m_data.step == pwm_Channels_StepCounter_Max) || (m_data.currentCycle == pwm_Timer_Cycles_Max)) { | ||||
|             /* end of current cycle reached*/  | ||||
|             if(m_data.readDone) { | ||||
|                 /* | ||||
|                   message received | ||||
|                   start a new cycle with the new values | ||||
|                   swap active message and message for reading | ||||
|                   message for reading is free for further messages from queue | ||||
|                 */ | ||||
|                 pwm_Channels_Message* pSwap= m_data.pActive; | ||||
|                 m_data.pActive= m_data.pRead; | ||||
|                 m_data.pRead=   pSwap; | ||||
| @@ -122,14 +115,14 @@ SIGNAL(SIG_OUTPUT_COMPARE1A) { | ||||
|                 m_data.step= 0; | ||||
|                 sleep= 0; | ||||
|             } else { | ||||
|                 /* could not read a new channels message in a whole cycle */ | ||||
|                 /* restart the cycle with the old values */ | ||||
|                 /* error could not read a new channels message in a whole cycle */ | ||||
|                 /* wait a complete cycle for the next message */ | ||||
|                 //sleep= pwm_Timer_Cycles_Max; | ||||
|                 m_data.currentCycle= 0; | ||||
|                 m_data.step= 0; | ||||
|                 sleep= 0; | ||||
|             } | ||||
|         } else { | ||||
|             /* process current step, go to next step */ | ||||
|             pwm_Timer_switchLed(m_data.pActive->step[m_data.step].field); | ||||
|             sleep= m_data.pActive->step[m_data.step].cycle - m_data.currentCycle; | ||||
|             m_data.currentCycle= m_data.pActive->step[m_data.step].cycle; | ||||
| @@ -138,9 +131,6 @@ SIGNAL(SIG_OUTPUT_COMPARE1A) { | ||||
|     } while(pwm_Timer_sleep(sleep)); | ||||
|  | ||||
|     if(!m_data.readDone && (sleep > pwm_Timer_Cycles_ReadMin)) { | ||||
|         /* | ||||
|           free space for reading and enough time to read: try to read | ||||
|         */ | ||||
|         if(messageQueue_read(m_data.pRead)) { | ||||
|             m_data.readDone= True; | ||||
|         } | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  * Tabsize: 4 | ||||
|  * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH | ||||
|  * License: Proprietary, free under certain conditions. See Documentation. | ||||
|  * This Revision: $Id: usbconfig.h,v 1.2 2006/09/29 21:51:07 rschaten Exp $ | ||||
|  * This Revision: $Id: usbconfig.h,v 1.1 2006/09/26 18:18:27 rschaten Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __usbconfig_h_included__ | ||||
| @@ -14,7 +14,7 @@ | ||||
| /** | ||||
|  * \file usbconfig.h | ||||
|  * \brief Configuration of the USB-driver. | ||||
|  * \version $Id: usbconfig.h,v 1.2 2006/09/29 21:51:07 rschaten Exp $ | ||||
|  * \version $Id: usbconfig.h,v 1.1 2006/09/26 18:18:27 rschaten Exp $ | ||||
|  */ | ||||
|  | ||||
|  | ||||
| @@ -30,7 +30,7 @@ the newest features and options. | ||||
|  | ||||
| /* ---------------------------- Hardware Config ---------------------------- */ | ||||
|  | ||||
| #define USB_CFG_IOPORTNAME      D | ||||
| #define USB_CFG_IOPORTNAME      B | ||||
| /* This is the port where the USB bus is connected. When you configure it to | ||||
|  * "PORTB", the registers PORTB, PINB (=PORTB-2) and DDRB (=PORTB-1) will be | ||||
|  * used. | ||||
| @@ -39,7 +39,7 @@ the newest features and options. | ||||
| /* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected. | ||||
|  * This MUST be bit 0 or 7. All other values will result in a compile error! | ||||
|  */ | ||||
| #define USB_CFG_DPLUS_BIT       2 | ||||
| #define USB_CFG_DPLUS_BIT       1 | ||||
| /* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected. | ||||
|  * This may be any bit in the port. Please note that D+ must also be connected | ||||
|  * to interrupt pin INT0! | ||||
|   | ||||
		Reference in New Issue
	
	Block a user