Add a program that demonstrates PWM and interrupts
This commit is contained in:
parent
5487c27c50
commit
02716cc58b
10
flake.nix
10
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 {
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include <base.h>
|
||||
|
||||
#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) {}
|
||||
}
|
||||
|
Loading…
Reference in New Issue