commit d18e4cfd08a7d0ac0efafab4ff7f1812990d0fac Author: Imbus <> Date: Sat Mar 23 19:36:08 2024 +0100 Initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..060e848 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Compiled object files +*.o +*.hex + +# Executables +*.exe +*.out +*.elf + +# Build directories +build/ +bin/ + +# IDE and editor files +#.vscode/ +.idea/ +*.sublime-project +*.sublime-workspace + +# Dependency directories +lib/ +vendor/ + +# Log files +*.log + +# OS generated files +.DS_Store +Thumbs.db diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..46b298b --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,25 @@ +{ + "configurations": [ + { + "name": "AVR", + "includePath": [ + "${workspaceFolder}/**", + "/usr/avr/include" + ], + "defines": [], + "compilerPath": "/usr/bin/avr-gcc", + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "gcc-x64", + "compilerArgs": [ + "-mmcu=atmega328p", + "-Os", + "-Wall", + "-Wextra", + "-Wpedantic", + "-Werror" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..97a4116 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# AVR Playground + +[QEMU AVR Docs](https://www.qemu.org/docs/master/system/target-avr.html) + +```bash +sudo dnf install avr-binutils avr-libc avr-gcc avr-gcc-c++ avrdude qemu-system-avr +``` diff --git a/main.c b/main.c new file mode 100644 index 0000000..ba94b22 --- /dev/null +++ b/main.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include + +#define BLINK_TIME 0.5 // 1 second + +ISR(TIMER1_OVF_vect) { + PORTB ^= _BV(PORTB5); // Toggle the LED + TCNT1 = 65535 - (F_CPU / 1024 * BLINK_TIME); // Reset timer value +} + +int main(void) { + // Set PORTB5 as output + DDRB |= _BV(DDB5); + + // Initialize TIMER1 value + TCNT1 = 65535 - (F_CPU / 1024 * BLINK_TIME); + + // Set the prescaler to 1024 + TCCR1B |= _BV(CS10) | _BV(CS12); + + // Enable TIMER1 overflow interrupt + TIMSK1 |= _BV(TOIE1); + + // Enable global interrupts + // sei(); + + // Enable global interrupts with style + __asm__ __volatile__ ("sei"); + + while (1) { + // Keep in mind that the sleep mode depth will affect the wake up time + sleep_cpu(); // Deep sleep + // set_sleep_mode(SLEEP_MODE_IDLE); // Idle sleep + // sleep_mode(); // Sets the CPU to whatever mode was set + } +} diff --git a/makefile b/makefile new file mode 100644 index 0000000..6acd480 --- /dev/null +++ b/makefile @@ -0,0 +1,65 @@ +# AVR-GCC compiler +CC = avr-gcc + +# Programmer (change it according to your programmer) +PROGRAMMER = usbasp + +# MCU +MCU = atmega328p +QEMU_MACHINE_NAME = uno + +# Compiler flags +CFLAGS = -std=c2x -Wall -Wno-array-bounds -mmcu=$(MCU) -DF_CPU=16000000UL -O3 + +# Source files +SRCS = main.c + +# Object files +OBJS = $(SRCS:.c=.o) + +# Target file +TARGET = main + +# Default target +all: $(TARGET).hex + +# Compile C files +%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +# Link object files +$(TARGET).elf: $(OBJS) + $(CC) $(CFLAGS) $(OBJS) -o $(TARGET).elf + avr-strip $(TARGET).elf + +# Convert ELF to HEX +$(TARGET).hex: $(TARGET).elf + avr-objcopy -O ihex -R .eeprom $(TARGET).elf $(TARGET).hex + +# Flash the program +flash: $(TARGET).hex + avrdude -p $(MCU) -c $(PROGRAMMER) -U flash:w:$(TARGET).hex + +# Run the program in QEMU +qemu: $(TARGET).elf + qemu-system-avr -machine $(QEMU_MACHINE_NAME) -bios $(TARGET).elf + +# View the generated assembly +asm: $(TARGET).hex + avr-objdump -S $(TARGET).elf + +.PHONY: serial +serial: + picocom -b 9600 /dev/ttyUSB0 + +.PHONY: check +check: + avrdude -p $(MCU) -c $(PROGRAMMER) + +# Clean +.PHONY: clean +clean: + rm -f $(OBJS) $(TARGET).elf $(TARGET).hex + +size: main.hex + avr-size --mcu=atmega328p main.hex