diff --git a/flake.nix b/flake.nix index 62a860e..d672974 100644 --- a/flake.nix +++ b/flake.nix @@ -30,21 +30,24 @@ pkgs = import nixpkgs { system = "x86_64-linux"; }; avr = pkgs.pkgsCross.avr.buildPackages; in pkgs.stdenv.mkDerivation rec { - name = "hello"; + name = "pwm"; src = ./.; + buildInputs = [ pkgs.simavr ]; + MCU = "attiny85"; CHIP_SELECT = "AVR_ATtiny85"; F_CPU = "8000000"; CFLAGS = ''-O -finline-functions -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -DF_CPU=${F_CPU} -std=gnu99 -D__${CHIP_SELECT}__=1 -mmcu=${MCU}''; buildPhase = '' - set -x - ${avr.gcc}/bin/avr-gcc ${CFLAGS} -I${src}/base/include/ -o main.elf ${src}/prototype/src/main.c + ${avr.gcc}/bin/avr-gcc ${CFLAGS} -I${src}/base/include/ -E -o main.post-cc ${src}/pwm/src/main.c + ${avr.gcc}/bin/avr-gcc ${CFLAGS} -I${src}/base/include/ -o main.elf ${src}/pwm/src/main.c $OBJCOPY -O ihex main.elf main.hex ''; installPhase = '' mkdir $out + cp main.post-cc $out cp main.elf main.hex $out ''; }; @@ -56,6 +59,7 @@ binutils gcc avrdude + simavr ]; in pkgs.mkShell { diff --git a/pwm/src/main.c b/pwm/src/main.c new file mode 100644 index 0000000..570a4da --- /dev/null +++ b/pwm/src/main.c @@ -0,0 +1,74 @@ +#include +#include +#include + +#include + +#define FIVE_SECOND_TICK (8000000 * 10) / 256 + +volatile uint32_t iteration = 0; + +void set_up_pwm(void); +void start_pwm(void); + +ISR(TIMER0_OVF_vect) { + if (iteration >= FIVE_SECOND_TICK) { + GTCCR |= _BV(TSM); + /* + PORTB &= ~(_BV(2)); + PORTB |= _BV(1); + */ + PORTB = _BV(1); + } else { + iteration += 1; + } +} + +void set_up_pwm(void) { + // Stop the clock + GTCCR = _BV(TSM) | _BV(PSR0); + + TCCR0B = _BV(CS00); + + // Set normal mode + TCCR0A = _BV(COM0A1) | _BV(WGM01) | _BV(WGM00); + + // Enable the overflow interrupt + TIMSK = _BV(TOIE0); +} + +void start_pwm(void) { + GTCCR &= ~(_BV(TSM)); +} + +int main (void) { + int8_t step = 1; + uint8_t target = 0; + + set_up_pwm(); + OCR0A = 0; + + PORTB = 0; + DDRB = _BV(2) | _BV(1) | _BV(0); + _delay_ms(50); + PORTB |= _BV(2); + + sei(); + start_pwm(); + + while (iteration != FIVE_SECOND_TICK) { + OCR0A = target; + target += step; + + if (target == 255) { + step = -1; + } else if (target == 0) { + step = 1; + } + + _delay_ms(10); + } + + while (1) {} +} +