diff options
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..575493b --- /dev/null +++ b/README.md @@ -0,0 +1,107 @@ +# AVR assembly programming +This is a repo containing my attempts at programming in AVR assembly + +I want the every byte of macihne code executed by my processor to be written by +myself, so no libraries, no definitions, no nothing. + +### DISCLAIMER +Please have a sense of humor and don't take the jokes in this +README seriously. + +### WARNING +ChatGPT and any other genAI, as of 2025-09-05, can NOT write proper +AVR assembly. And I doubt they'll learn any time soon. Try it for yourself, +maybe you'll get something working if they write it completely from scratch, +but as for debugging, you are on your own. Use debugging tools mentioned below. + +Examples of generative AI being completely useless include: them trying to +persuade me that I've used the wrong interrupt vector address, mixing up +`out`/`sts` and `in`/`lds` instructions, mixing up addresses of IO registers, +writing/reading data from wrong registers (like mixing up `TIMSK`/`TIFR`, +`PINx/PORTx`), not knowing how to actually compile the code and so much more, +not unserstanding how timers work and so on. Save yourself some time, don't use +genAI. + +## How can I use it? +Firstly, as an example of how to program in assembly for +AVR. I am not responsible for the quality though :silly:. My only source is +datasheets. + +Secondly, there is a really useful [Makefile](Makefile) that you can copy to use +with your own projects. Most variables do not need to be changed there, maybe +just the `MCUPATH`. Name a file `something.s`, and then run `make +TARGET=something` to build, or `make TARGET=something flash` to upload your +code to the arduino. You can set the `TARGET` as an environment variable to +aviod typing it in each invokation of `make`. + +Thirdly, for debugging. Run `make TARGET=something sim`, then run `avr-gdb +something`, when inside of it, type `target remote :1234` and you're good to go. +`make sim` automatically detects wheher the simulation is already running and +forks to background, so to rerun the simulation, just type `make sim` again: it +will rebuild the file, and you won't even have to restart gdb (it will preserve +breakpoints), just retype the `target remote :1234` command. I find this +workflow satisfying, and it does not exhaust my arduino flash memory by +flashing the program every 30 seconds there. I think I will add a debugging +guide as well... + +## Dependencies +### Software +* `make` +* avr toolchain (`avr-as`, `avr-ld`, `avr-objcopy`, `avr-objdump`) +* `avrdude` (flash tool) +* For debugging: `avr-gdb` + `simavr` (or `qemu-system-avr`, but I had problems + with it) + +Not that you don't actually need `avr-libc` or `avr-gcc` to build assembly. +### Hardware +* an ARDUINO UNO board, or any other AVR-based microcontroller if you change + the variables in Makefile. Note that most of the variables can be changed + from the environment. +* wirez +* rizz + +### Dependency installation +* Arch linux: `# pacman -S avr-binutils avrdude`. For C development, you also + need to install `avr-gcc` and `avr-libc`. For debugging, `avr-gdb` and + `simavr` [\[AUR\]](https://aur.archlinux.org/packages/simavr) + [\[CLONE\]](https://aur.archlinux.org/simavr.git) +* Any other non-superior distro: read the fucking manual + +## Why? +- to have fun. + +## Useful resources +* [ATMega328p datasheet](https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf) +* [AVR instruction manual](https://ww1.microchip.com/downloads/en/DeviceDoc/AVR-Instruction-Set-Manual-DS40002198A.pdf) +* [AVR130: Setup and use of AVR Timers](https://ww1.microchip.com/downloads/en/Appnotes/Atmel-2505-Setup-and-Use-of-AVR-Timers_ApplicationNote_AVR130.pdf) +* [Arduino UNO R3 info](https://docs.arduino.cc/hardware/uno-rev3/), [PINOUT](https://docs.arduino.cc/resources/pinouts/A000066-full-pinout.pdf) + +## Read this if you are going into it blind +This section contains some of the pain that I've gone through while doing this +programming journey. If you don't want to make same mistakes, please take your +time to read it. + +0. AVR interrupt addresses from datasheet are not the same ones you specify in + assembly! <br> + For example, TIMER1 COMPA (timer 1 compare A match) has address + `0x0016` in the datasheet, but in assembly you have to align it like this: + ```asm + .org 0x002C: jmp timer1_int + ``` + Why? Because they probably refer to "instruction address", not to "memory + address". Is it said anywhere? No. Can you figure it out by compiling + corresponding C code and looking at disassembly? Yes, but you will spend 5 + hours trying to understand why your interrupt is not working. +0. Don't forget to link your file after compiling! <br> + This would have not been a problem on a processor that has an OS, because + the file just wouldn't run unless you link it. But here you're using + `objcopy`. That means that ALL jumps and calls will be broken in your + assembly. I thought that this was a bug for so long, dont be like me. +0. I've said this before, but don't ever try to use AI, or even worse, vibe + code the microcontroller. It's just not going to work, you will loose time + instead of saving it. You can vibecode a crappy website in react only because + there is so much training data for it. But almost entirety of AVR programming + is done in C++, thanks to fucking nobody. But I mean, it is a good thing that + AI can't comprehend assembly. It means you'll have more fun exploring the old + fashined way ;) +0. I will add entries to this list as I go... |