From c4ebe9bfc347f0acaa1319e982d9a999eb9063cb Mon Sep 17 00:00:00 2001 From: "Jan \"Yenya\" Kasprzak" Date: Mon, 1 Dec 2014 13:05:17 +0100 Subject: [PATCH] Three-channel LED blinker --- projects/led-blinker/.gitignore | 4 + projects/led-blinker/Makefile | 68 ++++++++++++++++ projects/led-blinker/main.c | 134 ++++++++++++++++++++++++++++++++ 3 files changed, 206 insertions(+) create mode 100644 projects/led-blinker/.gitignore create mode 100644 projects/led-blinker/Makefile create mode 100644 projects/led-blinker/main.c diff --git a/projects/led-blinker/.gitignore b/projects/led-blinker/.gitignore new file mode 100644 index 0000000..324be1b --- /dev/null +++ b/projects/led-blinker/.gitignore @@ -0,0 +1,4 @@ +*.eep +*.elf +*.hex +*.o diff --git a/projects/led-blinker/Makefile b/projects/led-blinker/Makefile new file mode 100644 index 0000000..1bcbac1 --- /dev/null +++ b/projects/led-blinker/Makefile @@ -0,0 +1,68 @@ + +PROGRAM=blinker +SRC=main.c +OBJ=$(SRC:.c=.o) + + +MCU=attiny25 +AVRDUDE_MCU=$(MCU) +AVRDUDE_PROGRAMMER=usbasp + +CFLAGS=-Wall -Os -mmcu=$(MCU) -DUSE_LOGGING=1 -DF_CPU=1000000UL -std=gnu99 +LDFLAGS= +AVRDUDE_FLAGS= -p$(AVRDUDE_MCU) -c $(AVRDUDE_PROGRAMMER) -B100 + +FORMAT=ihex + +CC=avr-gcc +OBJCOPY=avr-objcopy +OBJDUMP=avr-objdump +AVRDUDE=avrdude + +all: $(PROGRAM).hex $(PROGRAM).eep + +program: $(PROGRAM).hex $(PROGRAM).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) -U flash:w:$(PROGRAM).hex:i -U eeprom:w:$(PROGRAM).eep:i + +program_flash: $(PROGRAM).hex + $(AVRDUDE) $(AVRDUDE_FLAGS) -U flash:w:$(PROGRAM).hex:i + +program_eeprom: $(PROGRAM).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) eeprom:w:$(PROGRAM).eep:i + +dump_eeprom: + $(AVRDUDE) $(AVRDUDE_FLAGS) -U eeprom:r:eeprom.raw:r + od -tx1 eeprom.raw + +objdump: $(PROGRAM).elf + $(OBJDUMP) --disassemble $< + +.PRECIOUS : $(OBJ) $(PROGRAM).elf + +%.hex: %.elf + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +%.eep: %.elf + $(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +%.elf: $(OBJ) + $(CC) $(CFLAGS) $(OBJ) -o $@ $(LDFLAGS) + +%.o: %.c lights.h Makefile + $(CC) -c $(CFLAGS) $< -o $@ + +%.s: %.c lights.h Makefile + $(CC) -S -c $(CFLAGS) $< -o $@ + +%.o: %.S + $(CC) -c $(CFLAGS) $< -o $@ + +clean: + rm -f $(PROGRAM).hex $(PROGRAM).eep $(PROGRAM).elf *.o *.s eeprom.raw + +version.c: + ./version.pl > version.c + +.PHONY: all clean dump_eeprom program program_flash program_eeprom objdump version.c + diff --git a/projects/led-blinker/main.c b/projects/led-blinker/main.c new file mode 100644 index 0000000..70491ed --- /dev/null +++ b/projects/led-blinker/main.c @@ -0,0 +1,134 @@ +#include +#include +#include +#include + +/* + * Overview: + * three LEDs: + * PB1/OC1A yellow + * PB2 yellow + * PB4/OC1B red + */ + +static void init() +{ + DDRB |= _BV(PB1) | _BV(PB2) | _BV(PB4); + + // PWM setup, use T/C 1 + TCCR1 = _BV(CS10) // clock at CLK/1 + | _BV(PWM1A) // OCR1A in PWM mode + | _BV(COM1A1); // clear on compare match + GTCCR = _BV(PWM1B) // OCR1B in PWM mode + | _BV(COM1B1); // clear on compare match) + + OCR1C = 255; + OCR1A = 0; + OCR1B = 0; +} + + +static unsigned char levels[] = { + 0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 255 +}; +#define N_LEVELS (sizeof(levels)/sizeof(levels[0])) + +static void led_set(unsigned char led, unsigned char val) +{ + switch (led) { + case 0: + OCR1A = val < N_LEVELS ? levels[val] : levels[N_LEVELS-1]; + break; + case 1: + if (val) { + PORTB |= _BV(PB2); + } else { + PORTB &= ~_BV(PB2); + } + break; + case 2: + OCR1B = val < N_LEVELS ? levels[val] : levels[N_LEVELS-1]; + break; + } +} + +static unsigned char rand[] = { +193, 33, 133, 97, 139, 225, 40, 105, 110, 238, 57, 250, 26, 221, 166, 247, 138, 23, 107, 122, 154, 33, 201, 66, 154, 78, 137, 198, 86, 232, 38, 182, 16, 198, 73, 231, 58, 114, 58, 105, +}; +#define N_RAND (sizeof(rand)/sizeof(rand[0])) + +static void led0() +{ + static unsigned char r, l, exp; + +again: + if (l == exp) { + r++; + if (r > N_RAND-7) + r = 0; + exp = rand[r] >> 4; + if (exp >= N_LEVELS-4) + goto again; + } + + if (l < exp) { + l++; + } else if (l > exp) { + l--; + } + + led_set(0, l); +} + +static void led1() +{ + static unsigned char r; + unsigned char exp; + + led_set(1, 1); +#if 0 +again: + r++; + if (r > N_RAND) + r = 0; + exp = rand[r]; + + led_set(1, ((exp >> 3) & 1) ^ ((exp >> 5) & 1)); +#endif +} + +static void led2() +{ + static unsigned char r, l, exp; + +again: + if (l == exp) { + r++; + if (r > N_RAND) + r = 0; + exp = rand[r] & 0xF; + if (exp >= N_LEVELS) + goto again; + } + + if (l < exp) { + l++; + } else if (l > exp) { + l--; + } + + led_set(2, l); +} + +int main(void) +{ + init(); + + while (1) { + led0(); + led1(); + led2(); + _delay_ms(40); + } + +} -- 2.43.5