pull/1/head
			
			
		
		
							parent
							
								
									6481532760
								
							
						
					
					
						commit
						83c253e445
					
				@ -1 +0,0 @@ | 
				
			|||||||
Subproject commit 21e5a96cdfa446af0266c3e37ab21ec1347f3646 | 
					 | 
				
			||||||
@ -0,0 +1,158 @@ | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					MCU	= atmega328p
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					F_CPU = 16000000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LFUSE = 0xFF
 | 
				
			||||||
 | 
					HFUSE = 0xDE
 | 
				
			||||||
 | 
					EFUSE = 0x05
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MAIN = main.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## If you've split your program into multiple files,
 | 
				
			||||||
 | 
					## include the additional .c source (in same directory) here
 | 
				
			||||||
 | 
					## (and include the .h files in your foo.c)
 | 
				
			||||||
 | 
					LOCAL_SOURCE = ws_driver.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Here you can link to one more directory (and multiple .c files)
 | 
				
			||||||
 | 
					# EXTRA_SOURCE_DIR = ../AVR-Programming-Library/
 | 
				
			||||||
 | 
					EXTRA_SOURCE_DIR =
 | 
				
			||||||
 | 
					EXTRA_SOURCE_FILES =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##########------------------------------------------------------##########
 | 
				
			||||||
 | 
					##########                 Programmer Defaults                  ##########
 | 
				
			||||||
 | 
					##########          Set up once, then forget about it           ##########
 | 
				
			||||||
 | 
					##########        (Can override.  See bottom of file.)          ##########
 | 
				
			||||||
 | 
					##########------------------------------------------------------##########
 | 
				
			||||||
 | 
					#19200
 | 
				
			||||||
 | 
					PROGRAMMER_TYPE = arduino
 | 
				
			||||||
 | 
					PROGRAMMER_ARGS = -b 57600 -P /dev/ttyUSB0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##########------------------------------------------------------##########
 | 
				
			||||||
 | 
					##########                   Makefile Magic!                    ##########
 | 
				
			||||||
 | 
					##########         Summary:                                     ##########
 | 
				
			||||||
 | 
					##########             We want a .hex file                      ##########
 | 
				
			||||||
 | 
					##########        Compile source files into .elf                ##########
 | 
				
			||||||
 | 
					##########        Convert .elf file into .hex                   ##########
 | 
				
			||||||
 | 
					##########        You shouldn't need to edit below.             ##########
 | 
				
			||||||
 | 
					##########------------------------------------------------------##########
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Defined programs / locations
 | 
				
			||||||
 | 
					CC = avr-gcc
 | 
				
			||||||
 | 
					OBJCOPY = avr-objcopy
 | 
				
			||||||
 | 
					OBJDUMP = avr-objdump
 | 
				
			||||||
 | 
					AVRSIZE = avr-size
 | 
				
			||||||
 | 
					AVRDUDE = sudo avrdude
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Compilation options, type man avr-gcc if you're curious.
 | 
				
			||||||
 | 
					CFLAGS = -std=gnu99 -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -Os -I. -I$(EXTRA_SOURCE_DIR)
 | 
				
			||||||
 | 
					CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
 | 
				
			||||||
 | 
					CFLAGS += -Wall -Wstrict-prototypes -Wno-main -Wno-strict-prototypes -Wno-comment
 | 
				
			||||||
 | 
					CFLAGS += -g2 -ggdb
 | 
				
			||||||
 | 
					CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax
 | 
				
			||||||
 | 
					CFLAGS += -std=gnu99
 | 
				
			||||||
 | 
					# CFLAGS += -lm
 | 
				
			||||||
 | 
					## CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm  ## for floating-point printf
 | 
				
			||||||
 | 
					## CFLAGS += -Wl,-u,vfprintf -lprintf_min      ## for smaller printf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Lump target and extra source files together
 | 
				
			||||||
 | 
					TARGET = $(strip $(basename $(MAIN)))
 | 
				
			||||||
 | 
					SRC = $(TARGET).c
 | 
				
			||||||
 | 
					EXTRA_SOURCE = $(addprefix $(EXTRA_SOURCE_DIR), $(EXTRA_SOURCE_FILES))
 | 
				
			||||||
 | 
					SRC += $(EXTRA_SOURCE)
 | 
				
			||||||
 | 
					SRC += $(LOCAL_SOURCE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## List of all header files
 | 
				
			||||||
 | 
					HEADERS = $(SRC:.c=.h)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## For every .c file, compile an .o object file
 | 
				
			||||||
 | 
					OBJ = $(SRC:.c=.o)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Generic Makefile targets.  (Only .hex file is necessary)
 | 
				
			||||||
 | 
					all: $(TARGET).hex size | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%.hex: %.elf | 
				
			||||||
 | 
						$(OBJCOPY) -R .eeprom -O ihex $< $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%.elf: $(SRC) | 
				
			||||||
 | 
						$(CC) $(CFLAGS) $(SRC) --output $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%.eeprom: %.elf | 
				
			||||||
 | 
						$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					debug: | 
				
			||||||
 | 
						@echo
 | 
				
			||||||
 | 
						@echo "Source files:"   $(SRC)
 | 
				
			||||||
 | 
						@echo "MCU, F_CPU, BAUD:"  $(MCU), $(F_CPU), $(BAUD)
 | 
				
			||||||
 | 
						@echo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Optionally create listing file from .elf
 | 
				
			||||||
 | 
					# This creates approximate assembly-language equivalent of your code.
 | 
				
			||||||
 | 
					# Useful for debugging time-sensitive bits,
 | 
				
			||||||
 | 
					# or making sure the compiler does what you want.
 | 
				
			||||||
 | 
					disassemble: $(TARGET).lst | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dis: disassemble | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					eeprom: $(TARGET).eeprom | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%.lst: %.elf | 
				
			||||||
 | 
						$(OBJDUMP) -S $< > $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Optionally show how big the resulting program is
 | 
				
			||||||
 | 
					size:  $(TARGET).elf | 
				
			||||||
 | 
						$(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					clean: | 
				
			||||||
 | 
						rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \
 | 
				
			||||||
 | 
						$(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \
 | 
				
			||||||
 | 
						$(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \
 | 
				
			||||||
 | 
						$(TARGET).eeprom
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					squeaky_clean: | 
				
			||||||
 | 
						rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##########------------------------------------------------------##########
 | 
				
			||||||
 | 
					##########              Programmer-specific details             ##########
 | 
				
			||||||
 | 
					##########           Flashing code to AVR using avrdude         ##########
 | 
				
			||||||
 | 
					##########------------------------------------------------------##########
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					flash: $(TARGET).hex | 
				
			||||||
 | 
						$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$<
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					flash_eeprom: $(TARGET).eeprom | 
				
			||||||
 | 
						$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$<
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					terminal: | 
				
			||||||
 | 
						$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					flash_arduino: PROGRAMMER_TYPE = arduino | 
				
			||||||
 | 
					flash_arduino: PROGRAMMER_ARGS = | 
				
			||||||
 | 
					flash_arduino: flash | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					flash_dragon_isp: PROGRAMMER_TYPE = dragon_isp | 
				
			||||||
 | 
					flash_dragon_isp: PROGRAMMER_ARGS = | 
				
			||||||
 | 
					flash_dragon_isp: flash | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##########------------------------------------------------------##########
 | 
				
			||||||
 | 
					##########       Fuse settings and suitable defaults            ##########
 | 
				
			||||||
 | 
					##########------------------------------------------------------##########
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Generic
 | 
				
			||||||
 | 
					FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fuses: | 
				
			||||||
 | 
						$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \
 | 
				
			||||||
 | 
						           $(PROGRAMMER_ARGS) $(FUSE_STRING)
 | 
				
			||||||
 | 
					show_fuses: | 
				
			||||||
 | 
						$(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Called with no extra definitions, sets to defaults
 | 
				
			||||||
 | 
					set_default_fuses:  FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m | 
				
			||||||
 | 
					set_default_fuses:  fuses | 
				
			||||||
@ -0,0 +1,13 @@ | 
				
			|||||||
 | 
					WS2812B RGB LED strip driving code | 
				
			||||||
 | 
					================================== | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This code is meant for 16MHz Arduino, but should work on any 16MHz AVR. It is in plain C, not the Arduino language. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All you need is `ws_driver.c` and `ws_driver.h`, and `config.c` where you define the port / pin information. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Connection | 
				
			||||||
 | 
					---------- | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Digital pin 8 on Arduino (PB0) is connected via a 200-500 R to WS2812B data input. In parallel to the LED strip is a 500-1000 uF capacitor that takes care of smoothening the power supply. Without the cap, the LEDs will flicker. | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It is recommended to use stronger power supply for the LED strip, a 30-led one takes around to 1A when fully powered. | 
				
			||||||
@ -0,0 +1,91 @@ | 
				
			|||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <avr/io.h> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define D0 0 | 
				
			||||||
 | 
					#define D1 1 | 
				
			||||||
 | 
					#define D2 2 | 
				
			||||||
 | 
					#define D3 3 | 
				
			||||||
 | 
					#define D4 4 | 
				
			||||||
 | 
					#define D5 5 | 
				
			||||||
 | 
					#define D6 6 | 
				
			||||||
 | 
					#define D7 7 | 
				
			||||||
 | 
					#define D8 0 | 
				
			||||||
 | 
					#define D9 1 | 
				
			||||||
 | 
					#define D10 2 | 
				
			||||||
 | 
					#define D11 3 | 
				
			||||||
 | 
					#define D12 4 | 
				
			||||||
 | 
					#define D13 5 | 
				
			||||||
 | 
					#define A0 0 | 
				
			||||||
 | 
					#define A1 1 | 
				
			||||||
 | 
					#define A2 2 | 
				
			||||||
 | 
					#define A3 3 | 
				
			||||||
 | 
					#define A4 4 | 
				
			||||||
 | 
					#define A5 5 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// port definitions
 | 
				
			||||||
 | 
					#define PORT_D0 PORTD | 
				
			||||||
 | 
					#define PORT_D1 PORTD | 
				
			||||||
 | 
					#define PORT_D2 PORTD | 
				
			||||||
 | 
					#define PORT_D3 PORTD | 
				
			||||||
 | 
					#define PORT_D4 PORTD | 
				
			||||||
 | 
					#define PORT_D5 PORTD | 
				
			||||||
 | 
					#define PORT_D6 PORTD | 
				
			||||||
 | 
					#define PORT_D7 PORTD | 
				
			||||||
 | 
					#define PORT_D8 PORTB | 
				
			||||||
 | 
					#define PORT_D9 PORTB | 
				
			||||||
 | 
					#define PORT_D10 PORTB | 
				
			||||||
 | 
					#define PORT_D11 PORTB | 
				
			||||||
 | 
					#define PORT_D12 PORTB | 
				
			||||||
 | 
					#define PORT_D13 PORTB | 
				
			||||||
 | 
					#define PORT_A0 PORTC | 
				
			||||||
 | 
					#define PORT_A1 PORTC | 
				
			||||||
 | 
					#define PORT_A2 PORTC | 
				
			||||||
 | 
					#define PORT_A3 PORTC | 
				
			||||||
 | 
					#define PORT_A4 PORTC | 
				
			||||||
 | 
					#define PORT_A5 PORTC | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PIN_D0 PIND | 
				
			||||||
 | 
					#define PIN_D1 PIND | 
				
			||||||
 | 
					#define PIN_D2 PIND | 
				
			||||||
 | 
					#define PIN_D3 PIND | 
				
			||||||
 | 
					#define PIN_D4 PIND | 
				
			||||||
 | 
					#define PIN_D5 PIND | 
				
			||||||
 | 
					#define PIN_D6 PIND | 
				
			||||||
 | 
					#define PIN_D7 PIND | 
				
			||||||
 | 
					#define PIN_D8 PINB | 
				
			||||||
 | 
					#define PIN_D9 PINB | 
				
			||||||
 | 
					#define PIN_D10 PINB | 
				
			||||||
 | 
					#define PIN_D11 PINB | 
				
			||||||
 | 
					#define PIN_D12 PINB | 
				
			||||||
 | 
					#define PIN_D13 PINB | 
				
			||||||
 | 
					#define PIN_A0 PINC | 
				
			||||||
 | 
					#define PIN_A1 PINC | 
				
			||||||
 | 
					#define PIN_A2 PINC | 
				
			||||||
 | 
					#define PIN_A3 PINC | 
				
			||||||
 | 
					#define PIN_A4 PINC | 
				
			||||||
 | 
					#define PIN_A5 PINC | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DDR_D0 DDRD | 
				
			||||||
 | 
					#define DDR_D1 DDRD | 
				
			||||||
 | 
					#define DDR_D2 DDRD | 
				
			||||||
 | 
					#define DDR_D3 DDRD | 
				
			||||||
 | 
					#define DDR_D4 DDRD | 
				
			||||||
 | 
					#define DDR_D5 DDRD | 
				
			||||||
 | 
					#define DDR_D6 DDRD | 
				
			||||||
 | 
					#define DDR_D7 DDRD | 
				
			||||||
 | 
					#define DDR_D8 DDRB | 
				
			||||||
 | 
					#define DDR_D9 DDRB | 
				
			||||||
 | 
					#define DDR_D10 DDRB | 
				
			||||||
 | 
					#define DDR_D11 DDRB | 
				
			||||||
 | 
					#define DDR_D12 DDRB | 
				
			||||||
 | 
					#define DDR_D13 DDRB | 
				
			||||||
 | 
					#define DDR_A0 DDRC | 
				
			||||||
 | 
					#define DDR_A1 DDRC | 
				
			||||||
 | 
					#define DDR_A2 DDRC | 
				
			||||||
 | 
					#define DDR_A3 DDRC | 
				
			||||||
 | 
					#define DDR_A4 DDRC | 
				
			||||||
 | 
					#define DDR_A5 DDRC | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define OUT 1 | 
				
			||||||
 | 
					#define IN 0 | 
				
			||||||
@ -0,0 +1,13 @@ | 
				
			|||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "arduino_pins.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define WS_PORT PORT_D8 | 
				
			||||||
 | 
					#define WS_BIT D8 | 
				
			||||||
 | 
					#define WS_DDR DDR_D8 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define WS_T_1H  700 | 
				
			||||||
 | 
					#define WS_T_1L  150 | 
				
			||||||
 | 
					#define WS_T_0H  150 | 
				
			||||||
 | 
					#define WS_T_0L  700 | 
				
			||||||
 | 
					#define WS_T_LATCH 6000 | 
				
			||||||
@ -0,0 +1,135 @@ | 
				
			|||||||
 | 
					#include <avr/io.h> | 
				
			||||||
 | 
					#include <avr/interrupt.h> | 
				
			||||||
 | 
					#include <avr/pgmspace.h> | 
				
			||||||
 | 
					#include <avr/cpufunc.h> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <util/delay.h> | 
				
			||||||
 | 
					#include <util/delay_basic.h> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdbool.h> | 
				
			||||||
 | 
					#include <stdint.h> | 
				
			||||||
 | 
					#include <math.h> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "arduino_pins.h" | 
				
			||||||
 | 
					#include "utils.h" | 
				
			||||||
 | 
					#include "config.h" | 
				
			||||||
 | 
					#include "ws_driver.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void init_io(void) SECTION(".init8"); | 
				
			||||||
 | 
					void init_io() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						set_bit(WS_DDR, WS_BIT, OUT); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void main() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						const uint8_t anim_step = 5; | 
				
			||||||
 | 
						const uint8_t anim_max = 255; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t r = 0; | 
				
			||||||
 | 
						uint8_t g = 0; | 
				
			||||||
 | 
						uint8_t b = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t step = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t r2 = anim_max; | 
				
			||||||
 | 
						uint8_t g2 = 0; | 
				
			||||||
 | 
						uint8_t b2 = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t step2 = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (1) { | 
				
			||||||
 | 
							r = r2; | 
				
			||||||
 | 
							g = g2; | 
				
			||||||
 | 
							b = b2; | 
				
			||||||
 | 
							step = step2; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (uint8_t i = 0; i < 72; i++) { | 
				
			||||||
 | 
								ws_send_rgb(r, g, b); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (i == 1) { | 
				
			||||||
 | 
									r2 = r; | 
				
			||||||
 | 
									g2 = g; | 
				
			||||||
 | 
									b2 = b; | 
				
			||||||
 | 
									step2 = step; | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								switch (step) { | 
				
			||||||
 | 
									case 0: | 
				
			||||||
 | 
										g += anim_step; | 
				
			||||||
 | 
										if (g == anim_max) step++; | 
				
			||||||
 | 
										break; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									case 1: | 
				
			||||||
 | 
										r -= anim_step; | 
				
			||||||
 | 
										if (r == 0) step++; | 
				
			||||||
 | 
										break; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									case 2: | 
				
			||||||
 | 
										b += anim_step; | 
				
			||||||
 | 
										if (b == anim_max) step++; | 
				
			||||||
 | 
										break; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									case 3: | 
				
			||||||
 | 
										g -= anim_step; | 
				
			||||||
 | 
										if (g == 0) step++; | 
				
			||||||
 | 
										break; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									case 4: | 
				
			||||||
 | 
										r += anim_step; | 
				
			||||||
 | 
										if (r == anim_max) step++; | 
				
			||||||
 | 
										break; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									default: | 
				
			||||||
 | 
										b -= anim_step; | 
				
			||||||
 | 
										if (b == 0) step = 0; | 
				
			||||||
 | 
										break; | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ws_show(); | 
				
			||||||
 | 
							_delay_ms(30); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// void main()
 | 
				
			||||||
 | 
					// {
 | 
				
			||||||
 | 
					// 	while (1) {
 | 
				
			||||||
 | 
					// 		uint8_t r = 250;
 | 
				
			||||||
 | 
					// 		uint8_t g = 0;
 | 
				
			||||||
 | 
					// 		uint8_t b = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 		uint8_t step = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 		for (uint8_t i = 0; i < 30; i++) {
 | 
				
			||||||
 | 
					// 			ws_send_rgb(r, g, b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 			switch (step) {
 | 
				
			||||||
 | 
					// 				case 0:
 | 
				
			||||||
 | 
					// 					r -= 50;
 | 
				
			||||||
 | 
					// 					g += 50;
 | 
				
			||||||
 | 
					// 					if (g == 250) step++;
 | 
				
			||||||
 | 
					// 					break;
 | 
				
			||||||
 | 
					// 				case 1:
 | 
				
			||||||
 | 
					// 					g -= 50;
 | 
				
			||||||
 | 
					// 					b += 50;
 | 
				
			||||||
 | 
					// 					if (b == 250) step++;
 | 
				
			||||||
 | 
					// 					break;
 | 
				
			||||||
 | 
					// 				case 2:
 | 
				
			||||||
 | 
					// 					b -= 50;
 | 
				
			||||||
 | 
					// 					r += 50;
 | 
				
			||||||
 | 
					// 					if (r == 250) step=0;
 | 
				
			||||||
 | 
					// 					break;
 | 
				
			||||||
 | 
					// 			}
 | 
				
			||||||
 | 
					// 		}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 		ws_show();
 | 
				
			||||||
 | 
					// 		_delay_ms(100);
 | 
				
			||||||
 | 
					// 	}
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,15 @@ | 
				
			|||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <avr/io.h> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// general macros
 | 
				
			||||||
 | 
					#define SECTION(pos) __attribute__((naked, used, section(pos))) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// pin manipulation
 | 
				
			||||||
 | 
					#define sbi(port, bit) (port) |= _BV(bit) | 
				
			||||||
 | 
					#define cbi(port, bit) (port) &= ~ _BV(bit) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define set_bit(port, bit, value) (port) = (((port) & ~_BV(bit)) | ((value) << (bit))) | 
				
			||||||
 | 
					#define get_bit(port, bit) (((port) >> (bit)) & 1) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define bus_pulse(port, bit) { sbi(port, bit); cbi(port, bit); } | 
				
			||||||
@ -0,0 +1,102 @@ | 
				
			|||||||
 | 
					#include <avr/io.h> | 
				
			||||||
 | 
					#include <util/delay_basic.h> | 
				
			||||||
 | 
					#include <stdint.h> | 
				
			||||||
 | 
					#include "ws_driver.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Raise the bus line */ | 
				
			||||||
 | 
					#define ws_high() (WS_PORT) |= (1 << WS_BIT) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Drop the bus line */ | 
				
			||||||
 | 
					#define ws_low() (WS_PORT) &= ~(1 << WS_BIT) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Convert nanoseconds to cycle count */ | 
				
			||||||
 | 
					#define ns2cycles(ns)  ( (ns) / (1000000000L / (signed long) F_CPU) ) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Wait c cycles */ | 
				
			||||||
 | 
					#define delay_c(c)  (((c) > 0) ? __builtin_avr_delay_cycles(c) :  __builtin_avr_delay_cycles(0)) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Wait n nanoseconds, plus c cycles  */ | 
				
			||||||
 | 
					#define delay_ns_c(ns, c)  delay_c(ns2cycles(ns) + (c)) | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ws_show() | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						ws_low(); | 
				
			||||||
 | 
						delay_ns_c(WS_T_LATCH, 0); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ws_send_byte(uint8_t bb) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						for (int8_t i = 7; i >= 0; --i) { | 
				
			||||||
 | 
							if (bb & (1 << i)) { | 
				
			||||||
 | 
								// send ONE
 | 
				
			||||||
 | 
								ws_high(); | 
				
			||||||
 | 
								delay_ns_c(WS_T_1H, -2); | 
				
			||||||
 | 
								ws_low(); | 
				
			||||||
 | 
								delay_ns_c(WS_T_1L, -10); // compensation for overhead
 | 
				
			||||||
 | 
							} else { | 
				
			||||||
 | 
								// send ZERO
 | 
				
			||||||
 | 
								ws_high(); | 
				
			||||||
 | 
								delay_ns_c(WS_T_0H, -2); | 
				
			||||||
 | 
								ws_low(); | 
				
			||||||
 | 
								delay_ns_c(WS_T_0L, -10); | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ws_send_rgb(uint8_t r, uint8_t g, uint8_t b) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						int8_t i; | 
				
			||||||
 | 
						// GREEN
 | 
				
			||||||
 | 
						for (i = 7; i >= 0; --i) { | 
				
			||||||
 | 
							if (g & (1 << i)) { | 
				
			||||||
 | 
								// send ONE
 | 
				
			||||||
 | 
								ws_high(); | 
				
			||||||
 | 
								delay_ns_c(WS_T_1H, -2); | 
				
			||||||
 | 
								ws_low(); | 
				
			||||||
 | 
								delay_ns_c(WS_T_1L, -10); | 
				
			||||||
 | 
							} else { | 
				
			||||||
 | 
								// send ZERO
 | 
				
			||||||
 | 
								ws_high(); | 
				
			||||||
 | 
								delay_ns_c(WS_T_0H, -2); | 
				
			||||||
 | 
								ws_low(); | 
				
			||||||
 | 
								delay_ns_c(WS_T_0L, -10); | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// RED
 | 
				
			||||||
 | 
						for (i = 7; i >= 0; --i) { | 
				
			||||||
 | 
							if (r & (1 << i)) { | 
				
			||||||
 | 
								// send ONE
 | 
				
			||||||
 | 
								ws_high(); | 
				
			||||||
 | 
								delay_ns_c(WS_T_1H, -2); | 
				
			||||||
 | 
								ws_low(); | 
				
			||||||
 | 
								delay_ns_c(WS_T_1L, -10); | 
				
			||||||
 | 
							} else { | 
				
			||||||
 | 
								// send ZERO
 | 
				
			||||||
 | 
								ws_high(); | 
				
			||||||
 | 
								delay_ns_c(WS_T_0H, -2); | 
				
			||||||
 | 
								ws_low(); | 
				
			||||||
 | 
								delay_ns_c(WS_T_0L, -10); | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// BLUE
 | 
				
			||||||
 | 
						for (i = 7; i >= 0; --i) { | 
				
			||||||
 | 
							if (b & (1 << i)) { | 
				
			||||||
 | 
								// send ONE
 | 
				
			||||||
 | 
								ws_high(); | 
				
			||||||
 | 
								delay_ns_c(WS_T_1H, -2); | 
				
			||||||
 | 
								ws_low(); | 
				
			||||||
 | 
								delay_ns_c(WS_T_1L, -10); | 
				
			||||||
 | 
							} else { | 
				
			||||||
 | 
								// send ZERO
 | 
				
			||||||
 | 
								ws_high(); | 
				
			||||||
 | 
								delay_ns_c(WS_T_0H, -2); | 
				
			||||||
 | 
								ws_low(); | 
				
			||||||
 | 
								delay_ns_c(WS_T_0L, -10); | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,52 @@ | 
				
			|||||||
 | 
					#pragma once | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -- AVR GCC utility for driving WS2812B and similar RGB LED stripes --
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// You must define the foillowing in config file or here:
 | 
				
			||||||
 | 
					// *  WS_PORT
 | 
				
			||||||
 | 
					// *  WS_BIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "config.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// The pin must be set to OUTPUT before using the output functions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// --- timing constraints (NS) ---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef WS_T_1H | 
				
			||||||
 | 
					#define WS_T_1H  700 | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef WS_T_1L | 
				
			||||||
 | 
					#define WS_T_1L  150 | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef WS_T_0H | 
				
			||||||
 | 
					#define WS_T_0H  150 | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef WS_T_0L | 
				
			||||||
 | 
					#define WS_T_0L  700 | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef WS_T_LATCH | 
				
			||||||
 | 
					#define WS_T_LATCH 7000 | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// More accurate timing
 | 
				
			||||||
 | 
					// #define WS_T_1H  800
 | 
				
			||||||
 | 
					// #define WS_T_1L  450
 | 
				
			||||||
 | 
					// #define WS_T_0H  200
 | 
				
			||||||
 | 
					// #define WS_T_0L  650
 | 
				
			||||||
 | 
					// #define WS_T_LATCH 50000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Latch and display the RGB values */ | 
				
			||||||
 | 
					void ws_show(void); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Send one byte to the RGB strip */ | 
				
			||||||
 | 
					void ws_send_byte(uint8_t b); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Send RGB color to the strip */ | 
				
			||||||
 | 
					void ws_send_rgb(uint8_t r, uint8_t g, uint8_t b); | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue