From 46b57676df609623515f691b0af46192ecc74615 Mon Sep 17 00:00:00 2001 From: Manfred Steiner <sx@htl-kaindorf.at> Date: Sun, 27 Nov 2022 16:24:15 +0100 Subject: [PATCH] simuc option board, debian packet creation --- README.md | 33 +- examples/Makefile | 2 + examples/simuc/.gitignore | 4 + examples/simuc/.vscode/launch.json | 21 + examples/simuc/.vscode/settings.json | 87 + examples/simuc/.vscode/tasks.json | 26 + examples/simuc/Makefile | 111 ++ examples/simuc/README.md | 64 + .../htl-simuc_version_arch/DEBIAN/control | 10 + .../dpkg/htl-simuc_version_arch/usr/bin/simuc | 1 + .../usr/share/doc/htl-simuc/copyright | 43 + .../usr/share/doc/htl-simuc/readme | 5 + .../usr/share/htl-simuc/readme | 1 + .../simavr/sim/avr/avr_mcu_section.h | 332 ++++ .../share/htl-simuc/simavr/sim/avr_acomp.c | 241 +++ .../share/htl-simuc/simavr/sim/avr_acomp.h | 89 + .../usr/share/htl-simuc/simavr/sim/avr_adc.c | 427 +++++ .../usr/share/htl-simuc/simavr/sim/avr_adc.h | 193 +++ .../share/htl-simuc/simavr/sim/avr_bitbang.c | 248 +++ .../share/htl-simuc/simavr/sim/avr_bitbang.h | 117 ++ .../share/htl-simuc/simavr/sim/avr_eeprom.c | 148 ++ .../share/htl-simuc/simavr/sim/avr_eeprom.h | 131 ++ .../share/htl-simuc/simavr/sim/avr_extint.c | 228 +++ .../share/htl-simuc/simavr/sim/avr_extint.h | 129 ++ .../share/htl-simuc/simavr/sim/avr_flash.c | 145 ++ .../share/htl-simuc/simavr/sim/avr_flash.h | 92 ++ .../share/htl-simuc/simavr/sim/avr_ioport.c | 340 ++++ .../share/htl-simuc/simavr/sim/avr_ioport.h | 148 ++ .../usr/share/htl-simuc/simavr/sim/avr_lin.c | 106 ++ .../usr/share/htl-simuc/simavr/sim/avr_lin.h | 55 + .../usr/share/htl-simuc/simavr/sim/avr_spi.c | 119 ++ .../usr/share/htl-simuc/simavr/sim/avr_spi.h | 107 ++ .../share/htl-simuc/simavr/sim/avr_timer.c | 985 +++++++++++ .../share/htl-simuc/simavr/sim/avr_timer.h | 176 ++ .../usr/share/htl-simuc/simavr/sim/avr_twi.c | 521 ++++++ .../usr/share/htl-simuc/simavr/sim/avr_twi.h | 116 ++ .../usr/share/htl-simuc/simavr/sim/avr_uart.c | 546 ++++++ .../usr/share/htl-simuc/simavr/sim/avr_uart.h | 229 +++ .../usr/share/htl-simuc/simavr/sim/avr_usb.c | 801 +++++++++ .../usr/share/htl-simuc/simavr/sim/avr_usb.h | 74 + .../share/htl-simuc/simavr/sim/avr_watchdog.c | 231 +++ .../share/htl-simuc/simavr/sim/avr_watchdog.h | 96 ++ .../share/htl-simuc/simavr/sim/fifo_declare.h | 189 +++ .../usr/share/htl-simuc/simavr/sim/run_avr.c | 287 ++++ .../usr/share/htl-simuc/simavr/sim/sim_avr.c | 453 +++++ .../usr/share/htl-simuc/simavr/sim/sim_avr.h | 517 ++++++ .../htl-simuc/simavr/sim/sim_avr_types.h | 57 + .../usr/share/htl-simuc/simavr/sim/sim_cmds.c | 193 +++ .../usr/share/htl-simuc/simavr/sim/sim_cmds.h | 82 + .../usr/share/htl-simuc/simavr/sim/sim_core.c | 1457 +++++++++++++++++ .../usr/share/htl-simuc/simavr/sim/sim_core.h | 142 ++ .../htl-simuc/simavr/sim/sim_cycle_timers.c | 249 +++ .../htl-simuc/simavr/sim/sim_cycle_timers.h | 121 ++ .../usr/share/htl-simuc/simavr/sim/sim_elf.c | 499 ++++++ .../usr/share/htl-simuc/simavr/sim/sim_elf.h | 103 ++ .../usr/share/htl-simuc/simavr/sim/sim_gdb.c | 1026 ++++++++++++ .../usr/share/htl-simuc/simavr/sim/sim_gdb.h | 55 + .../usr/share/htl-simuc/simavr/sim/sim_hex.c | 287 ++++ .../usr/share/htl-simuc/simavr/sim/sim_hex.h | 90 + .../htl-simuc/simavr/sim/sim_interrupts.c | 296 ++++ .../htl-simuc/simavr/sim/sim_interrupts.h | 134 ++ .../usr/share/htl-simuc/simavr/sim/sim_io.c | 298 ++++ .../usr/share/htl-simuc/simavr/sim/sim_io.h | 132 ++ .../usr/share/htl-simuc/simavr/sim/sim_irq.c | 294 ++++ .../usr/share/htl-simuc/simavr/sim/sim_irq.h | 150 ++ .../share/htl-simuc/simavr/sim/sim_network.h | 89 + .../share/htl-simuc/simavr/sim/sim_regbit.h | 199 +++ .../usr/share/htl-simuc/simavr/sim/sim_time.h | 64 + .../share/htl-simuc/simavr/sim/sim_utils.c | 68 + .../share/htl-simuc/simavr/sim/sim_utils.h | 51 + .../share/htl-simuc/simavr/sim/sim_vcd_file.c | 630 +++++++ .../share/htl-simuc/simavr/sim/sim_vcd_file.h | 131 ++ .../usr/share/htl-simuc/simuc/simuc | Bin 0 -> 1820968 bytes .../usr/share/htl-simuc/simuc/src/main.cpp | 190 +++ .../share/htl-simuc/simuc/src/sim/error.cpp | 18 + .../usr/share/htl-simuc/simuc/src/sim/error.h | 11 + .../usr/share/htl-simuc/simuc/src/sim/sim.cpp | 282 ++++ .../usr/share/htl-simuc/simuc/src/sim/sim.h | 43 + .../simuc/src/simavr/parts/fifo_declare.h | 189 +++ .../simuc/src/simavr/parts/uart_pty.c | 371 +++++ .../simuc/src/simavr/parts/uart_pty.h | 90 + .../htl-simuc/simuc/src/simavr/semaphore.h | 32 + .../htl-simuc/simuc/src/simavr/simavr.cpp | 749 +++++++++ .../share/htl-simuc/simuc/src/simavr/simavr.h | 132 ++ examples/simuc/sim/vcd/.gitkeep | 0 examples/simuc/src/main.cpp | 190 +++ examples/simuc/src/sim/error.cpp | 18 + examples/simuc/src/sim/error.h | 11 + examples/simuc/src/sim/sim.cpp | 282 ++++ examples/simuc/src/sim/sim.h | 43 + .../simuc/src/simavr/parts/fifo_declare.h | 189 +++ examples/simuc/src/simavr/parts/uart_pty.c | 371 +++++ examples/simuc/src/simavr/parts/uart_pty.h | 90 + examples/simuc/src/simavr/semaphore.h | 32 + examples/simuc/src/simavr/simavr.cpp | 749 +++++++++ examples/simuc/src/simavr/simavr.h | 132 ++ 96 files changed, 20127 insertions(+), 8 deletions(-) create mode 100644 examples/simuc/.gitignore create mode 100644 examples/simuc/.vscode/launch.json create mode 100644 examples/simuc/.vscode/settings.json create mode 100644 examples/simuc/.vscode/tasks.json create mode 100644 examples/simuc/Makefile create mode 100644 examples/simuc/README.md create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/DEBIAN/control create mode 120000 examples/simuc/dpkg/htl-simuc_version_arch/usr/bin/simuc create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/doc/htl-simuc/copyright create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/doc/htl-simuc/readme create mode 120000 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/readme create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr/avr_mcu_section.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_acomp.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_acomp.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_adc.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_adc.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_bitbang.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_bitbang.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_eeprom.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_eeprom.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_extint.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_extint.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_flash.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_flash.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_ioport.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_ioport.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_lin.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_lin.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_spi.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_spi.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_timer.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_timer.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_twi.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_twi.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_uart.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_uart.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_usb.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_usb.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_watchdog.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_watchdog.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/fifo_declare.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/run_avr.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr_types.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cmds.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cmds.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_core.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_core.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cycle_timers.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cycle_timers.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_elf.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_elf.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_gdb.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_gdb.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_hex.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_hex.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_interrupts.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_interrupts.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_io.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_io.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_irq.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_irq.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_network.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_regbit.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_time.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_utils.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_utils.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_vcd_file.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_vcd_file.h create mode 100755 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/simuc create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/main.cpp create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/error.cpp create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/error.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/sim.cpp create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/sim.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/fifo_declare.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/uart_pty.c create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/uart_pty.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/semaphore.h create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/simavr.cpp create mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/simavr.h create mode 100644 examples/simuc/sim/vcd/.gitkeep create mode 100644 examples/simuc/src/main.cpp create mode 100644 examples/simuc/src/sim/error.cpp create mode 100644 examples/simuc/src/sim/error.h create mode 100644 examples/simuc/src/sim/sim.cpp create mode 100644 examples/simuc/src/sim/sim.h create mode 100644 examples/simuc/src/simavr/parts/fifo_declare.h create mode 100644 examples/simuc/src/simavr/parts/uart_pty.c create mode 100644 examples/simuc/src/simavr/parts/uart_pty.h create mode 100644 examples/simuc/src/simavr/semaphore.h create mode 100644 examples/simuc/src/simavr/simavr.cpp create mode 100644 examples/simuc/src/simavr/simavr.h diff --git a/README.md b/README.md index 606e9f9..450d4db 100644 --- a/README.md +++ b/README.md @@ -2,29 +2,46 @@ This repository is mirrored from [https://github.com/buserror/simavr.git](https://github.com/buserror/simavr.git), commit 7003af0 (Mon Jul 18 10:29:17 2022) -Original `README.md`: see [README-simavr.md](README-simavr.md) +* **simuc**: see [examples/](examples/simuc/README.md) +* Original `README.md`: see [README-simavr.md](README-simavr.md) -## build +------------------------------------------ + +## Build simavr library on Debian- or Ubuntu-systems ### Prepare system ```sh $ sudo apt install gcc make gcc-avr avr-libc $ sudo apt install libelf-dev $ sudo apt install freeglut3 freeglut3-dev +$ sudo apt install libncurses3 ``` -### make simavr libs +### Clone repository + +```sh +user@host:~ $ git clone https://git.htl-mechatronik.at/public/sx/simavr.git +user@host:~ $ cd simavr +user@host:~/simavr $ +``` -Make sure your shell working directory is simavr +### Make libaries and example executables ```sh -$ cd simavr -$ make +user@host:~/simavr $ make ``` Result is available in: -* static lib: `obj-x86_64-linux-gnu/libsimavr.a` -* shared lib: `obj-x86_64-linux-gnu/libsimavr.so` + +* static lib: `obj-.../libsimavr.a` +* shared lib: `obj-.../libsimavr.so` + +The ... is a placeholder for the *architecture*, which is the result of `gcc -dumpmachine` and depends on system architecture: +* i386: `obj-i686-linux-gnu` +* amd64: `obj-x86_64-linux-gnu` +* arm64: `obj-aarch64-linux-gnu` +* ... + Project examples available in folder `examples` diff --git a/examples/Makefile b/examples/Makefile index 65cc893..7fe92ee 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -9,9 +9,11 @@ endif all: for bi in ${boards}; do $(MAKE) -C $$bi; done + $(MAKE) -C simuc clean: for bi in ${boards}; do $(MAKE) -C $$bi clean; done + $(MAKE) -C simuc clean # # The USB example is not made by default, as it downloads stuff diff --git a/examples/simuc/.gitignore b/examples/simuc/.gitignore new file mode 100644 index 0000000..d1ad022 --- /dev/null +++ b/examples/simuc/.gitignore @@ -0,0 +1,4 @@ +dist/** +build/** +dpkg/**/*.deb +**/*.vcd diff --git a/examples/simuc/.vscode/launch.json b/examples/simuc/.vscode/launch.json new file mode 100644 index 0000000..64e527c --- /dev/null +++ b/examples/simuc/.vscode/launch.json @@ -0,0 +1,21 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/dist/simuc", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "preLaunchTask": "build" + } + ] +} diff --git a/examples/simuc/.vscode/settings.json b/examples/simuc/.vscode/settings.json new file mode 100644 index 0000000..189a435 --- /dev/null +++ b/examples/simuc/.vscode/settings.json @@ -0,0 +1,87 @@ +{ + "files.associations": { + "cstdio": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdlib": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "list": "cpp", + "map": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "random": "cpp", + "ratio": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "semaphore": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp", + "variant": "cpp" + }, + "cSpell.words": [ + "aref", + "atmega", + "avcc", + "avrsim", + "ddrb", + "eeprom", + "eesize", + "evws", + "ioend", + "lfcrlf", + "lockbits", + "megaavr", + "millis", + "mmcu", + "picocom", + "PORTB", + "ramend", + "simavr", + "simuc", + "slavename", + "SRAM", + "sreg" + ] +} \ No newline at end of file diff --git a/examples/simuc/.vscode/tasks.json b/examples/simuc/.vscode/tasks.json new file mode 100644 index 0000000..4e8bd30 --- /dev/null +++ b/examples/simuc/.vscode/tasks.json @@ -0,0 +1,26 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "type": "shell", + "command": "make", + "args": [], + "problemMatcher": [ "$gcc" ], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "clean", + "type": "shell", + "command": "make", + "args": [ + "clean" + ] + } + ] +} diff --git a/examples/simuc/Makefile b/examples/simuc/Makefile new file mode 100644 index 0000000..456d1d5 --- /dev/null +++ b/examples/simuc/Makefile @@ -0,0 +1,111 @@ +$(shell mkdir -p dist >/dev/null) +$(shell mkdir -p build >/dev/null) + +PRJ="simuc" +$(PRJ): dist/simuc + +start2: $(PRJ) + LD_LIBRARY_PATH=$(pwd);dist/simuc + +start: $(PRJ) + dist/simuc + +CFLAGS = -Os -Wall +#X_CFLAGS = -O0 -g -Wall +X_CFLAGS = -Os -g -Wall + + +dist/simuc: build/main.o build/sim.o build/simavr.o build/error.o build/uart_pty.o + #g++ -o $@ -g -Wall -gdwarf-2 $^ -Wl,-rpath,$(CURDIR) -L$(CURDIR) -lsimavr -lpthread -lutil + g++ -o $@ -g -Wall -gdwarf-2 $^ ../../simavr/obj-$(shell gcc -dumpmachine)/libsimavr.a -lelf -lpthread -lutil + + +#dist/libsim.so: build/sim.o build/simavr.o build/error.o build/uart_pty.o +# gcc -o $@ $(CFLAGS) -shared $^ + +build/sim.o: src/sim/sim.cpp src/sim/sim.h src/sim/error.h src/simavr/simavr.h + gcc -o $@ $(CFLAGS) -fPIC -c $< + +build/simavr.o: src/simavr/simavr.cpp src/simavr/simavr.h src/sim/error.h + gcc -o $@ $(CFLAGS) -fPIC -c $< + +build/error.o: src/sim/error.cpp src/sim/error.h + gcc -o $@ $(CFLAGS) -fPIC -c $< + +build/uart_pty.o: src/simavr/parts/uart_pty.c src/simavr/parts/uart_pty.h src/simavr/parts/fifo_declare.h + gcc -o $@ $(CFLAGS) -Wno-unused-result -fPIC -c $< + +build/main.o: src/main.cpp src/sim/sim.h src/simavr/simavr.h + g++ -o $@ $(X_CFLAGS) -c $< + + +# ############################################ +# Debian Packet for htl-simuc_version_arch.deb +# ############################################ + +ARCH := $(shell arch) +ifeq ($(ARCH), x86_64) + DEBARCH="amd64" + OBJARCH="" +endif +ifeq ($(ARCH), x86_32) + DEBARCH="i386" +endif +ifeq ($(ARCH), aarch64) + DEBARCH="arm64" +endif + +DEBVERSION := 0.0.1~1 +DEBNAME := dpkg/htl-simuc_version_arch +DEBSRC := dpkg/htl-simuc_version_arch + +DEB := $(DEBNAME:%version=%$(DEBVERSION),%arch=%$(DEBARCH).deb) + +deb: dpkg $(DEBSRC)/DEBIAN/control $(DEBSRC)/usr/share/doc/htl-simuc/readme + @dpkg-deb --root-owner-group --build $(DEBSRC) ${DEB} + +.PHONY: $(DEBSRC)/DEBIAN/control $(DEBSRC)/usr/share/doc/htl-simuc/readme + +$(DEBSRC)/DEBIAN/control: + echo "Package: htl-simuc" > $@ + echo "Version:" ${DEBVERSION} >> $@ + @echo "Section: devel" >> $@ + echo "Architecture:" $(DEBARCH) >> $@ + @echo "Depends: libelf1" >> $@ + @echo "Recommends: gcc-avr, avr-libc, gdb-avr, binutils-avr, avrdude" >> $@ + echo "Installed-Size:" $(shell du -s $(DEBSRC) | cut -f1) >> $@ + @echo "Priority: optional" >> $@ + @echo "Maintainer: Manfred Steiner <sx@htl-kaindorf.at>" >> $@ + @echo "Description: megaavr microcontroller simulation" >> $@ + @chmod 644 $@ + +$(DEBSRC)/usr/share/doc/htl-simuc/readme: + @echo "created: $(shell date)" > $@ + @echo "https://git.htl-mechatronik.at/public/?p=sx/simavr.git;a=home" >> $@ + @echo >> $@ + @echo "$ git clone https://git.htl-mechatronik.at/public/sx/simavr.git" >> $@ + @echo "$ git checkout $(shell git rev-parse HEAD)" >> $@ + @chmod 644 $@ + +dpkg: $(PRJ) + @test -d $(DEBSRC)/usr/share/htl-simuc || mkdir -m 755 $(DEBSRC)/usr/share/htl-simuc + @test -d $(DEBSRC)/usr/share/htl-simuc/simuc || mkdir -m 755 $(DEBSRC)/usr/share/htl-simuc/simuc + rsync -a --delete dist/simuc $(DEBSRC)/usr/share/htl-simuc/simuc + @test -d $(DEBSRC)/usr/share/htl-simuc/simuc/src || mkdir -m 755 $(DEBSRC)/usr/share/htl-simuc/simuc/src + rsync -a --delete src/ $(DEBSRC)/usr/share/htl-simuc/simuc/src/ + @test -d $(DEBSRC)/usr/share/htl-simuc/simavr || mkdir -m 755 $(DEBSRC)/usr/share/htl-simuc/simavr + @test -d $(DEBSRC)/usr/share/htl-simuc/simavr/sim || mkdir -m 755 $(DEBSRC)/usr/share/htl-simuc/simavr/sim + rsync -a --delete ../../simavr/sim/ $(DEBSRC)/usr/share/htl-simuc/simavr/sim/ + @find $(DEBSRC) -type d -exec chmod 755 {} \; + @find $(DEBSRC)/usr/share/htl-simuc/ -type f -exec chmod 644 {} \; + @chmod 755 $(DEBSRC)/usr/share/htl-simuc/simuc/simuc + @touch $(DEBSRC) + +# ##################################################################### + +clean: + -@rm -r dist + -@rm -r build + -@find dpkg -name "*.deb" -delete + -@rm -rf $(DEBSRC)/usr/share/htl-simuc + -@rm -f $(DEBSRC)/DEBIAN/control diff --git a/examples/simuc/README.md b/examples/simuc/README.md new file mode 100644 index 0000000..5dee7f8 --- /dev/null +++ b/examples/simuc/README.md @@ -0,0 +1,64 @@ +# simuc + +**simuc** is used to simulate a megaAvr microcontroller. + +If the cpu is stopped by command or `avr-gdb`, some information is printed on standard output: +* Number of cycles and elapsed time +* Status Flags +* General Purpose registers r0..r31 +* address registers X, Y and Z +* Stack pointer SP and stack content + +Commands available via standard input (keyboard): +* *Enter* print current cycles and elapsed time +* `interrupt`: stop cpu +* `continue`: continue cpu run +* `stack`: print complete stack content on standard output + +Microcontrollers UART interface(s) is/are connected to local devices and can be used with terminal programs (like `picocom`). + +After start of `simuc` the program waits for an keyboard action to start simulation. So you are able to connect with avr-gdb before the simulation is executing some machine code. + +1) start `simuc` with proper options and arguments +2) start new shell and execute `avr-gdb` +3) inside (gdb) connect to simuc with the gdb shell command `target remote :1234` +4) load symbols with gdb command `file ...` +5) optionally set source directory with `directory ...` +6) press enter in the shell of simuc +7) now debug avr program step by step with gdb commands `stepi`, `step`, `nexti`, `next` or continue execution with `continue` + +------------------------------------------------------------- + +## Build simavr + +### Prepare system +```sh +$ sudo apt install gcc make gcc-avr avr-libc +$ sudo apt install libelf-dev +$ sudo apt install freeglut3 freeglut3-dev +$ sudo apt install libncurses3 +``` + +### Clone repository + +```sh +user@host:~ $ git clone https://git.htl-mechatronik.at/public/sx/simavr.git +user@host:~ $ cd simavr/examples/simuc +user@host:~/simavr/examples/simuc $ +``` + +### Make simuc executable + +```sh +user@host:~/simavr/examples/simuc $ make +``` + +Executable `simuc` available in folder `dist` + +### Make debian packet `htl-simuc` + +```sh +user@host:~/simavr/examples/simuc $ make deb +``` + +Debian packet available in folder `dpkg` diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/DEBIAN/control b/examples/simuc/dpkg/htl-simuc_version_arch/DEBIAN/control new file mode 100644 index 0000000..6b155e4 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/DEBIAN/control @@ -0,0 +1,10 @@ +Package: htl-simuc +Version: 0.0.1~1 +Section: devel +Architecture: amd64 +Depends: libelf1 +Recommends: gcc-avr, avr-libc, gdb-avr, binutils-avr, avrdude +Installed-Size: 4328 +Priority: optional +Maintainer: Manfred Steiner <sx@htl-kaindorf.at> +Description: megaavr microcontroller simulation diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/bin/simuc b/examples/simuc/dpkg/htl-simuc_version_arch/usr/bin/simuc new file mode 120000 index 0000000..c184c52 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/bin/simuc @@ -0,0 +1 @@ +../share/htl-simuc/simuc/simuc \ No newline at end of file diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/doc/htl-simuc/copyright b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/doc/htl-simuc/copyright new file mode 100644 index 0000000..5cf1991 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/doc/htl-simuc/copyright @@ -0,0 +1,43 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: htl-simuc + +Files: * +Copyright: 2022 Manfred Steiner <sx@htl-kaindorf.at> +License: GPL-3+ + +License: GPL-3+ + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + . + On Debian systems, the complete text of the GNU General Public + License version 3 can be found in "/usr/share/common-licenses/GPL-3". + +License: LGPL-3+ + This library is free software: you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + . + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + . + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see + <http://www.gnu.org/licenses/>. + . + On Debian systems, the complete text of the GNU Lesser General + Public License version 3 can be found in + "/usr/share/common-licenses/LGPL-3". + diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/doc/htl-simuc/readme b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/doc/htl-simuc/readme new file mode 100644 index 0000000..06453d5 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/doc/htl-simuc/readme @@ -0,0 +1,5 @@ +created: So 27 Nov 2022 16:21:49 CET +https://git.htl-mechatronik.at/public/?p=sx/simavr.git;a=home + +git clone https://git.htl-mechatronik.at/public/sx/simavr.git +git checkout 0a12726a5335284495e557078a73381dc5fc8599 diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/readme b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/readme new file mode 120000 index 0000000..bf9863d --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/readme @@ -0,0 +1 @@ +../doc/htl-simuc/readme \ No newline at end of file diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr/avr_mcu_section.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr/avr_mcu_section.h new file mode 100644 index 0000000..3deae7b --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr/avr_mcu_section.h @@ -0,0 +1,332 @@ +/* + avr_mcu_section.h + + Copyright 2008-2013 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __AVR_MCU_SECTION_H__ +#define __AVR_MCU_SECTION_H__ + +/* + * This header is used to pass "parameters" to the programmer or the simulator, + * it tags the ELF file with a section that contains parameters about the physical + * AVR this was compiled for, including the speed, model, and signature bytes. + * + * A programmer software can read this and verify fuses values for example, and a + * simulator can instantiate the proper "model" of AVR, the speed and so on without + * command line parameters. + * + * Example of use: + * + * #include "avr_mcu_section.h" + * AVR_MCU(F_CPU, "atmega88"); + * + */ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + AVR_MMCU_TAG = 0, + AVR_MMCU_TAG_NAME, + AVR_MMCU_TAG_FREQUENCY, + AVR_MMCU_TAG_VCC, + AVR_MMCU_TAG_AVCC, + AVR_MMCU_TAG_AREF, + AVR_MMCU_TAG_LFUSE, + AVR_MMCU_TAG_HFUSE, + AVR_MMCU_TAG_EFUSE, + AVR_MMCU_TAG_SIGNATURE, + AVR_MMCU_TAG_SIMAVR_COMMAND, + AVR_MMCU_TAG_SIMAVR_CONSOLE, + AVR_MMCU_TAG_VCD_FILENAME, + AVR_MMCU_TAG_VCD_PERIOD, + AVR_MMCU_TAG_VCD_TRACE, + AVR_MMCU_TAG_VCD_PORTPIN, + AVR_MMCU_TAG_VCD_IRQ, + AVR_MMCU_TAG_PORT_EXTERNAL_PULL, +}; + +enum { + SIMAVR_CMD_NONE = 0, + SIMAVR_CMD_VCD_START_TRACE, + SIMAVR_CMD_VCD_STOP_TRACE, + SIMAVR_CMD_UART_LOOPBACK, +}; + +#if __AVR__ +/* + * WARNING. Due to newer GCC being stupid, they introduced a bug that + * prevents us introducing variable length strings in the declaration + * of structs. Worked for a million years, and no longer. + * So the new method declares the string as fixed size, and the parser + * is forced to skip the zeroes in padding. Dumbo. + */ +#define _MMCU_ __attribute__((section(".mmcu"))) __attribute__((used)) +struct avr_mmcu_long_t { + uint8_t tag; + uint8_t len; + uint32_t val; +} __attribute__((__packed__)); + +struct avr_mmcu_string_t { + uint8_t tag; + uint8_t len; + char string[64]; +} __attribute__((__packed__)); + +struct avr_mmcu_addr_t { + uint8_t tag; + uint8_t len; + void * what; +} __attribute__((__packed__)); + +struct avr_mmcu_vcd_trace_t { + uint8_t tag; + uint8_t len; + uint8_t mask; + void * what; + char name[32]; +} __attribute__((__packed__)); + +#define AVR_MCU_STRING(_tag, _str) \ + const struct avr_mmcu_string_t _##_tag _MMCU_ = {\ + .tag = _tag,\ + .len = sizeof(struct avr_mmcu_string_t) - 2,\ + .string = _str,\ + } +/* + * This trick allows concatenation of tokens. We need a macro redirection + * for it to work. + * The goal is to make unique variable names (they don't matter anyway) + */ +#define DO_CONCAT2(_a, _b) _a##_b +#define DO_CONCAT(_a, _b) DO_CONCAT2(_a,_b) + +#define AVR_MCU_LONG(_tag, _val) \ + const struct avr_mmcu_long_t DO_CONCAT(DO_CONCAT(_, _tag), __LINE__) _MMCU_ = {\ + .tag = _tag,\ + .len = sizeof(struct avr_mmcu_long_t) - 2,\ + .val = _val,\ + } + +#define AVR_MCU_BYTE(_tag, _val) \ + const uint8_t _##_tag _MMCU_ = { _tag, 1, _val } + +/*! + * This Macro allows you to specify traces for the VCD file output + * engine. This specifies a default header, and let you fill in the + * relevant bits. + * Example: + * const struct avr_mmcu_vcd_trace_t _mytrace[] _MMCU_ = { + * { AVR_MCU_VCD_SYMBOL("UDR0"), .what = (void*)&UDR0, }, + * { AVR_MCU_VCD_SYMBOL("UDRE0"), .mask = (1 << UDRE0), .what = (void*)&UCSR0A, }, + * }; + * This structure will automatically tell simavr to add a VCD trace + * for the UART register, and the UDRE0 bit, so you can trace exactly + * the timing of the changed using gtkwave. + */ +#define AVR_MCU_VCD_SYMBOL(_name) \ + .tag = AVR_MMCU_TAG_VCD_TRACE, \ + .len = sizeof(struct avr_mmcu_vcd_trace_t) - 2,\ + .name = _name + +/*! + * Specifies the name and wanted period (in usec) for a VCD file + * this is not mandatory for the VCD output to work, if this tag + * is not used, a VCD file will still be created with default values + */ +#define AVR_MCU_VCD_FILE(_name, _period) \ + AVR_MCU_STRING(AVR_MMCU_TAG_VCD_FILENAME, _name);\ + AVR_MCU_LONG(AVR_MMCU_TAG_VCD_PERIOD, _period) + +/*! + * It is possible to send "commands" to simavr from the + * firmware itself. For this to work you need to specify + * an IO register that is to be used for a write-only + * bridge. A favourite is one of the usual "GPIO register" + * that most (all ?) AVR have. + * See definition of SIMAVR_CMD_* to see what commands can + * be used from your firmware. + */ +#define AVR_MCU_SIMAVR_COMMAND(_register) \ + const struct avr_mmcu_addr_t _simavr_command_register _MMCU_ = {\ + .tag = AVR_MMCU_TAG_SIMAVR_COMMAND,\ + .len = sizeof(void *),\ + .what = (void*)_register, \ + } +/*! + * Similar to AVR_MCU_SIMAVR_COMMAND, The CONSOLE allows the AVR code + * to declare a register (typically a GPIO register, but any unused + * register can work...) that will allow printing on the host's console + * without using a UART to do debug. + */ +#define AVR_MCU_SIMAVR_CONSOLE(_register) \ + const struct avr_mmcu_addr_t _simavr_console_register _MMCU_ = {\ + .tag = AVR_MMCU_TAG_SIMAVR_CONSOLE,\ + .len = sizeof(void *),\ + .what = (void*)_register, \ + } +/*! + * Allows the firmware to hint simavr as to wether there are external + * pullups/down on PORT pins. It helps if the firmware uses "open drain" + * pins by toggling the DDR pins to switch between an output state and + * a "default" state. + * The value passed here will be output on the PORT IRQ when the DDR + * pin is set to input again + */ +#define AVR_MCU_EXTERNAL_PORT_PULL(_port, _mask, _val) \ + AVR_MCU_LONG(AVR_MMCU_TAG_PORT_EXTERNAL_PULL, \ + (((unsigned long)((_port)&0xff) << 16) | \ + ((unsigned long)((_mask)&0xff) << 8) | \ + ((_val)&0xff))); +/*! + * Add this port/pin to the VCD file. The syntax uses the name of the + * port as a character, and not a pointer to a register. + * AVR_MCU_VCD_PORT_PIN('B', 5); + */ +#define AVR_MCU_VCD_PORT_PIN(_port, _pin, _name) \ + const struct avr_mmcu_vcd_trace_t DO_CONCAT(DO_CONCAT(_, _tag), __LINE__) _MMCU_ = {\ + .tag = AVR_MMCU_TAG_VCD_PORTPIN, \ + .len = sizeof(struct avr_mmcu_vcd_trace_t) - 2,\ + .mask = _port, \ + .what = (void*)_pin, \ + .name = _name, \ + } + +/*! + * These allows you to add a trace showing how long an IRQ vector is pending, + * and also how long it is running. You can specify the IRQ as a vector name + * straight from the firmware file, and it will be named properly in the trace + */ + +#define AVR_MCU_VCD_IRQ_TRACE(_vect_number, __what, _trace_name) \ + const struct avr_mmcu_vcd_trace_t DO_CONCAT(DO_CONCAT(_, _tag), __LINE__) _MMCU_ = {\ + .tag = AVR_MMCU_TAG_VCD_IRQ, \ + .len = sizeof(struct avr_mmcu_vcd_trace_t) - 2,\ + .mask = _vect_number, \ + .what = (void*)__what, \ + .name = _trace_name, \ + }; +#define AVR_MCU_VCD_IRQ(_irq_name) \ + AVR_MCU_VCD_IRQ_TRACE(_irq_name##_vect_num, 1, #_irq_name) +#define AVR_MCU_VCD_IRQ_PENDING(_irq_name) \ + AVR_MCU_VCD_IRQ_TRACE(_irq_name##_vect_num, 0, #_irq_name "_pend") +#define AVR_MCU_VCD_ALL_IRQ() \ + AVR_MCU_VCD_IRQ_TRACE(0xff, 1, "IRQ") +#define AVR_MCU_VCD_ALL_IRQ_PENDING() \ + AVR_MCU_VCD_IRQ_TRACE(0xff, 0, "IRQ_PENDING") + +/*! + * This tag allows you to specify the voltages used by your board + * It is optional in most cases, but you will need it if you use + * ADC module's IRQs. Not specifying it in this case might lead + * to a divide-by-zero crash. + * The units are Volts*1000 (millivolts) + */ +#define AVR_MCU_VOLTAGES(_vcc, _avcc, _aref) \ + AVR_MCU_LONG(AVR_MMCU_TAG_VCC, (_vcc));\ + AVR_MCU_LONG(AVR_MMCU_TAG_AVCC, (_avcc));\ + AVR_MCU_LONG(AVR_MMCU_TAG_AREF, (_aref)); + +/*! + * This the has to be used if you want to add other tags to the .mmcu section + * the _mmcu symbol is used as an anchor to make sure it stays linked in. + */ +#define AVR_MCU(_speed, _name) \ + AVR_MCU_STRING(AVR_MMCU_TAG_NAME, _name);\ + AVR_MCU_LONG(AVR_MMCU_TAG_FREQUENCY, _speed);\ + const uint8_t _mmcu[2] _MMCU_ = { AVR_MMCU_TAG, 0 } + +/* + * The following MAP macros where copied from + * https://github.com/swansontec/map-macro/blob/master/map.h + * + * The license header for that file is reproduced below: + * + * Copyright (C) 2012 William Swanson + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +#define _EVAL0(...) __VA_ARGS__ +#define _EVAL1(...) _EVAL0 (_EVAL0 (_EVAL0 (__VA_ARGS__))) +#define _EVAL2(...) _EVAL1 (_EVAL1 (_EVAL1 (__VA_ARGS__))) +#define _EVAL3(...) _EVAL2 (_EVAL2 (_EVAL2 (__VA_ARGS__))) +#define _EVAL4(...) _EVAL3 (_EVAL3 (_EVAL3 (__VA_ARGS__))) +#define _EVAL(...) _EVAL4 (_EVAL4 (_EVAL4 (__VA_ARGS__))) + +#define _MAP_END(...) +#define _MAP_OUT + +#define _MAP_GET_END() 0, _MAP_END +#define _MAP_NEXT0(test, next, ...) next _MAP_OUT +#define _MAP_NEXT1(test, next) _MAP_NEXT0 (test, next, 0) +#define _MAP_NEXT(test, next) _MAP_NEXT1 (_MAP_GET_END test, next) + +#define _MAP0(f, x, peek, ...) f(x) _MAP_NEXT (peek, _MAP1) (f, peek, __VA_ARGS__) +#define _MAP1(f, x, peek, ...) f(x) _MAP_NEXT (peek, _MAP0) (f, peek, __VA_ARGS__) +#define _MAP(f, ...) _EVAL (-MAP1 (f, __VA_ARGS__, (), 0)) + +/* End of original MAP macros. */ + +// Define MAP macros with one additional argument +#define _MAP0_1(f, a, x, peek, ...) f(a, x) _MAP_NEXT (peek, _MAP1_1) (f, a, peek, __VA_ARGS__) +#define _MAP1_1(f, a, x, peek, ...) f(a, x) _MAP_NEXT (peek, _MAP0_1) (f, a, peek, __VA_ARGS__) +#define _MAP_1(f, a, ...) _EVAL (_MAP1_1 (f, a, __VA_ARGS__, (), 0)) + +#define _SEND_SIMAVR_CMD_BYTE(reg, b) reg = b; + +// A helper macro for sending multi-byte commands +#define SEND_SIMAVR_CMD(reg, ...) \ + do { \ + _MAP_1(_SEND_SIMAVR_CMD_BYTE, reg, __VA_ARGS__) \ + } while(0) + +#endif /* __AVR__ */ + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_acomp.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_acomp.c new file mode 100644 index 0000000..f3e14e1 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_acomp.c @@ -0,0 +1,241 @@ +/* + avr_acomp.c + + Copyright 2017 Konstantin Begun + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include "avr_acomp.h" +#include "avr_timer.h" + +static uint8_t +avr_acomp_get_state( + struct avr_t * avr, + avr_acomp_t *ac) +{ + if (avr_regbit_get(avr, ac->disabled)) + return 0; + + // get positive voltage + uint16_t positive_v; + + if (avr_regbit_get(avr, ac->acbg)) { // if bandgap + positive_v = ACOMP_BANDGAP; + } else { + positive_v = ac->ain_values[0]; // AIN0 + } + + // get negative voltage + uint16_t negative_v = 0; + + // multiplexer is enabled if acme is set and adc is off + if (avr_regbit_get(avr, ac->acme) && !avr_regbit_get(avr, ac->aden)) { + if (!avr_regbit_get(avr, ac->pradc)) { + uint8_t adc_i = avr_regbit_get_array(avr, ac->mux, ARRAY_SIZE(ac->mux)); + if (adc_i < ac->mux_inputs && adc_i < ARRAY_SIZE(ac->adc_values)) { + negative_v = ac->adc_values[adc_i]; + } + } + + } else { + negative_v = ac->ain_values[1]; // AIN1 + } + + return positive_v > negative_v; +} + +static avr_cycle_count_t +avr_acomp_sync_state( + struct avr_t * avr, + avr_cycle_count_t when, + void * param) +{ + avr_acomp_t * p = (avr_acomp_t *)param; + if (!avr_regbit_get(avr, p->disabled)) { + + uint8_t cur_state = avr_regbit_get(avr, p->aco); + uint8_t new_state = avr_acomp_get_state(avr, p); + + if (new_state != cur_state) { + avr_regbit_setto(avr, p->aco, new_state); // set ACO + + uint8_t acis0 = avr_regbit_get(avr, p->acis[0]); + uint8_t acis1 = avr_regbit_get(avr, p->acis[1]); + + if ((acis0 == 0 && acis1 == 0) || (acis1 == 1 && acis0 == new_state)) { + avr_raise_interrupt(avr, &p->ac); + } + + avr_raise_irq(p->io.irq + ACOMP_IRQ_OUT, new_state); + } + + } + + return 0; +} + +static inline void +avr_schedule_sync_state( + struct avr_t * avr, + void *param) +{ + avr_cycle_timer_register(avr, 1, avr_acomp_sync_state, param); +} + +static void +avr_acomp_write_acsr( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_acomp_t * p = (avr_acomp_t *)param; + + avr_core_watch_write(avr, addr, v); + + if (avr_regbit_get(avr, p->acic) != (p->timer_irq ? 1:0)) { + if (p->timer_irq) { + avr_unconnect_irq(p->io.irq + ACOMP_IRQ_OUT, p->timer_irq); + p->timer_irq = NULL; + } + else { + avr_irq_t *irq = avr_io_getirq(avr, AVR_IOCTL_TIMER_GETIRQ(p->timer_name), TIMER_IRQ_IN_ICP); + if (irq) { + avr_connect_irq(p->io.irq + ACOMP_IRQ_OUT, irq); + p->timer_irq = irq; + } + } + } + + avr_schedule_sync_state(avr, param); +} + +static void +avr_acomp_dependencies_changed( + struct avr_irq_t * irq, + uint32_t value, + void * param) +{ + avr_acomp_t * p = (avr_acomp_t *)param; + avr_schedule_sync_state(p->io.avr, param); +} + +static void +avr_acomp_irq_notify( + struct avr_irq_t * irq, + uint32_t value, + void * param) +{ + avr_acomp_t * p = (avr_acomp_t *)param; + + switch (irq->irq) { + case ACOMP_IRQ_AIN0 ... ACOMP_IRQ_AIN1: { + p->ain_values[irq->irq - ACOMP_IRQ_AIN0] = value; + avr_schedule_sync_state(p->io.avr, param); + } break; + case ACOMP_IRQ_ADC0 ... ACOMP_IRQ_ADC15: { + p->adc_values[irq->irq - ACOMP_IRQ_ADC0] = value; + avr_schedule_sync_state(p->io.avr, param); + } break; + } +} + +static void +avr_acomp_register_dependencies( + avr_acomp_t *p, + avr_regbit_t rb) +{ + if (rb.reg) { + avr_irq_register_notify( + avr_iomem_getirq(p->io.avr, rb.reg, NULL, rb.bit), + avr_acomp_dependencies_changed, + p); + } +} + +static void +avr_acomp_reset(avr_io_t * port) +{ + avr_acomp_t * p = (avr_acomp_t *)port; + + for (int i = 0; i < ACOMP_IRQ_COUNT; i++) + avr_irq_register_notify(p->io.irq + i, avr_acomp_irq_notify, p); + + // register notification for changes of registers comparator does not own + // avr_register_io_write is tempting instead, but it requires that the handler + // updates the actual memory too. Given this is for the registers this module + // does not own, it is tricky to know whether it should write to the actual memory. + // E.g., if there is already a native handler for it then it will do the writing + // (possibly even omitting some bits etc). IInterefering would probably be wrong. + // On the other hand if there isn't a handler already, then this hadnler would have to, + // as otherwise nobody will. + // This write notification mechanism should probably need reviewing and fixing + // For now using IRQ mechanism, as it is not intrusive + + avr_acomp_register_dependencies(p, p->pradc); + avr_acomp_register_dependencies(p, p->aden); + avr_acomp_register_dependencies(p, p->acme); + + // mux + for (int i = 0; i < ARRAY_SIZE(p->mux); ++i) { + avr_acomp_register_dependencies(p, p->mux[i]); + } +} + +static const char * irq_names[ACOMP_IRQ_COUNT] = { + [ACOMP_IRQ_AIN0] = "16<ain0", + [ACOMP_IRQ_AIN1] = "16<ain1", + [ACOMP_IRQ_ADC0] = "16<adc0", + [ACOMP_IRQ_ADC1] = "16<adc1", + [ACOMP_IRQ_ADC2] = "16<adc2", + [ACOMP_IRQ_ADC3] = "16<adc3", + [ACOMP_IRQ_ADC4] = "16<adc4", + [ACOMP_IRQ_ADC5] = "16<adc5", + [ACOMP_IRQ_ADC6] = "16<adc6", + [ACOMP_IRQ_ADC7] = "16<adc7", + [ACOMP_IRQ_ADC8] = "16<adc0", + [ACOMP_IRQ_ADC9] = "16<adc9", + [ACOMP_IRQ_ADC10] = "16<adc10", + [ACOMP_IRQ_ADC11] = "16<adc11", + [ACOMP_IRQ_ADC12] = "16<adc12", + [ACOMP_IRQ_ADC13] = "16<adc13", + [ACOMP_IRQ_ADC14] = "16<adc14", + [ACOMP_IRQ_ADC15] = "16<adc15", + [ACOMP_IRQ_OUT] = ">out" +}; + +static avr_io_t _io = { + .kind = "ac", + .reset = avr_acomp_reset, + .irq_names = irq_names, +}; + +void +avr_acomp_init( + avr_t * avr, + avr_acomp_t * p) +{ + p->io = _io; + + avr_register_io(avr, &p->io); + avr_register_vector(avr, &p->ac); + // allocate this module's IRQ + avr_io_setirqs(&p->io, AVR_IOCTL_ACOMP_GETIRQ, ACOMP_IRQ_COUNT, NULL); + + avr_register_io_write(avr, p->r_acsr, avr_acomp_write_acsr, p); +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_acomp.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_acomp.h new file mode 100644 index 0000000..caa3c4e --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_acomp.h @@ -0,0 +1,89 @@ +/* + avr_acomp.h + + Copyright 2017 Konstantin Begun + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __AVR_COMP_H___ +#define __AVR_COMP_H___ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sim_avr.h" + +/* + * simavr Analog Comparator allows external code to feed real voltages to the + * simulator, and the simulator uses it's 'real' reference voltage + * to set comparator output accordingly and trigger in interrupt, if set up this way + * + */ + +enum { + // input IRQ values. Values are /always/ volts * 1000 (millivolts) + ACOMP_IRQ_AIN0 = 0, ACOMP_IRQ_AIN1, + ACOMP_IRQ_ADC0, ACOMP_IRQ_ADC1, ACOMP_IRQ_ADC2, ACOMP_IRQ_ADC3, + ACOMP_IRQ_ADC4, ACOMP_IRQ_ADC5, ACOMP_IRQ_ADC6, ACOMP_IRQ_ADC7, + ACOMP_IRQ_ADC8, ACOMP_IRQ_ADC9, ACOMP_IRQ_ADC10, ACOMP_IRQ_ADC11, + ACOMP_IRQ_ADC12, ACOMP_IRQ_ADC13, ACOMP_IRQ_ADC14, ACOMP_IRQ_ADC15, + ACOMP_IRQ_OUT, // output has changed + ACOMP_IRQ_COUNT +}; + +// Get the internal IRQ corresponding to the INT +#define AVR_IOCTL_ACOMP_GETIRQ AVR_IOCTL_DEF('a','c','m','p') + +enum { + ACOMP_BANDGAP = 1100 +}; + +typedef struct avr_acomp_t { + avr_io_t io; + + uint8_t mux_inputs; // number of inputs (not mux bits!) in multiplexer. Other bits in mux below would be expected to be zero + avr_regbit_t mux[4]; + avr_regbit_t pradc; // ADC power reduction, this impacts on ability to use adc multiplexer + avr_regbit_t aden; // ADC Enabled, this impacts on ability to use adc multiplexer + avr_regbit_t acme; // AC multiplexed input enabled + + avr_io_addr_t r_acsr; // control & status register + avr_regbit_t acis[2]; // + avr_regbit_t acic; // input capture enable + avr_regbit_t aco; // output + avr_regbit_t acbg; // bandgap select + avr_regbit_t disabled; + + char timer_name; // connected timer for incput capture triggering + + // use ACI and ACIE bits + avr_int_vector_t ac; + + // runtime data + uint16_t adc_values[16]; // current values on the ADCs inputs + uint16_t ain_values[2]; // current values on AIN inputs + avr_irq_t* timer_irq; +} avr_acomp_t; + +void avr_acomp_init(avr_t * avr, avr_acomp_t * port); + +#ifdef __cplusplus +}; +#endif + +#endif // __AVR_COMP_H___ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_adc.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_adc.c new file mode 100644 index 0000000..6adf1f2 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_adc.c @@ -0,0 +1,427 @@ +/* + avr_adc.c + + Copyright 2008, 2010 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "sim_time.h" +#include "avr_adc.h" + +static avr_cycle_count_t +avr_adc_int_raise( + struct avr_t * avr, avr_cycle_count_t when, void * param) +{ + avr_adc_t * p = (avr_adc_t *)param; + if (avr_regbit_get(avr, p->aden)) { + // if the interrupts are not used, still raised the UDRE and TXC flag + avr_raise_interrupt(avr, &p->adc); + avr_regbit_clear(avr, p->adsc); + if( p->adts_mode == avr_adts_free_running ) + avr_raise_irq(p->io.irq + ADC_IRQ_IN_TRIGGER, 1); + if (!p->read_status) { + /* Update I/O registers. */ + + avr->data[p->r_adcl] = p->result & 0xff; + avr->data[p->r_adch] = p->result >> 8; + } + } + return 0; +} + +static avr_cycle_count_t +avr_adc_convert(struct avr_t * avr, avr_cycle_count_t when, void * param) +{ + avr_adc_t *p = (avr_adc_t *)param; + + p->first = 0; // Converter initialised + + /* Ask the calling program for inputs. */ + + avr_adc_mux_t mux = p->muxmode[p->current_muxi]; + union { + avr_adc_mux_t mux; + uint32_t v; + } e = { .mux = mux }; + avr_raise_irq(p->io.irq + ADC_IRQ_OUT_TRIGGER, e.v); + + // optional shift left/right + uint8_t shift = p->current_extras.adjust ? 6 : 0; // shift LEFT + + int32_t reg = 0, clipped = 0; + switch (mux.kind) { + case ADC_MUX_SINGLE: + reg = p->adc_values[mux.src]; + break; + case ADC_MUX_DIFF: + if (mux.gain == 0) + mux.gain = 1; + reg = ((uint32_t)p->adc_values[mux.src] * mux.gain) - + ((uint32_t)p->adc_values[mux.diff] * mux.gain); + break; + case ADC_MUX_TEMP: + reg = p->temp; // assumed to be already calibrated somehow + break; + case ADC_MUX_REF: + reg = mux.src; // reference voltage + break; + case ADC_MUX_VCC4: + if ( !avr->vcc) { + AVR_LOG(avr, LOG_WARNING, "ADC: missing VCC analog voltage\n"); + } else + reg = avr->vcc / 4; + break; + } + + int32_t vref = 3300; + uint16_t ref = p->ref_values[p->current_refi]; + + switch (ref) { + case ADC_VREF_VCC: + if (!avr->vcc) + AVR_LOG(avr, LOG_WARNING, "ADC: missing VCC analog voltage\n"); + else + vref = avr->vcc; + break; + case ADC_VREF_AREF: + if (!avr->aref) + AVR_LOG(avr, LOG_WARNING, "ADC: missing AREF analog voltage\n"); + else + vref = avr->aref; + break; + case ADC_VREF_AVCC: + if (!avr->avcc) + AVR_LOG(avr, LOG_WARNING, "ADC: missing AVCC analog voltage\n"); + else + vref = avr->avcc; + break; + default: + vref = ref; + } +// printf("ADCL %d:%3d:%3d read %4d vref %d:%d=%d\n", +// mux.kind, mux.diff, mux.src, +// reg, refi, ref, vref); + + if (mux.kind == ADC_MUX_DIFF) { + if (p->current_extras.negate) + reg = -reg; + if (p->current_extras.bipolar) { + reg = (reg * (int32_t)0x1ff) / vref; // scale to 9 bits + if (reg > (int32_t)0x1ff) { + clipped = 0x1ff; + } else if (reg < -(int32_t)0x1ff) { + clipped = 0x200; + } + } else { + reg = (reg * (int32_t)0x3ff) / vref; // scale to 10 bit + if (reg < 0 || reg > (int32_t)0x3ff) + clipped = 0x1ff; + } + } else { + reg = (reg * (int32_t)0x3ff) / vref; // scale to 10 bits + if (reg < 0 || reg > (int32_t)0x3ff) + clipped = 0x3ff; + } +// printf("ADC to 9/10 bits 0x%x %d\n", reg, reg); + if (clipped) { + AVR_LOG(avr, LOG_WARNING, + "ADC: channel %d clipped %u/%u VREF %d\n", + p->current_muxi, reg, clipped, vref); + reg = clipped; + } + reg &= 0x3ff; + reg <<= shift; +// printf("ADC to 9/10 bits %x shifted %d\n", reg, shift); + p->result = reg; + + /* Schedule the interrupt in 11 ADC cycles. */ + + avr_cycle_timer_register(avr, p->current_prescale * 11, + avr_adc_int_raise, p); + return 0; +} + +/* + * From Datasheet: + * "When ADCL is read, the ADC Data Register is not updated until ADCH is read. + * Consequently, if the result is left adjusted and no more than 8-bit + * precision is required, it is sufficient to read ADCH. + * Otherwise, ADCL must be read first, then ADCH." + */ + +static uint8_t +avr_adc_read_l( + struct avr_t * avr, avr_io_addr_t addr, void * param) +{ + avr_adc_t * p = (avr_adc_t *)param; + + p->read_status = 1; // Set the update interlock. + return avr_core_watch_read(avr, addr); +} + +static uint8_t +avr_adc_read_h( + struct avr_t * avr, avr_io_addr_t addr, void * param) +{ + avr_adc_t * p = (avr_adc_t *)param; + + p->read_status = 0; // Clear the update interlock. + return avr_core_watch_read(avr, addr); +} + +static void +avr_adc_configure_trigger( + struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param) +{ + avr_adc_t * p = (avr_adc_t *)param; + + uint8_t adate = avr_regbit_get(avr, p->adate); + uint8_t old_adts = p->adts_mode; + + static char * auto_trigger_names[] = { + "none", + "free_running", + "analog_comparator_0", + "analog_comparator_1", + "analog_comparator_2", + "analog_comparator_3", + "external_interrupt_0", + "timer_0_compare_match_a", + "timer_0_compare_match_b", + "timer_0_overflow", + "timer_1_compare_match_b", + "timer_1_overflow", + "timer_1_capture_event", + "pin_change_interrupt", + "psc_module_0_sync_signal", + "psc_module_1_sync_signal", + "psc_module_2_sync_signal", + }; + + if( adate ) { + uint8_t adts = avr_regbit_get_array(avr, p->adts, ARRAY_SIZE(p->adts)); + p->adts_mode = p->adts_op[adts]; + + switch(p->adts_mode) { + case avr_adts_free_running: { + // do nothing at free running mode + } break; + // TODO: implement the other auto trigger modes + default: { + AVR_LOG(avr, LOG_WARNING, + "ADC: unimplemented auto trigger mode: %s\n", + auto_trigger_names[p->adts_mode]); + p->adts_mode = avr_adts_none; + } break; + } + } else { + // TODO: remove previously configured auto triggers + p->adts_mode = avr_adts_none; + } + + if( old_adts != p->adts_mode ) + AVR_LOG(avr, LOG_TRACE, "ADC: auto trigger configured: %s\n", + auto_trigger_names[p->adts_mode]); +} + +static void +avr_adc_write_adcsra( + struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param) +{ + + avr_adc_t * p = (avr_adc_t *)param; + uint8_t adsc = avr_regbit_get(avr, p->adsc); + uint8_t aden = avr_regbit_get(avr, p->aden); + uint8_t new_aden; + + if (p->adc.raised.reg == addr) { + uint8_t mask; + + mask = 1 << p->adc.raised.bit; + if (mask & v) { + // Clear interrupt flag on bit set. + + avr_clear_interrupt(avr, &p->adc); + v &= ~mask; + } else { + v |= (mask & avr->data[p->adsc.reg]); + } + } + + avr->data[p->adsc.reg] = v; + new_aden = avr_regbit_get(avr, p->aden); + + // can't write zero to adsc + if (adsc && !avr_regbit_get(avr, p->adsc)) { + avr_regbit_set(avr, p->adsc); + v = avr->data[p->adsc.reg]; + } + if (!aden && new_aden) { + // first conversion + p->first = 1; + AVR_LOG(avr, LOG_TRACE, "ADC: Start AREF %d AVCC %d\n", avr->aref, avr->avcc); + } + if (aden && !avr_regbit_get(avr, p->aden)) { + // stop ADC + + avr_cycle_timer_cancel(avr, avr_adc_convert, p); + avr_cycle_timer_cancel(avr, avr_adc_int_raise, p); + avr_regbit_clear(avr, p->adsc); + v = avr->data[p->adsc.reg]; // Peter Ross pross@xvid.org + } + if (new_aden && !adsc && avr_regbit_get(avr, p->adsc)) { + // start one! + + /* Copy mux, prescaler and ADSRB settings, as they may change + * before conversion. + */ + + p->current_muxi = avr_regbit_get_array(avr, p->mux, + ARRAY_SIZE(p->mux)); + p->current_refi = avr_regbit_get_array(avr, p->ref, + ARRAY_SIZE(p->ref)); + + // clock prescaler are just a bit shift.. and 0 means 1 + + uint32_t div = avr_regbit_get_array(avr, p->adps, + ARRAY_SIZE(p->adps)); + if (!div) div++; + + if (p->first) + AVR_LOG(avr, LOG_TRACE, "ADC: starting at %uKHz\n", + (avr->frequency >> div) / 13 / 100); + div = (1 << div); + div *= (p->first ? 14 : 2); // first conversion is longer + p->current_prescale = div; + avr_cycle_timer_register(avr, div, avr_adc_convert, p); + p->current_extras.bipolar = + p->bin.reg && avr_regbit_get(avr, p->bin); + p->current_extras.negate = + p->ipr.reg && avr_regbit_get(avr, p->ipr); + p->current_extras.adjust = avr_regbit_get(avr, p->adlar); + } + avr_core_watch_write(avr, addr, v); + avr_adc_configure_trigger(avr, addr, v, param); +} + +static void +avr_adc_write_adcsrb( + struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param) +{ + avr_core_watch_write(avr, addr, v); + avr_adc_configure_trigger(avr, addr, v, param); +} + +static void +avr_adc_irq_notify( + struct avr_irq_t * irq, uint32_t value, void * param) +{ + avr_adc_t * p = (avr_adc_t *)param; + avr_t * avr = p->io.avr; + + switch (irq->irq) { + case ADC_IRQ_ADC0 ... ADC_IRQ_ADC15: { + p->adc_values[irq->irq] = value; + } break; + case ADC_IRQ_TEMP: { + p->temp = value; + } break; + case ADC_IRQ_IN_TRIGGER: { + if (avr_regbit_get(avr, p->adate)) { + // start a conversion only if it's not running + // otherwise ignore the trigger + if(!avr_regbit_get(avr, p->adsc) ) { + uint8_t addr = p->adsc.reg; + if (addr) { + uint8_t val = avr->data[addr] | (1 << p->adsc.bit); + if (p->adc.raised.reg == addr) { + uint8_t mask; + + mask = 1 << p->adc.raised.bit; + val &= ~mask; + } + + // write ADSC to ADCSRA + + avr_adc_write_adcsra(avr, addr, val, param); + } + } + } + } + break; + } +} + +static void avr_adc_reset(avr_io_t * port) +{ + avr_adc_t * p = (avr_adc_t *)port; + + // stop ADC + avr_cycle_timer_cancel(p->io.avr, avr_adc_int_raise, p); + avr_regbit_clear(p->io.avr, p->adsc); + + for (int i = 0; i < ADC_IRQ_COUNT; i++) + avr_irq_register_notify(p->io.irq + i, avr_adc_irq_notify, p); +} + +static const char * irq_names[ADC_IRQ_COUNT] = { + [ADC_IRQ_ADC0] = "16<adc0", + [ADC_IRQ_ADC1] = "16<adc1", + [ADC_IRQ_ADC2] = "16<adc2", + [ADC_IRQ_ADC3] = "16<adc3", + [ADC_IRQ_ADC4] = "16<adc4", + [ADC_IRQ_ADC5] = "16<adc5", + [ADC_IRQ_ADC6] = "16<adc6", + [ADC_IRQ_ADC7] = "16<adc7", + [ADC_IRQ_ADC8] = "16<adc0", + [ADC_IRQ_ADC9] = "16<adc9", + [ADC_IRQ_ADC10] = "16<adc10", + [ADC_IRQ_ADC11] = "16<adc11", + [ADC_IRQ_ADC12] = "16<adc12", + [ADC_IRQ_ADC13] = "16<adc13", + [ADC_IRQ_ADC14] = "16<adc14", + [ADC_IRQ_ADC15] = "16<adc15", + [ADC_IRQ_TEMP] = "16<temp", + [ADC_IRQ_IN_TRIGGER] = "<trigger_in", + [ADC_IRQ_OUT_TRIGGER] = ">trigger_out", +}; + +static avr_io_t _io = { + .kind = "adc", + .reset = avr_adc_reset, + .irq_names = irq_names, +}; + +void avr_adc_init(avr_t * avr, avr_adc_t * p) +{ + p->io = _io; + + avr_register_io(avr, &p->io); + avr_register_vector(avr, &p->adc); + // allocate this module's IRQ + avr_io_setirqs(&p->io, AVR_IOCTL_ADC_GETIRQ, ADC_IRQ_COUNT, NULL); + + avr_register_io_write(avr, p->r_adcsra, avr_adc_write_adcsra, p); + // some ADCs don't have ADCSRB (atmega8/16/32) + if (p->r_adcsrb) + avr_register_io_write(avr, p->r_adcsrb, avr_adc_write_adcsrb, p); + avr_register_io_read(avr, p->r_adcl, avr_adc_read_l, p); + avr_register_io_read(avr, p->r_adch, avr_adc_read_h, p); +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_adc.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_adc.h new file mode 100644 index 0000000..c9dbfa0 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_adc.h @@ -0,0 +1,193 @@ +/* + avr_adc.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __AVR_ADC_H___ +#define __AVR_ADC_H___ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sim_avr.h" + +/* + * simavr ADC allows external code to feed real voltages to the + * simulator, and the simulator uses it's 'real' reference voltage + * to do the right thing and return the 'proper' 10 bits ADC value + * to the AVR firmware. + * + * To send values to the ADC, register your code to wait for the + * ADC_IRQ_OUT_TRIGGER irq, and at that point send any of the + * ADC_IRQ_ADC* with Millivolts as value. + * + * External trigger is not done yet. + */ + +enum { + // input IRQ values. Values are /always/ volts * 1000 (millivolts) + ADC_IRQ_ADC0 = 0, ADC_IRQ_ADC1, ADC_IRQ_ADC2, ADC_IRQ_ADC3, + ADC_IRQ_ADC4, ADC_IRQ_ADC5, ADC_IRQ_ADC6, ADC_IRQ_ADC7, + ADC_IRQ_ADC8, ADC_IRQ_ADC9, ADC_IRQ_ADC10, ADC_IRQ_ADC11, + ADC_IRQ_ADC12, ADC_IRQ_ADC13, ADC_IRQ_ADC14, ADC_IRQ_ADC15, + ADC_IRQ_TEMP, // see the datasheet + ADC_IRQ_IN_TRIGGER, + ADC_IRQ_OUT_TRIGGER, // sends a avr_adc_mux_t + ADC_IRQ_COUNT +}; + +// Get the internal IRQ corresponding to the INT +#define AVR_IOCTL_ADC_GETIRQ AVR_IOCTL_DEF('a','d','c','0') + +/* + * Definition of a ADC mux mode. + */ +enum { + ADC_MUX_NONE = 0, // Nothing. return 0 + ADC_MUX_NOISE, // Nothing. return something random + ADC_MUX_SINGLE, // Normal ADC pin reading + ADC_MUX_DIFF, // differential channels (src-diff) + ADC_MUX_TEMP, // internal temp sensor + ADC_MUX_REF, // reference voltage (in src * 100) + ADC_MUX_VCC4, // VCC/4 +}; +typedef struct avr_adc_mux_t { + unsigned long kind : 3, gain : 8, diff : 8, src : 13; +} avr_adc_mux_t; + +enum { + ADC_VREF_AREF = 0, // default mode + ADC_VREF_VCC, + ADC_VREF_AVCC, + ADC_VREF_V110 = 1100, + ADC_VREF_V256 = 2560, +}; + +// ADC trigger sources +typedef enum { + avr_adts_none = 0, + avr_adts_free_running, + avr_adts_analog_comparator_0, + avr_adts_analog_comparator_1, + avr_adts_analog_comparator_2, + avr_adts_analog_comparator_3, + avr_adts_external_interrupt_0, + avr_adts_timer_0_compare_match_a, + avr_adts_timer_0_compare_match_b, + avr_adts_timer_0_overflow, + avr_adts_timer_1_compare_match_b, + avr_adts_timer_1_overflow, + avr_adts_timer_1_capture_event, + avr_adts_pin_change_interrupt, + avr_adts_psc_module_0_sync_signal, + avr_adts_psc_module_1_sync_signal, + avr_adts_psc_module_2_sync_signal, +} avr_adts_type; + +typedef struct avr_adc_t { + avr_io_t io; + + uint8_t r_admux; + // if the last bit exists in the mux, we are an extended ADC + avr_regbit_t mux[6]; + avr_regbit_t ref[3]; // reference voltages bits + uint16_t ref_values[8]; // ADC_VREF_* + + avr_regbit_t adlar; // left/right adjustment bit + + uint8_t r_adcsra; // ADC Control and Status Register A + avr_regbit_t aden; // ADC Enabled + avr_regbit_t adsc; // ADC Start Conversion + avr_regbit_t adate; // ADC Auto Trigger Enable + + avr_regbit_t adps[3]; // Prescaler bits. Note that it's a frequency bit shift + + uint8_t r_adcl, r_adch; // Data Registers + + uint8_t r_adcsrb; // ADC Control and Status Register B + avr_regbit_t adts[4]; // Timing Source + avr_adts_type adts_op[16]; // ADTS type + uint8_t adts_mode; // the extracted ADTS mode + avr_regbit_t bin; // Bipolar Input Mode (tinyx5 have it) + avr_regbit_t ipr; // Input Polarity Reversal (tinyx5 have it) + + // use ADIF and ADIE bits + avr_int_vector_t adc; + + avr_adc_mux_t muxmode[64]; // maximum 6 bits of mux modes + + /* + * runtime bits + */ + + uint16_t adc_values[16]; // current values on the ADCs + uint16_t temp; // temp sensor reading + uint8_t first; + uint8_t read_status; // marked one when adcl is read + + /* Conversion parameters saved at start (ADSC is set). */ + + uint8_t current_muxi; + uint8_t current_refi; + uint8_t current_prescale; + struct { + unsigned int bipolar : 1; // BIN bit. + unsigned int negate : 1; // IPR bit. + unsigned int adjust : 1; // ADLAR bit. + } current_extras; + + /* Buffered conversion result. */ + + uint16_t result; +} avr_adc_t; + +void avr_adc_init(avr_t * avr, avr_adc_t * port); + + +/* + * Helper macros for the Cores definition of muxes + */ +#define AVR_ADC_SINGLE(_chan) { \ + .kind = ADC_MUX_SINGLE, \ + .src = (_chan), \ + } +#define AVR_ADC_DIFF(_a,_b,_g) { \ + .kind = ADC_MUX_DIFF, \ + .src = (_a), \ + .diff = (_b), \ + .gain = (_g), \ + } +#define AVR_ADC_REF(_t) { \ + .kind = ADC_MUX_REF, \ + .src = (_t), \ + } +#define AVR_ADC_TEMP() { \ + .kind = ADC_MUX_TEMP, \ + } + +#define AVR_ADC_VCC4() { \ + .kind = ADC_MUX_VCC4, \ + } + +#ifdef __cplusplus +}; +#endif + +#endif /* __AVR_ADC_H___ */ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_bitbang.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_bitbang.c new file mode 100644 index 0000000..e34aab2 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_bitbang.c @@ -0,0 +1,248 @@ +/* + avr_bitbang.c + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + 2011 Stephan Veigl <veig@gmx.net> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __AVR_BITBANG_H__ +#define __AVR_BITBANG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <stdlib.h> + +#include "avr_bitbang.h" + +#include "sim_regbit.h" +#include "sim_core.h" +#include "avr_ioport.h" + +///@todo refactor SPI to bitbang + +#define BITBANG_MASK 0xFFFFFFFFUL + +/** + * read (sample) data from input pin + * + * @param p internal bitbang structure + */ +static void avr_bitbang_read_bit(avr_bitbang_t *p) +{ + avr_ioport_state_t iostate; + uint8_t bit = 0; + + if ( !p->enabled ) + return; + + // read from HW pin + if ( p->p_in.port ) { + avr_ioctl(p->avr, AVR_IOCTL_IOPORT_GETSTATE( p->p_in.port ), &iostate); + bit = ( iostate.pin >> p->p_in.pin ) & 1; + + if ( p->data_order ) { + // data order: shift right + p->data = (p->data >> 1) | ( bit << (p->buffer_size-1)); + } else { + // data order: shift left + p->data = (p->data << 1) | bit; + } + + } + + // module callback + if ( p->callback_bit_read ) { + p->callback_bit_read(bit, p->callback_param); + } + + // data sanitary + p->data = p->data & ~(BITBANG_MASK << p->buffer_size); +} + +/** + * write data to output pin + * + * @param p bitbang structure + */ +static void avr_bitbang_write_bit(avr_bitbang_t *p) +{ + uint8_t bit = 0; + + if ( !p->enabled ) + return; + + if ( p->data_order ) { + // data order: shift right + bit = p->data & 1; + } else { + // data order: shift left + bit = (p->data >> (p->buffer_size-1)) & 1; + } + + // output to HW pin + if ( p->p_out.port ) { + avr_raise_irq(avr_io_getirq(p->avr, AVR_IOCTL_IOPORT_GETIRQ( p->p_out.port ), p->p_out.pin), bit); + } + + // module callback + if ( p->callback_bit_write ) { + p->callback_bit_write(bit, p->callback_param); + } +} + + +/** + * process clock edges (both: positive and negative edges) + * + * @param p bitbang structure + * + */ +static void avr_bitbang_clk_edge(avr_bitbang_t *p) +{ + uint8_t phase = (p->clk_count & 1) ^ p->clk_phase; + uint8_t clk = (p->clk_count & 1) ^ p->clk_pol; + + if ( !p->enabled ) + return; + + // increase clock + p->clk_count++; + clk ^= 1; + phase ^= 1; + + // generate clock output on HW pin + if ( p->clk_generate && p->p_clk.port ) { + avr_raise_irq(avr_io_getirq(p->avr, AVR_IOCTL_IOPORT_GETIRQ( p->p_clk.port ), p->p_clk.pin), clk); + } + + if ( phase ) { + // read data in + avr_bitbang_read_bit(p); + + } else { + // write data out + avr_bitbang_write_bit(p); + } + + if ( p->clk_count >= (p->buffer_size*2) ) { + // transfer finished + if ( p->callback_transfer_finished ) { + p->data = p->callback_transfer_finished(p->data, p->callback_param); + } + p->clk_count = 0; + } +} + +static avr_cycle_count_t avr_bitbang_clk_timer(struct avr_t * avr, avr_cycle_count_t when, void * param) +{ + avr_bitbang_t * p = (avr_bitbang_t *)param; + + avr_bitbang_clk_edge(p); + + if ( p->enabled ) + return when + p->clk_cycles/2; + else + return 0; +} + +static void avr_bitbang_clk_hook(struct avr_irq_t * irq, uint32_t value, void * param) +{ + avr_bitbang_t * p = (avr_bitbang_t *)param; + uint8_t clk = (p->clk_count & 1) ^ p->clk_pol; + + // no clock change + if ( clk == value ) + return; + + avr_bitbang_clk_edge(p); +} + +/** + * reset bitbang sub-module + * + * @param avr avr attached to + * @param p bitbang structure + */ +void avr_bitbang_reset(avr_t *avr, avr_bitbang_t * p) +{ + p->avr = avr; + p->enabled = 0; + p->clk_count = 0; + p->data = 0; + + if ( p->buffer_size < 1 || p->buffer_size > 32 ) { + AVR_LOG(avr, LOG_ERROR, + "Error: bitbang buffer size should be between 1 and 32. set value: %d\n", p->buffer_size); + abort(); + } + +} + +/** + * start bitbang transfer + * + * buffers should be written / cleared in advanced + * timers and interrupts are connected + * + * @param p bitbang structure + */ +void avr_bitbang_start(avr_bitbang_t * p) +{ + p->enabled = 1; + p->clk_count = 0; + + if ( p->clk_phase == 0 ) { + // write first bit + avr_bitbang_write_bit(p); + } + + if ( p->clk_generate ) { + // master mode, generate clock -> set timer + avr_cycle_timer_register(p->avr, (p->clk_cycles/2), avr_bitbang_clk_timer, p); + } else { + // slave mode -> attach clock function to clock pin + ///@todo test + avr_irq_register_notify( avr_io_getirq(p->avr, AVR_IOCTL_IOPORT_GETIRQ( p->p_clk.port ), p->p_clk.pin), avr_bitbang_clk_hook, p); + } + +} + + +/** + * stop bitbang transfer + * + * timers and interrupts are disabled + * + * @param p bitbang structure + */ +void avr_bitbang_stop(avr_bitbang_t * p) +{ + + p->enabled = 0; + avr_cycle_timer_cancel(p->avr, avr_bitbang_clk_timer, p); + avr_irq_unregister_notify( avr_io_getirq(p->avr, AVR_IOCTL_IOPORT_GETIRQ( p->p_clk.port ), p->p_clk.pin), avr_bitbang_clk_hook, p); +} + +#ifdef __cplusplus +}; +#endif + +#endif /*__AVR_BITBANG_H__*/ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_bitbang.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_bitbang.h new file mode 100644 index 0000000..3d8832f --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_bitbang.h @@ -0,0 +1,117 @@ +/* + avr_bitbang.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + 2011 Stephan Veigl <veig@gmx.net> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + @defgroup avr_bitbang Generic BitBang Module + @{ + + Generic BitBang Module of simavr AVR simulator. + + @par Features / Implementation Status + - easy buffer access with push() / pop() functions + - one input and one output pin (can be the same HW pin for I2C) + + @todo + - one input and one output pin (can be the same HW pin for I2C) + - one clock pin which can be configured as input or output + when the clock is output, the clock signal is generated with a + configured frequency (master / slave mode) + - 2x 32-bit buffers (input / output) (allows start, stop bits for UART, etc.) + - on each read / write a callback is executed to notify the master module + +*/ + + +#ifndef AVR_BITBANG_H_ +#define AVR_BITBANG_H_ + +#include "sim_avr.h" +#include "avr_ioport.h" + + + + +/// SPI Module initialization and state structure +typedef struct avr_bitbang_t { + avr_t * avr; ///< avr we are attached to + + uint8_t enabled; ///< bit-bang enabled flag + uint8_t clk_generate; ///< generate clock and write to clock pin (if available) -> master / slave mode + uint8_t clk_pol; ///< clock polarity, base (inactive) value of clock + uint8_t clk_phase; ///< clock phase / data sampling edge + /// - 0: data are sampled at first clock edge + /// - 1: data are sampled at second clock edge + uint32_t clk_cycles; ///< cycles per clock period - must be multiple of 2! (used if clk_generate is enabled) + uint8_t data_order; ///< data order / shift + /// - 0: shift left + /// - 1: shift right + + uint8_t buffer_size; ///< size of buffer in bits (1...32) + + void *callback_param; /// anonymous parameter for callback functions + void (*callback_bit_read)(uint8_t bit, void *param); ///< callback function to notify about bit read + void (*callback_bit_write)(uint8_t bit, void *param); ///< callback function to notify about bit write + uint32_t (*callback_transfer_finished)(uint32_t data, void *param); ///< callback function to notify about a complete transfer + /// (read received data and write new output data) + + avr_iopin_t p_clk; ///< clock pin (optional) + avr_iopin_t p_in; ///< data in pin + avr_iopin_t p_out; ///< data out pin + +// private data + uint32_t data; ///< data buffer + /// - latest received bit the is lowest / most right one, bit number: 0 + /// - next bit to be written is the highest one, bit number: (buffer_size-1) + int8_t clk_count; ///< internal clock edge count +} avr_bitbang_t; + +/** + * reset bitbang sub-module + * + * @param avr avr attached to + * @param p bitbang structure + */ +void avr_bitbang_reset(avr_t *avr, avr_bitbang_t * p); + +/** + * start bitbang transfer + * + * buffers should be written / cleared in advanced + * timers and interrupts are connected + * + * @param p bitbang structure + */ +void avr_bitbang_start(avr_bitbang_t * p); + + +/** + * stop bitbang transfer + * + * timers and interrupts are disabled + * + * @param p bitbang structure + */ +void avr_bitbang_stop(avr_bitbang_t * p); + + +#endif /* AVR_BITBANG_H_ */ +/// @} end of avr_bitbang group diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_eeprom.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_eeprom.c new file mode 100644 index 0000000..c348f3f --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_eeprom.c @@ -0,0 +1,148 @@ +/* + avr_eeprom.c + + IO module that simulates the AVR EEProm + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "avr_eeprom.h" + +static avr_cycle_count_t avr_eempe_clear(struct avr_t * avr, avr_cycle_count_t when, void * param) +{ + avr_eeprom_t * p = (avr_eeprom_t *)param; + avr_regbit_clear(p->io.avr, p->eempe); + return 0; +} + +static avr_cycle_count_t avr_eei_raise(struct avr_t * avr, avr_cycle_count_t when, void * param) +{ + avr_eeprom_t * p = (avr_eeprom_t *)param; + avr_raise_interrupt(p->io.avr, &p->ready); + return 0; +} + +static void avr_eeprom_write(avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param) +{ + avr_eeprom_t * p = (avr_eeprom_t *)param; + uint8_t eempe = avr_regbit_get(avr, p->eempe); + + avr_core_watch_write(avr, addr, v); + + if (!eempe && avr_regbit_get(avr, p->eempe)) { + avr_cycle_timer_register(avr, 4, avr_eempe_clear, p); + } + + uint16_t ee_addr; + if (p->r_eearh) + ee_addr = avr->data[p->r_eearl] | (avr->data[p->r_eearh] << 8); + else + ee_addr = avr->data[p->r_eearl]; + if (((eempe && avr_regbit_get(avr, p->eepe)) || avr_regbit_get(avr, p->eere)) && + ee_addr >= p->size) { + AVR_LOG(avr, LOG_ERROR, "EEPROM: *** %s address out of bounds: %04x > %04x," + " wrapping to %04x (PC=%04x)\n", + eempe ? "Write" : "Read", + ee_addr, p->size-1, ee_addr & (p->size-1), + avr->pc); + ee_addr = ee_addr & (p->size-1); + } + if (eempe && avr_regbit_get(avr, p->eepe)) { // write operation + // printf("eeprom write %04x <- %02x\n", addr, avr->data[p->r_eedr]); + p->eeprom[ee_addr] = avr->data[p->r_eedr]; + // Automatically clears that bit (?) + avr_regbit_clear(avr, p->eempe); + + avr_cycle_timer_register_usec(avr, 3400, avr_eei_raise, p); // 3.4ms here + } + if (avr_regbit_get(avr, p->eere)) { // read operation + avr->data[p->r_eedr] = p->eeprom[ee_addr]; + // printf("eeprom read %04x : %02x\n", addr, p->eeprom[addr]); + } + + // autocleared + avr_regbit_clear(avr, p->eepe); + avr_regbit_clear(avr, p->eere); +} + +static int avr_eeprom_ioctl(struct avr_io_t * port, uint32_t ctl, void * io_param) +{ + avr_eeprom_t * p = (avr_eeprom_t *)port; + int res = -1; + + switch(ctl) { + case AVR_IOCTL_EEPROM_SET: { + avr_eeprom_desc_t * desc = (avr_eeprom_desc_t*)io_param; + if (!desc || !desc->size || !desc->ee || (desc->offset + desc->size) > p->size) { + AVR_LOG(port->avr, LOG_WARNING, "EEPROM: %s: AVR_IOCTL_EEPROM_SET Invalid argument\n", + __FUNCTION__); + return -2; + } + memcpy(p->eeprom + desc->offset, desc->ee, desc->size); + AVR_LOG(port->avr, LOG_TRACE, "EEPROM: %s: AVR_IOCTL_EEPROM_SET Loaded %d at offset %d\n", + __FUNCTION__, desc->size, desc->offset); + } break; + case AVR_IOCTL_EEPROM_GET: { + avr_eeprom_desc_t * desc = (avr_eeprom_desc_t*)io_param; + if (!desc || (desc->offset + desc->size) > p->size) { + AVR_LOG(port->avr, LOG_WARNING, "EEPROM: %s: AVR_IOCTL_EEPROM_GET Invalid argument\n", + __FUNCTION__); + return -2; + } + if (desc->ee) + memcpy(desc->ee, p->eeprom + desc->offset, desc->size); + else // allow to get access to the read data, for gdb support + desc->ee = p->eeprom + desc->offset; + } break; + } + + return res; +} + +static void avr_eeprom_dealloc(struct avr_io_t * port) +{ + avr_eeprom_t * p = (avr_eeprom_t *)port; + if (p->eeprom) + free(p->eeprom); + p->eeprom = NULL; +} + +static avr_io_t _io = { + .kind = "eeprom", + .ioctl = avr_eeprom_ioctl, + .dealloc = avr_eeprom_dealloc, +}; + +void avr_eeprom_init(avr_t * avr, avr_eeprom_t * p) +{ + p->io = _io; +// printf("%s init (%d bytes) EEL/H:%02x/%02x EED=%02x EEC=%02x\n", +// __FUNCTION__, p->size, p->r_eearl, p->r_eearh, p->r_eedr, p->r_eecr); + + p->eeprom = malloc(p->size); + memset(p->eeprom, 0xff, p->size); + + avr_register_io(avr, &p->io); + avr_register_vector(avr, &p->ready); + + avr_register_io_write(avr, p->r_eecr, avr_eeprom_write, p); +} + diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_eeprom.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_eeprom.h new file mode 100644 index 0000000..9ad1c5a --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_eeprom.h @@ -0,0 +1,131 @@ +/* + avr_eeprom.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __AVR_EEPROM_H__ +#define __AVR_EEPROM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sim_avr.h" + +typedef struct avr_eeprom_t { + avr_io_t io; + + uint8_t * eeprom; // actual bytes + uint16_t size; // size for this MCU + + uint8_t r_eearh; + uint8_t r_eearl; + uint8_t r_eedr; + + // eepm -- eeprom write mode + uint8_t r_eecr; // shortcut, assumes these bits fit in that register + avr_regbit_t eepm[4]; + avr_regbit_t eempe; // eeprom master program enable + avr_regbit_t eepe; // eeprom program enable + avr_regbit_t eere; // eeprom read enable + + avr_int_vector_t ready; // EERIE vector +} avr_eeprom_t; + +void avr_eeprom_init(avr_t * avr, avr_eeprom_t * port); + +typedef struct avr_eeprom_desc_t { + uint8_t * ee; + uint16_t offset; + uint32_t size; +} avr_eeprom_desc_t; + +#define AVR_IOCTL_EEPROM_GET AVR_IOCTL_DEF('e','e','g','p') +#define AVR_IOCTL_EEPROM_SET AVR_IOCTL_DEF('e','e','s','p') + + +/* + * the eeprom block seems to be very similar across AVRs, + * so here is a macro to declare a "typical" one in a core. + */ + +#define AVR_EEPROM_DECLARE(_vector) \ + .eeprom = {\ + .size = E2END+1,\ + .r_eearh = EEARH,\ + .r_eearl = EEARL,\ + .r_eedr = EEDR,\ + .r_eecr = EECR,\ + .eepm = { AVR_IO_REGBIT(EECR, EEPM0), AVR_IO_REGBIT(EECR, EEPM1) },\ + .eempe = AVR_IO_REGBIT(EECR, EEMPE),\ + .eepe = AVR_IO_REGBIT(EECR, EEPE),\ + .eere = AVR_IO_REGBIT(EECR, EERE),\ + .ready = {\ + .enable = AVR_IO_REGBIT(EECR, EERIE),\ + .vector = _vector,\ + },\ + } + +/* + * no EEPM registers in atmega128 + */ +#define AVR_EEPROM_DECLARE_NOEEPM(_vector) \ + .eeprom = {\ + .size = E2END+1,\ + .r_eearh = EEARH,\ + .r_eearl = EEARL,\ + .r_eedr = EEDR,\ + .r_eecr = EECR,\ + .eepm = { }, \ + .eempe = AVR_IO_REGBIT(EECR, EEMWE),\ + .eepe = AVR_IO_REGBIT(EECR, EEWE),\ + .eere = AVR_IO_REGBIT(EECR, EERE),\ + .ready = {\ + .enable = AVR_IO_REGBIT(EECR, EERIE),\ + .vector = _vector,\ + },\ + } + + +/* + * macro definition without a high address bit register, + * which is not implemented in some tiny AVRs. + */ + +#define AVR_EEPROM_DECLARE_8BIT(_vector) \ + .eeprom = {\ + .size = E2END+1,\ + .r_eearl = EEAR,\ + .r_eedr = EEDR,\ + .r_eecr = EECR,\ + .eepm = { AVR_IO_REGBIT(EECR, EEPM0), AVR_IO_REGBIT(EECR, EEPM1) },\ + .eempe = AVR_IO_REGBIT(EECR, EEMPE),\ + .eepe = AVR_IO_REGBIT(EECR, EEPE),\ + .eere = AVR_IO_REGBIT(EECR, EERE),\ + .ready = {\ + .enable = AVR_IO_REGBIT(EECR, EERIE),\ + .vector = _vector,\ + },\ + } + +#ifdef __cplusplus +}; +#endif + +#endif /* __AVR_EEPROM_H__ */ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_extint.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_extint.c new file mode 100644 index 0000000..6f85660 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_extint.c @@ -0,0 +1,228 @@ +/* + avr_extint.c + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "avr_extint.h" +#include "avr_ioport.h" + +typedef struct avr_extint_poll_context_t { + uint32_t eint_no; // index of particular interrupt source we are monitoring + avr_extint_t *extint; +} avr_extint_poll_context_t; + +static avr_cycle_count_t avr_extint_poll_level_trig( + struct avr_t * avr, + avr_cycle_count_t when, + void * param) +{ + avr_extint_poll_context_t *poll = (avr_extint_poll_context_t *)param; + avr_extint_t * p = poll->extint; + + /* Check for change of interrupt mode. */ + + if (avr_regbit_get_array(avr, p->eint[poll->eint_no].isc, 2)) + goto terminate_poll; + + uint8_t port = p->eint[poll->eint_no].port_ioctl & 0xFF; + avr_ioport_state_t iostate; + if (avr_ioctl(avr, AVR_IOCTL_IOPORT_GETSTATE( port ), &iostate) < 0) + goto terminate_poll; + uint8_t bit = ( iostate.pin >> p->eint[poll->eint_no].port_pin ) & 1; + if (bit) + goto terminate_poll; // Only poll while pin level remains low + + if (avr->sreg[S_I]) { + uint8_t raised = avr_regbit_get(avr, p->eint[poll->eint_no].vector.raised) || p->eint[poll->eint_no].vector.pending; + if (!raised) + avr_raise_interrupt(avr, &p->eint[poll->eint_no].vector); + } + + return when+1; + +terminate_poll: + free(poll); + return 0; +} + +static avr_extint_t * avr_extint_get(avr_t * avr) +{ + if (!avr) + return NULL; + avr_io_t * periferal = avr->io_port; + while (periferal) { + if (!strcmp(periferal->kind, "extint")) { + return (avr_extint_t *)periferal; + } + periferal = periferal->next; + } + return NULL; +} + +static inline uint8_t avr_extint_exists(avr_extint_t *extint, int8_t extint_no) +{ + return (extint_no < EXTINT_COUNT) && (extint->eint[extint_no].port_ioctl); +} + +/** + * @brief avr_extint_is_strict_lvl_trig + * @param avr + * @param extint_no: an ext interrupt number, e.g. 0 or 1 (corresponds to INT0 or INT1) + * @return -1 if irrelevant extint_no given, strict + * level triggering flag otherwise. + */ +int avr_extint_is_strict_lvl_trig(avr_t * avr, uint8_t extint_no) +{ + avr_extint_t *p = avr_extint_get(avr); + if (!p || !avr_extint_exists(p, extint_no)) + return -1; + if (!p->eint[extint_no].isc[1].reg) + return -1; // this is edge-only triggered interrupt + return p->eint[extint_no].strict_lvl_trig; +} + +/** + * @brief avr_extint_set_strict_lvl_trig + * @param avr + * @param extint_no: an ext interrupt number, e.g. 0 or 1 (corresponds to INT0 or INT1) + * @param strict: new value for level triggering flag + */ +void avr_extint_set_strict_lvl_trig(avr_t * avr, uint8_t extint_no, uint8_t strict) +{ + avr_extint_t *p = avr_extint_get(avr); + if (!p || !avr_extint_exists(p, extint_no)) + return; + if (!p->eint[extint_no].isc[1].reg) + return; // this is edge-only triggered interrupt + p->eint[extint_no].strict_lvl_trig = strict; +} + +static void avr_extint_irq_notify(struct avr_irq_t * irq, uint32_t value, void * param) +{ + avr_extint_t * p = (avr_extint_t *)param; + avr_t * avr = p->io.avr; + + int up = !irq->value && value; + int down = irq->value && !value; + + // ?? uint8_t isc_bits = p->eint[irq->irq + 1].isc->reg ? 2 : 1; + uint8_t isc_bits = p->eint[irq->irq].isc[1].reg ? 2 : 1; + uint8_t mode = avr_regbit_get_array(avr, p->eint[irq->irq].isc, isc_bits); + + // Asynchronous interrupts, eg int2 in m16, m32 etc. support only down/up + if (isc_bits == 1) + mode +=2; + + switch (mode) { + case 0: // Level triggered (low level) interrupt + { + /** + Datasheet excerpt: + >When the external interrupt is enabled and is configured as level triggered (only INT0/INT1), + >the interrupt will trigger as long as the pin is held low. + Thus we have to query the pin value continiously while it's held low and try to trigger the interrupt. + This can be expensive, so avr_extint_set_strict_lvl_trig function provisioned to allow the user + to turn this feature off. In this case bahaviour will be similar to the falling edge interrupt. + */ + if (!value) { + if (avr->sreg[S_I]) { + uint8_t raised = avr_regbit_get(avr, p->eint[irq->irq].vector.raised) || p->eint[irq->irq].vector.pending; + if (!raised) + avr_raise_interrupt(avr, &p->eint[irq->irq].vector); + } + if (p->eint[irq->irq].strict_lvl_trig) { + avr_extint_poll_context_t *poll = malloc(sizeof(avr_extint_poll_context_t)); + if (poll) { + poll->eint_no = irq->irq; + poll->extint = p; + avr_cycle_timer_register(avr, 1, avr_extint_poll_level_trig, poll); + } + } + } + } + break; + case 1: // Toggle-triggered interrupt + if (up || down) + avr_raise_interrupt(avr, &p->eint[irq->irq].vector); + break; + case 2: // Falling edge triggered + if (down) + avr_raise_interrupt(avr, &p->eint[irq->irq].vector); + break; + case 3: // Rising edge trigggerd + if (up) + avr_raise_interrupt(avr, &p->eint[irq->irq].vector); + break; + } +} + +static void avr_extint_reset(avr_io_t * port) +{ + avr_extint_t * p = (avr_extint_t *)port; + + for (int i = 0; i < EXTINT_COUNT; i++) { + if (p->eint[i].port_ioctl) { + avr_irq_register_notify(p->io.irq + i, avr_extint_irq_notify, p); + + if (p->eint[i].isc[1].reg) // level triggering available + p->eint[i].strict_lvl_trig = 1; // turn on repetitive level triggering by default + avr_irq_t * irq = avr_io_getirq(p->io.avr, + p->eint[i].port_ioctl, p->eint[i].port_pin); + + avr_connect_irq(irq, p->io.irq + i); + } + } +} + +static const char * irq_names[EXTINT_COUNT] = { + [EXTINT_IRQ_OUT_INT0] = "<int0", + [EXTINT_IRQ_OUT_INT1] = "<int1", + [EXTINT_IRQ_OUT_INT2] = "<int2", + [EXTINT_IRQ_OUT_INT3] = "<int3", + [EXTINT_IRQ_OUT_INT4] = "<int4", + [EXTINT_IRQ_OUT_INT5] = "<int5", + [EXTINT_IRQ_OUT_INT6] = "<int6", + [EXTINT_IRQ_OUT_INT7] = "<int7", +}; + +static avr_io_t _io = { + .kind = "extint", + .reset = avr_extint_reset, + .irq_names = irq_names, +}; + +void avr_extint_init(avr_t * avr, avr_extint_t * p) +{ + p->io = _io; + + avr_register_io(avr, &p->io); + for (int i = 0; i < EXTINT_COUNT; i++) { + if (!p->eint[i].port_ioctl) + break; + avr_register_vector(avr, &p->eint[i].vector); + } + // allocate this module's IRQ + + avr_io_setirqs(&p->io, AVR_IOCTL_EXTINT_GETIRQ(), EXTINT_COUNT, NULL); +} + diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_extint.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_extint.h new file mode 100644 index 0000000..62aa154 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_extint.h @@ -0,0 +1,129 @@ +/* + avr_extint.h + + External Interrupt Handling (for INT0-3) + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + Copyright 2014 Doug Szumski <d.s.szumski@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __AVR_EXTINT_H__ +#define __AVR_EXTINT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sim_avr.h" + + +enum { + EXTINT_IRQ_OUT_INT0 = 0, + EXTINT_IRQ_OUT_INT1, EXTINT_IRQ_OUT_INT2, EXTINT_IRQ_OUT_INT3, + EXTINT_IRQ_OUT_INT4, EXTINT_IRQ_OUT_INT5, EXTINT_IRQ_OUT_INT6, + EXTINT_IRQ_OUT_INT7, + EXTINT_COUNT +}; + +// Get the internal IRQ corresponding to the INT +#define AVR_IOCTL_EXTINT_GETIRQ() AVR_IOCTL_DEF('i','n','t',' ') + +/* + * This module is just a "relay" for the pin change IRQ in the IO port + * module. We hook up to their IRQ and raise out interrupt vectors as needed + * + * "isc" is handled, apart from the "level" mode that doesn't make sense here (?) + */ +typedef struct avr_extint_t { + avr_io_t io; + + struct { + avr_regbit_t isc[2]; // interrupt sense control bits + avr_int_vector_t vector; // interrupt vector + + uint32_t port_ioctl; // ioctl to use to get port + uint8_t port_pin; // pin number in said port + uint8_t strict_lvl_trig;// enforces a repetitive interrupt triggering while the pin is held low + } eint[EXTINT_COUNT]; + +} avr_extint_t; + +void avr_extint_init(avr_t * avr, avr_extint_t * p); +int avr_extint_is_strict_lvl_trig(avr_t * avr, uint8_t extint_no); +void avr_extint_set_strict_lvl_trig(avr_t * avr, uint8_t extint_no, uint8_t strict); + + +// Declares a typical INT into a avr_extint_t in a core. +// this is a shortcut since INT declarations are pretty standard. +// The Tinies as well as the atmega1280 are slightly different. +// See sim_tinyx5.h and sim_mega1280.h +#define AVR_EXTINT_DECLARE(_index, _portname, _portpin) \ + .eint[_index] = { \ + .port_ioctl = AVR_IOCTL_IOPORT_GETIRQ(_portname), \ + .port_pin = _portpin, \ + .isc = { AVR_IO_REGBIT(EICRA, ISC##_index##0), AVR_IO_REGBIT(EICRA, ISC##_index##1) },\ + .vector = { \ + .enable = AVR_IO_REGBIT(EIMSK, INT##_index), \ + .raised = AVR_IO_REGBIT(EIFR, INTF##_index), \ + .vector = INT##_index##_vect, \ + },\ + } + +// Asynchronous External Interrupt, for example INT2 on the m16 and m32 +// Uses only 1 interrupt sense control bit +#define AVR_ASYNC_EXTINT_DECLARE(_index, _portname, _portpin) \ + .eint[_index] = { \ + .port_ioctl = AVR_IOCTL_IOPORT_GETIRQ(_portname), \ + .port_pin = _portpin, \ + .isc = { AVR_IO_REGBIT(MCUCSR, ISC##_index) },\ + .vector = { \ + .enable = AVR_IO_REGBIT(GICR, INT##_index), \ + .raised = AVR_IO_REGBIT(GIFR, INTF##_index), \ + .vector = INT##_index##_vect, \ + },\ + } + +#define AVR_EXTINT_MEGA_DECLARE(_index, _portname, _portpin, _EICR) \ + .eint[_index] = { \ + .port_ioctl = AVR_IOCTL_IOPORT_GETIRQ(_portname), \ + .port_pin = _portpin, \ + .isc = { AVR_IO_REGBIT(EICR##_EICR, ISC##_index##0), AVR_IO_REGBIT(EICR##_EICR, ISC##_index##1) },\ + .vector = { \ + .enable = AVR_IO_REGBIT(EIMSK, INT##_index), \ + .raised = AVR_IO_REGBIT(EIFR, INTF##_index), \ + .vector = INT##_index##_vect, \ + },\ + } + +#define AVR_EXTINT_TINY_DECLARE(_index, _portname, _portpin, _IFR) \ + .eint[_index] = { \ + .port_ioctl = AVR_IOCTL_IOPORT_GETIRQ(_portname), \ + .port_pin = _portpin, \ + .isc = { AVR_IO_REGBIT(MCUCR, ISC##_index##0), AVR_IO_REGBIT(MCUCR, ISC##_index##1) }, \ + .vector = { \ + .enable = AVR_IO_REGBIT(GIMSK, INT##_index), \ + .raised = AVR_IO_REGBIT(_IFR, INTF##_index), \ + .vector = INT##_index##_vect, \ + }, \ + } + +#ifdef __cplusplus +}; +#endif + +#endif /*__AVR_EXTINT_H__*/ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_flash.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_flash.c new file mode 100644 index 0000000..cc1fd96 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_flash.c @@ -0,0 +1,145 @@ +/* + avr_flash.c + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "avr_flash.h" + +static avr_cycle_count_t avr_progen_clear(struct avr_t * avr, avr_cycle_count_t when, void * param) +{ + avr_flash_t * p = (avr_flash_t *)param; + avr_regbit_clear(p->io.avr, p->selfprgen); + AVR_LOG(avr, LOG_WARNING, "FLASH: avr_progen_clear - SPM not received, clearing PRGEN bit\n"); + return 0; +} + + +static void avr_flash_write(avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param) +{ + avr_flash_t * p = (avr_flash_t *)param; + + avr_core_watch_write(avr, addr, v); + +// printf("** avr_flash_write %02x\n", v); + + if (avr_regbit_get(avr, p->selfprgen)) + avr_cycle_timer_register(avr, 4, avr_progen_clear, p); // 4 cycles is very little! +} + +static void avr_flash_clear_temppage(avr_flash_t *p) +{ + for (int i = 0; i < p->spm_pagesize / 2; i++) { + p->tmppage[i] = 0xff; + p->tmppage_used[i] = 0; + } +} + +static int avr_flash_ioctl(struct avr_io_t * port, uint32_t ctl, void * io_param) +{ + if (ctl != AVR_IOCTL_FLASH_SPM) + return -1; + + avr_flash_t * p = (avr_flash_t *)port; + avr_t * avr = p->io.avr; + + avr_flashaddr_t z = avr->data[R_ZL] | (avr->data[R_ZH] << 8); + if (avr->rampz) + z |= avr->data[avr->rampz] << 16; + uint16_t r01 = avr->data[0] | (avr->data[1] << 8); + +// printf("AVR_IOCTL_FLASH_SPM %02x Z:%04x R01:%04x\n", avr->data[p->r_spm], z,r01); + if (avr_regbit_get(avr, p->selfprgen)) { + avr_cycle_timer_cancel(avr, avr_progen_clear, p); + + if (avr_regbit_get(avr, p->pgers)) { + z &= ~1; + AVR_LOG(avr, LOG_TRACE, "FLASH: Erasing page %04x (%d)\n", (z / p->spm_pagesize), p->spm_pagesize); + for (int i = 0; i < p->spm_pagesize; i++) + avr->flash[z++] = 0xff; + } else if (avr_regbit_get(avr, p->pgwrt)) { + z &= ~(p->spm_pagesize - 1); + AVR_LOG(avr, LOG_TRACE, "FLASH: Writing page %04x (%d)\n", (z / p->spm_pagesize), p->spm_pagesize); + for (int i = 0; i < p->spm_pagesize / 2; i++) { + avr->flash[z++] = p->tmppage[i]; + avr->flash[z++] = p->tmppage[i] >> 8; + } + avr_flash_clear_temppage(p); + } else if (avr_regbit_get(avr, p->blbset)) { + AVR_LOG(avr, LOG_TRACE, "FLASH: Setting lock bits (ignored)\n"); + } else if (p->flags & AVR_SELFPROG_HAVE_RWW && avr_regbit_get(avr, p->rwwsre)) { + avr_flash_clear_temppage(p); + } else { + AVR_LOG(avr, LOG_TRACE, "FLASH: Writing temppage %08x (%04x)\n", z, r01); + z >>= 1; + if (!p->tmppage_used[z % (p->spm_pagesize / 2)]) { + p->tmppage[z % (p->spm_pagesize / 2)] = r01; + p->tmppage_used[z % (p->spm_pagesize / 2)] = 1; + } + } + } + avr_regbit_clear(avr, p->selfprgen); + return 0; +} + +static void +avr_flash_reset(avr_io_t * port) +{ + avr_flash_t * p = (avr_flash_t *) port; + + avr_flash_clear_temppage(p); +} + +static void +avr_flash_dealloc(struct avr_io_t * port) +{ + avr_flash_t * p = (avr_flash_t *) port; + + if (p->tmppage) + free(p->tmppage); + + if (p->tmppage_used) + free(p->tmppage_used); +} + +static avr_io_t _io = { + .kind = "flash", + .ioctl = avr_flash_ioctl, + .reset = avr_flash_reset, + .dealloc = avr_flash_dealloc, +}; + +void avr_flash_init(avr_t * avr, avr_flash_t * p) +{ + p->io = _io; +// printf("%s init SPM %04x\n", __FUNCTION__, p->r_spm); + + if (!p->tmppage) + p->tmppage = malloc(p->spm_pagesize); + + if (!p->tmppage_used) + p->tmppage_used = malloc(p->spm_pagesize / 2); + + avr_register_io(avr, &p->io); + avr_register_vector(avr, &p->flash); + + avr_register_io_write(avr, p->r_spm, avr_flash_write, p); +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_flash.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_flash.h new file mode 100644 index 0000000..07747fc --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_flash.h @@ -0,0 +1,92 @@ +/* + avr_flash.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef __AVR_FLASH_H___ +#define __AVR_FLASH_H___ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sim_avr.h" + +/* + * Handles self-programming subsystem if the core + * supports it. + */ +typedef struct avr_flash_t { + avr_io_t io; + + uint16_t flags; + uint16_t *tmppage; + uint8_t *tmppage_used; + uint16_t spm_pagesize; + uint8_t r_spm; + avr_regbit_t selfprgen; + avr_regbit_t pgers; // page erase + avr_regbit_t pgwrt; // page write + avr_regbit_t blbset; // lock bit set + avr_regbit_t rwwsre; // read while write section read enable + avr_regbit_t rwwsb; // read while write section busy + + avr_int_vector_t flash; // Interrupt vector +} avr_flash_t; + +/* Set if the flash supports a Read While Write section */ +#define AVR_SELFPROG_HAVE_RWW (1 << 0) + +void avr_flash_init(avr_t * avr, avr_flash_t * p); + + +#define AVR_IOCTL_FLASH_SPM AVR_IOCTL_DEF('f','s','p','m') + +#define AVR_SELFPROG_DECLARE_INTERNAL(_spmr, _spen, _vector) \ + .r_spm = _spmr,\ + .spm_pagesize = SPM_PAGESIZE,\ + .selfprgen = AVR_IO_REGBIT(_spmr, _spen),\ + .pgers = AVR_IO_REGBIT(_spmr, PGERS),\ + .pgwrt = AVR_IO_REGBIT(_spmr, PGWRT),\ + .blbset = AVR_IO_REGBIT(_spmr, BLBSET),\ + .flash = {\ + .enable = AVR_IO_REGBIT(_spmr, SPMIE),\ + .vector = _vector,\ + }\ + +#define AVR_SELFPROG_DECLARE_NORWW(_spmr, _spen, _vector) \ + .selfprog = {\ + .flags = 0,\ + AVR_SELFPROG_DECLARE_INTERNAL(_spmr, _spen, _vector),\ + } + +#define AVR_SELFPROG_DECLARE(_spmr, _spen, _vector) \ + .selfprog = {\ + .flags = AVR_SELFPROG_HAVE_RWW,\ + AVR_SELFPROG_DECLARE_INTERNAL(_spmr, _spen, _vector),\ + .rwwsre = AVR_IO_REGBIT(_spmr, RWWSRE),\ + .rwwsb = AVR_IO_REGBIT(_spmr, RWWSB),\ + } + +#ifdef __cplusplus +}; +#endif + +#endif /* __AVR_FLASH_H___ */ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_ioport.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_ioport.c new file mode 100644 index 0000000..91cf106 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_ioport.c @@ -0,0 +1,340 @@ +/* + avr_ioport.c + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include "avr_ioport.h" + +#define D(_w) + +static void +avr_ioport_flag_write( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_ioport_t * p = (avr_ioport_t *)param; + + // Clear interrupt if 1 is written to flag. + + if (avr_regbit_from_value(avr, p->pcint.raised, v)) + avr_clear_interrupt(avr, &p->pcint); +} + +static uint8_t +avr_ioport_read( + struct avr_t * avr, + avr_io_addr_t addr, + void * param) +{ + avr_ioport_t * p = (avr_ioport_t *)param; + uint8_t ddr = avr->data[p->r_ddr]; + uint8_t v = (avr->data[p->r_pin] & ~ddr) | (avr->data[p->r_port] & ddr); + avr->data[addr] = v; + avr_raise_irq(p->io.irq + IOPORT_IRQ_REG_PIN, v); + D(if (avr->data[addr] != v) printf("** PIN%c(%02x) = %02x\r\n", p->name, addr, v);) + + // made to trigger potential watchpoints + v = avr_core_watch_read(avr, addr); + return v; +} + +static void +avr_ioport_update_irqs( + avr_ioport_t * p) +{ + avr_t * avr = p->io.avr; + uint8_t ddr = avr->data[p->r_ddr]; + // Set the PORT value if the pin is marked as output + // otherwise, if there is an 'external' pullup, set it + // otherwise, if the PORT pin was 1 to indicate an + // internal pullup, set that. + for (int i = 0; i < 8; i++) { + if (ddr & (1 << i)) + avr_raise_irq(p->io.irq + i, (avr->data[p->r_port] >> i) & 1); + else if (p->external.pull_mask & (1 << i)) + avr_raise_irq(p->io.irq + i, (p->external.pull_value >> i) & 1); + else if ((avr->data[p->r_port] >> i) & 1) + avr_raise_irq(p->io.irq + i, 1); + } + uint8_t pin = (avr->data[p->r_pin] & ~ddr) | (avr->data[p->r_port] & ddr); + pin = (pin & ~p->external.pull_mask) | p->external.pull_value; + avr_raise_irq(p->io.irq + IOPORT_IRQ_PIN_ALL, pin); + + // if IRQs are registered on the PORT register (for example, VCD dumps) send + // those as well + avr_io_addr_t port_io = AVR_DATA_TO_IO(p->r_port); + if (avr->io[port_io].irq) { + avr_raise_irq(avr->io[port_io].irq + AVR_IOMEM_IRQ_ALL, avr->data[p->r_port]); + for (int i = 0; i < 8; i++) + avr_raise_irq(avr->io[port_io].irq + i, (avr->data[p->r_port] >> i) & 1); + } +} + +static void +avr_ioport_write( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_ioport_t * p = (avr_ioport_t *)param; + + D(if (avr->data[addr] != v) printf("** PORT%c(%02x) = %02x\r\n", p->name, addr, v);) + avr_core_watch_write(avr, addr, v); + avr_raise_irq(p->io.irq + IOPORT_IRQ_REG_PORT, v); + avr_ioport_update_irqs(p); +} + +/* + * This is a reasonably new behaviour for the io-ports. Writing 1's to the PIN register + * toggles the PORT equivalent bit (regardless of direction + */ +static void +avr_ioport_pin_write( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_ioport_t * p = (avr_ioport_t *)param; + + avr_ioport_write(avr, p->r_port, avr->data[p->r_port] ^ v, param); +} + +/* + * This is a the callback for the DDR register. There is nothing much to do here, apart + * from triggering an IRQ in case any 'client' code is interested in the information, + * and restoring all PIN bits marked as output to PORT values. + */ +static void +avr_ioport_ddr_write( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_ioport_t * p = (avr_ioport_t *)param; + + D(if (avr->data[addr] != v) printf("** DDR%c(%02x) = %02x\r\n", p->name, addr, v);) + avr_raise_irq(p->io.irq + IOPORT_IRQ_DIRECTION_ALL, v); + avr_core_watch_write(avr, addr, v); + avr_ioport_update_irqs(p); +} + +/* + * this is our "main" pin change callback, it can be triggered by either the + * AVR code, or any external piece of code that see fit to do it. + * Either way, this will raise pin change interrupts, if needed + */ +void +avr_ioport_irq_notify( + struct avr_irq_t * irq, + uint32_t value, + void * param) +{ + avr_ioport_t * p = (avr_ioport_t *)param; + avr_t * avr = p->io.avr; + + int output = value & AVR_IOPORT_OUTPUT; + value &= 0xff; + uint8_t mask = 1 << irq->irq; + uint8_t ddr = avr->data[p->r_ddr]; + + if (output) { + if ((mask & ddr) == 0) + return; // TODO: stop further processing of IRQ. + + // If the IRQ was marked as Output, also do the IO write. + + avr_ioport_write(avr, + p->r_port, + (avr->data[p->r_port] & ~mask) | + (value ? mask : 0), + p); + } else { + // Set the real PIN bit. Ignore DDR as it's masked when read. + + avr_core_watch_write(avr, p->r_pin, + (avr->data[p->r_pin] & ~mask) | + (value ? mask : 0)); + + /* BUG: If DDR bit is set here, there should be no + * interrupt. But a spurious IRQ call by the user + * is indistinguishable from an internal one + * caused by writing the output port register and + * that should cause an interrupt. Doh! + */ + } + + if (p->r_pcint) { + // Ignore lingering copy of AVR_IOPORT_OUTPUT, or + // differing non-zero values. + + if (!value == !(irq->value & 0xff)) + return; + + // if the pcint bit is on, try to raise it + + int raisedata = avr->data[p->r_pcint]; + uint8_t uiRegMask = p->mask; + int8_t iShift = p->shift; + + if (uiRegMask) // If mask is 0, do nothing (backwards compat) + raisedata &= uiRegMask; // Mask off + + if (iShift>0) // Shift data if necessary for alignment. + raisedata <<= iShift; + else if (iShift<0) + raisedata >>= -iShift; + + int raise = raisedata & mask; + if (raise) + avr_raise_interrupt(avr, &p->pcint); + } +} + +static void +avr_ioport_reset( + avr_io_t * port) +{ + avr_ioport_t * p = (avr_ioport_t *)port; + for (int i = 0; i < IOPORT_IRQ_PIN_ALL; i++) + avr_irq_register_notify(p->io.irq + i, avr_ioport_irq_notify, p); +} + +static int +avr_ioport_ioctl( + struct avr_io_t * port, + uint32_t ctl, + void * io_param) +{ + avr_ioport_t * p = (avr_ioport_t *)port; + avr_t * avr = p->io.avr; + int res = -1; + + // all IOCTls require some sort of valid parameter, bail if not + if (!io_param) + return -1; + + switch(ctl) { + case AVR_IOCTL_IOPORT_GETIRQ_REGBIT: { + avr_ioport_getirq_t * r = (avr_ioport_getirq_t*)io_param; + + if (r->bit.reg == p->r_port || r->bit.reg == p->r_pin || r->bit.reg == p->r_ddr) { + // it's us ! check the special case when the "all pins" irq is requested + int o = 0; + if (r->bit.mask == 0xff) + r->irq[o++] = &p->io.irq[IOPORT_IRQ_PIN_ALL]; + else { + // otherwise fill up the ones needed + for (int bi = 0; bi < 8; bi++) + if (r->bit.mask & (1 << bi)) + r->irq[o++] = &p->io.irq[r->bit.bit + bi]; + } + if (o < 8) + r->irq[o] = NULL; + return o; + } + } break; + default: { + /* + * Return the port state if the IOCTL matches us. + */ + if (ctl == AVR_IOCTL_IOPORT_GETSTATE(p->name)) { + avr_ioport_state_t state = { + .name = p->name, + .port = avr->data[p->r_port], + .ddr = avr->data[p->r_ddr], + .pin = avr->data[p->r_pin], + }; + if (io_param) + *((avr_ioport_state_t*)io_param) = state; + res = 0; + } + /* + * Set the default IRQ values when pin is set as input + */ + if (ctl == AVR_IOCTL_IOPORT_SET_EXTERNAL(p->name)) { + avr_ioport_external_t * m = (avr_ioport_external_t*)io_param; + p->external.pull_mask = m->mask; + p->external.pull_value = m->value; + res = 0; + } + } + } + + return res; +} + +static const char * irq_names[IOPORT_IRQ_COUNT] = { + [IOPORT_IRQ_PIN0] = "=pin0", + [IOPORT_IRQ_PIN1] = "=pin1", + [IOPORT_IRQ_PIN2] = "=pin2", + [IOPORT_IRQ_PIN3] = "=pin3", + [IOPORT_IRQ_PIN4] = "=pin4", + [IOPORT_IRQ_PIN5] = "=pin5", + [IOPORT_IRQ_PIN6] = "=pin6", + [IOPORT_IRQ_PIN7] = "=pin7", + [IOPORT_IRQ_PIN_ALL] = "8>all", + [IOPORT_IRQ_DIRECTION_ALL] = "8>ddr", + [IOPORT_IRQ_REG_PORT] = "8>port", + [IOPORT_IRQ_REG_PIN] = "8>pin", +}; + +static avr_io_t _io = { + .kind = "port", + .reset = avr_ioport_reset, + .ioctl = avr_ioport_ioctl, + .irq_names = irq_names, +}; + +void avr_ioport_init(avr_t * avr, avr_ioport_t * p) +{ + if (!p->r_port) { + printf("skipping PORT%c for core %s\n", p->name, avr->mmcu); + return; + } + p->io = _io; +// printf("%s PIN%c 0x%02x DDR%c 0x%02x PORT%c 0x%02x\n", __FUNCTION__, +// p->name, p->r_pin, +// p->name, p->r_ddr, +// p->name, p->r_port); + + avr_register_io(avr, &p->io); + avr_register_vector(avr, &p->pcint); + // allocate this module's IRQ + avr_io_setirqs(&p->io, AVR_IOCTL_IOPORT_GETIRQ(p->name), IOPORT_IRQ_COUNT, NULL); + + for (int i = 0; i < IOPORT_IRQ_REG_PIN; i++) { + p->io.irq[i].flags |= IRQ_FLAG_FILTERED; + if (i < IOPORT_IRQ_PIN_ALL) + p->io.irq[i].flags &= ~IRQ_FLAG_INIT; + } + avr_register_io_write(avr, p->r_port, avr_ioport_write, p); + avr_register_io_read(avr, p->r_pin, avr_ioport_read, p); + avr_register_io_write(avr, p->r_pin, avr_ioport_pin_write, p); + avr_register_io_write(avr, p->r_ddr, avr_ioport_ddr_write, p); + if (p->pcint.raised.reg) { + avr_register_io_write(avr, p->pcint.raised.reg, + avr_ioport_flag_write, p); + } +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_ioport.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_ioport.h new file mode 100644 index 0000000..024b695 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_ioport.h @@ -0,0 +1,148 @@ +/* + avr_ioport.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __AVR_IOPORT_H__ +#define __AVR_IOPORT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sim_avr.h" + +enum { + IOPORT_IRQ_PIN0 = 0, + IOPORT_IRQ_PIN1,IOPORT_IRQ_PIN2,IOPORT_IRQ_PIN3,IOPORT_IRQ_PIN4, + IOPORT_IRQ_PIN5,IOPORT_IRQ_PIN6,IOPORT_IRQ_PIN7, + IOPORT_IRQ_PIN_ALL, + IOPORT_IRQ_DIRECTION_ALL, + IOPORT_IRQ_REG_PORT, + IOPORT_IRQ_REG_PIN, + IOPORT_IRQ_COUNT +}; + +#define AVR_IOPORT_OUTPUT 0x100 + +// add port name (uppercase) to get the real IRQ +#define AVR_IOCTL_IOPORT_GETIRQ(_name) AVR_IOCTL_DEF('i','o','g',(_name)) + + +// this ioctl takes a avr_regbit_t, compares the register address +// to PORT/PIN/DDR and return the corresponding IRQ(s) if it matches +typedef struct avr_ioport_getirq_t { + avr_regbit_t bit; // bit wanted + avr_irq_t * irq[8]; // result, terminated by NULL if < 8 +} avr_ioport_getirq_t; + +#define AVR_IOCTL_IOPORT_GETIRQ_REGBIT AVR_IOCTL_DEF('i','o','g','r') + +/* + * ioctl used to get a port state. + * + * for (int i = 'A'; i <= 'F'; i++) { + * avr_ioport_state_t state; + * if (avr_ioctl(AVR_IOCTL_IOPORT_GETSTATE(i), &state) == 0) + * printf("PORT%c %02x DDR %02x PIN %02x\n", + * state.name, state.port, state.ddr, state.pin); + * } + */ +typedef struct avr_ioport_state_t { + unsigned long name : 7, + port : 8, ddr : 8, pin : 8; +} avr_ioport_state_t; + +// add port name (uppercase) to get the port state +#define AVR_IOCTL_IOPORT_GETSTATE(_name) AVR_IOCTL_DEF('i','o','s',(_name)) + +/* + * ioctl used to set default port state when set as input. + * + */ +typedef struct avr_ioport_external_t { + unsigned long name : 7, + mask : 8, value : 8; +} avr_ioport_external_t; + +// add port name (uppercase) to set default input pin IRQ values +#define AVR_IOCTL_IOPORT_SET_EXTERNAL(_name) AVR_IOCTL_DEF('i','o','p',(_name)) + +/** + * pin structure + */ +typedef struct avr_iopin_t { + uint16_t port : 8; ///< port e.g. 'B' + uint16_t pin : 8; ///< pin number +} avr_iopin_t; +#define AVR_IOPIN(_port, _pin) { .port = _port, .pin = _pin } + +/* + * Definition for an IO port + */ +typedef struct avr_ioport_t { + avr_io_t io; + char name; + avr_io_addr_t r_port; + avr_io_addr_t r_ddr; + avr_io_addr_t r_pin; + + avr_int_vector_t pcint; // PCINT vector + avr_io_addr_t r_pcint; // pcint 8 pins mask + + // Mask and shift for PCINTs. This is needed for chips like the 2560 + // where PCINT do not align with IRQs. + + uint8_t mask; + int8_t shift; + + // This represent the default IRQ value when + // the port is set as input. + // If the mask is not set, no output value is sent + // on the output IRQ. If the mask is set, the specified + // value is sent. + struct { + uint8_t pull_mask, pull_value; + } external; +} avr_ioport_t; + +void avr_ioport_init(avr_t * avr, avr_ioport_t * port); + +#define AVR_IOPORT_DECLARE(_lname, _cname, _uname) \ + .port ## _lname = { \ + .name = _cname, .r_port = PORT ## _uname, .r_ddr = DDR ## _uname, .r_pin = PIN ## _uname, \ + } + +#define AVR_IOPORT_DECLARE_PC(_lname, _cname, _uname, _pcnum) \ + .port ## _lname = { \ + .name = _cname, .r_port = PORT ## _uname, \ + .r_ddr = DDR ## _uname, .r_pin = PIN ## _uname, \ + .pcint = { \ + .enable = AVR_IO_REGBIT(PCICR, PCIE ## _pcnum), \ + .raised = AVR_IO_REGBIT(PCIFR, PCIF ## _pcnum), \ + .vector = PCINT ## _pcnum ## _vect, \ + }, \ + .r_pcint = PCMSK ## _pcnum, \ + } + +#ifdef __cplusplus +}; +#endif + +#endif /* __AVR_IOPORT_H__ */ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_lin.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_lin.c new file mode 100644 index 0000000..001b34c --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_lin.c @@ -0,0 +1,106 @@ +/* + avr_lin.h + + Copyright 2008, 2011 Michel Pollet <buserror@gmail.com> + Copyright 2011 Markus Lampert <mlampert@telus.net> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include "avr_lin.h" +#include "sim_time.h" + + +static void +avr_lin_baud_write( + struct avr_t *avr, + avr_io_addr_t addr, + uint8_t v, + void *param) +{ + avr_lin_t *p = (avr_lin_t*) param; + + if (p->r_linbtr != p->ldisr.reg || p->r_linbtr != p->lbt.reg) { // sanity check + AVR_LOG(avr, LOG_ERROR, "LIN: LDISR and LBT[x] register different!\n"); + return; + } + + AVR_LOG(avr, LOG_TRACE, "LIN: addr[%04x] = %02x\n", addr, v); + if (addr == p->ldisr.reg) { + if (avr_regbit_get(avr, p->lena)) { + AVR_LOG(avr, LOG_WARNING, "LIN: LENA bit set on changing LBTR\n"); + return; + } + if ((v >> p->ldisr.bit) & p->ldisr.mask) { + uint8_t lbt = (v >> p->lbt.bit) & p->lbt.mask; + uint8_t ov = v; + v = (1 << p->ldisr.bit) | (lbt << p->lbt.bit); + AVR_LOG(avr, LOG_TRACE, "LIN: v=%02x -> LBT = %02x -> LINBT = %02x\n", ov, lbt, v); + } else { + v = 0x20; + } + } + avr_core_watch_write(avr, addr, v); // actually set the value + + uint32_t lbt = avr_regbit_get(avr, p->lbt); // Min value CANNOT be zero + uint32_t lbrr = (avr->data[p->r_linbrrh] << 8) | avr->data[p->r_linbrrl]; + AVR_LOG(avr, LOG_TRACE, "LIN: UART LBT/LBRR to %04x/%04x\n", lbt, lbrr); + // there is no division by zero case here, lbt is >= 8 + //uint32_t baud = avr->frequency / (lbt * (lbrr + 1)); + uint32_t word_size = 1 /*start*/+ 8 /*data bits*/+ 1 /*parity*/+ 1 /*stop*/; + int cycles_per_bit = lbt * (lbrr + 1); + double baud = ((double)avr->frequency) / cycles_per_bit; // can be less than 1 + p->uart.cycles_per_byte = cycles_per_bit * word_size; + + AVR_LOG(avr, LOG_TRACE, "LIN: UART configured to %04x/%04x = %.4f bps, 8 data 1 stop\n", lbt, + lbrr, baud); + + //p->uart.cycles_per_byte = 1000000 / (baud / word_size); + AVR_LOG(avr, LOG_TRACE, "LIN: Roughly %d usec per byte\n", + avr_cycles_to_usec(avr, p->uart.cycles_per_byte)); +} + +static void +avr_lin_reset( + avr_io_t *port) +{ + avr_lin_t *p = (avr_lin_t*) port; + avr_t * avr = p->io.avr; + + AVR_LOG(avr, LOG_TRACE, "LIN: UART: reset\n"); + + p->uart.io.reset(&p->uart.io); + avr->data[p->r_linbtr] = 0x20; +} + +static avr_io_t _io = { + .kind = "lin", + .reset = avr_lin_reset, +}; + +void +avr_lin_init( + avr_t *avr, + avr_lin_t *p) +{ + // init uart part + avr_uart_init(avr, &p->uart); + + p->io = _io; + avr_register_io_write(avr, p->r_linbtr, avr_lin_baud_write, p); + avr_register_io_write(avr, p->r_linbrrl, avr_lin_baud_write, p); +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_lin.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_lin.h new file mode 100644 index 0000000..b1ecadf --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_lin.h @@ -0,0 +1,55 @@ +/* + avr_lin.h + + Copyright 2008, 2011 Michel Pollet <buserror@gmail.com> + Copyright 2011 Markus Lampert <mlampert@telus.net> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __AVR_LIN_H__ +#define __AVR_LIN_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sim_avr.h" +#include "avr_uart.h" + +typedef struct avr_lin_t { + avr_io_t io; + + avr_io_addr_t r_linbtr; + avr_io_addr_t r_linbrrh, r_linbrrl; + + avr_regbit_t lena; + avr_regbit_t ldisr; + avr_regbit_t lbt; + + avr_uart_t uart; // used when LIN controller is setup as a UART +} avr_lin_t; + +void +avr_lin_init( + avr_t *avr, + avr_lin_t *port); + +#ifdef __cplusplus +}; +#endif + +#endif /* __AVR_LIN_H__ */ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_spi.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_spi.c new file mode 100644 index 0000000..bb602ac --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_spi.c @@ -0,0 +1,119 @@ +/* + avr_spi.c + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + Modified 2020 by VintagePC <https://github.com/vintagepc> to support clock divisors + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include "avr_spi.h" + +static avr_cycle_count_t avr_spi_raise(struct avr_t * avr, avr_cycle_count_t when, void * param) +{ + avr_spi_t * p = (avr_spi_t *)param; + + if (avr_regbit_get(avr, p->spe)) { + // in master mode, any byte is sent as it comes.. + if (avr_regbit_get(avr, p->mstr)) { + avr_raise_interrupt(avr, &p->spi); + avr_raise_irq(p->io.irq + SPI_IRQ_OUTPUT, avr->data[p->r_spdr]); + } + } + return 0; +} + +static uint8_t avr_spi_read(struct avr_t * avr, avr_io_addr_t addr, void * param) +{ + avr_spi_t * p = (avr_spi_t *)param; + uint8_t v = p->input_data_register; + p->input_data_register = 0; + avr_regbit_clear(avr, p->spi.raised); +// printf("avr_spi_read = %02x\n", v); + return v; +} + +static void avr_spi_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param) +{ + + static const uint8_t _avr_spi_clkdiv[4] = {4,16,64,128}; + avr_spi_t * p = (avr_spi_t *)param; + + if (addr == p->r_spdr) { + /* Clear the SPIF bit. See ATmega164/324/644 manual, Section 18.5.2. */ + avr_regbit_clear(avr, p->spi.raised); + + avr_core_watch_write(avr, addr, v); + uint16_t clock_shift = _avr_spi_clkdiv[avr->data[p->r_spcr]&0b11]; + // If master && 2X, double rate (half divisor) + if (avr_regbit_get(avr, p->mstr) && avr_regbit_get(avr, p->spr[2])) + clock_shift>>=1; + + // We can wait directly in clockshifts, it is a divisor, so /4 means 4 avr cycles to clock out one bit. + avr_cycle_timer_register(avr, clock_shift<<3, avr_spi_raise, p); // *8 since 8 clocks to a byte. + } +} + +static void avr_spi_irq_input(struct avr_irq_t * irq, uint32_t value, void * param) +{ + avr_spi_t * p = (avr_spi_t *)param; + avr_t * avr = p->io.avr; + + // check to see if receiver is enabled + if (!avr_regbit_get(avr, p->spe)) + return; + + // double buffer the input.. ? + p->input_data_register = value; + avr_raise_interrupt(avr, &p->spi); + + // if in slave mode, + // 'output' the byte only when we received one... + if (!avr_regbit_get(avr, p->mstr)) { + avr_raise_irq(p->io.irq + SPI_IRQ_OUTPUT, avr->data[p->r_spdr]); + } +} + +void avr_spi_reset(struct avr_io_t *io) +{ + avr_spi_t * p = (avr_spi_t *)io; + avr_irq_register_notify(p->io.irq + SPI_IRQ_INPUT, avr_spi_irq_input, p); +} + +static const char * irq_names[SPI_IRQ_COUNT] = { + [SPI_IRQ_INPUT] = "8<in", + [SPI_IRQ_OUTPUT] = "8<out", +}; + +static avr_io_t _io = { + .kind = "spi", + .reset = avr_spi_reset, + .irq_names = irq_names, +}; + +void avr_spi_init(avr_t * avr, avr_spi_t * p) +{ + p->io = _io; + + avr_register_io(avr, &p->io); + avr_register_vector(avr, &p->spi); + // allocate this module's IRQ + avr_io_setirqs(&p->io, AVR_IOCTL_SPI_GETIRQ(p->name), SPI_IRQ_COUNT, NULL); + + avr_register_io_write(avr, p->r_spdr, avr_spi_write, p); + avr_register_io_read(avr, p->r_spdr, avr_spi_read, p); +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_spi.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_spi.h new file mode 100644 index 0000000..c676adb --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_spi.h @@ -0,0 +1,107 @@ +/* + avr_spi.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + Modified 2020 by VintagePC <https://github.com/vintagepc> to support clock divisors + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __AVR_SPI_H__ +#define __AVR_SPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sim_avr.h" + +enum { + SPI_IRQ_INPUT = 0, + SPI_IRQ_OUTPUT, + SPI_IRQ_COUNT +}; + +// add port number to get the real IRQ +#define AVR_IOCTL_SPI_GETIRQ(_name) AVR_IOCTL_DEF('s','p','i',(_name)) + +typedef struct avr_spi_t { + avr_io_t io; + char name; + avr_regbit_t disabled; // bit in the PRR + + avr_io_addr_t r_spdr; // data register + avr_io_addr_t r_spcr; // control register + avr_io_addr_t r_spsr; // status register + + avr_regbit_t spe; // spi enable + avr_regbit_t mstr; // master/slave + avr_regbit_t spr[4]; // clock divider + + avr_int_vector_t spi; // spi interrupt + + uint8_t input_data_register; +} avr_spi_t; + +void avr_spi_init(avr_t * avr, avr_spi_t * port); + +#define AVR_SPIX_DECLARE(_name, _prr, _prspi) \ + .spi = { \ + .name = '0' + _name,\ + .disabled = AVR_IO_REGBIT(_prr, _prspi), \ + \ + .r_spdr = SPDR ## _name, \ + .r_spcr = SPCR ## _name, \ + .r_spsr = SPSR ## _name, \ + \ + .spe = AVR_IO_REGBIT(SPCR ## _name, SPE ## _name), \ + .mstr = AVR_IO_REGBIT(SPCR ## _name, MSTR ## _name), \ + \ + .spr = { AVR_IO_REGBIT(SPCR ## _name, SPR0 ## _name), \ + AVR_IO_REGBIT(SPCR ## _name, SPR1 ## _name), \ + AVR_IO_REGBIT(SPSR ## _name, SPI2X ## _name) }, \ + .spi = { \ + .enable = AVR_IO_REGBIT(SPCR ## _name, SPIE ## _name), \ + .raised = AVR_IO_REGBIT(SPSR ## _name, SPIF ## _name), \ + .vector = SPI_STC_vect, \ + }, \ + } + + +#define AVR_SPI_DECLARE(_prr, _prspi) \ + .spi = { \ + .disabled = AVR_IO_REGBIT(_prr, _prspi), \ + \ + .r_spdr = SPDR, \ + .r_spcr = SPCR, \ + .r_spsr = SPSR, \ + \ + .spe = AVR_IO_REGBIT(SPCR, SPE), \ + .mstr = AVR_IO_REGBIT(SPCR, MSTR), \ + \ + .spr = { AVR_IO_REGBIT(SPCR, SPR0), AVR_IO_REGBIT(SPCR, SPR1), AVR_IO_REGBIT(SPSR, SPI2X) }, \ + .spi = { \ + .enable = AVR_IO_REGBIT(SPCR, SPIE), \ + .raised = AVR_IO_REGBIT(SPSR, SPIF), \ + .vector = SPI_STC_vect, \ + }, \ + } + +#ifdef __cplusplus +}; +#endif + +#endif /*__AVR_SPI_H__*/ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_timer.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_timer.c new file mode 100644 index 0000000..39a46bd --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_timer.c @@ -0,0 +1,985 @@ +/* + avr_timer.c + + Handles the 8 bits and 16 bits AVR timer. + Handles + + CDC + + Fast PWM + + Copyright 2008-2012 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include <math.h> + +#include "avr_timer.h" +#include "avr_ioport.h" +#include "sim_time.h" + +/* + * The timers are /always/ 16 bits here, if the higher byte register + * is specified it's just added. + */ +static uint16_t +_timer_get_ocr( + avr_timer_t * p, + int compi) +{ + return p->io.avr->data[p->comp[compi].r_ocr] | + (p->comp[compi].r_ocrh ? + (p->io.avr->data[p->comp[compi].r_ocrh] << 8) : 0); +} + +static uint16_t +_timer_get_comp_ocr( + struct avr_t * avr, + avr_timer_comp_p comp) +{ + int ocrh = comp->r_ocrh; + return avr->data[comp->r_ocr] | + (ocrh ? (avr->data[ocrh] << 8) : 0); +} + +static uint16_t +_timer_get_tcnt( + avr_timer_t * p) +{ + return p->io.avr->data[p->r_tcnt] | + (p->r_tcnth ? (p->io.avr->data[p->r_tcnth] << 8) : 0); +} + +static uint16_t +_timer_get_icr( + avr_timer_t * p) +{ + return p->io.avr->data[p->r_icr] | + (p->r_tcnth ? (p->io.avr->data[p->r_icrh] << 8) : 0); +} +static avr_cycle_count_t +avr_timer_comp( + avr_timer_t *p, + avr_cycle_count_t when, + uint8_t comp, + uint8_t raise_interrupt) +{ + avr_t * avr = p->io.avr; + if (raise_interrupt) { + avr_raise_interrupt(avr, &p->comp[comp].interrupt); + } + + // check output compare mode and set/clear pins + uint8_t mode = avr_regbit_get(avr, p->comp[comp].com); + avr_irq_t * irq = &p->io.irq[TIMER_IRQ_OUT_COMP + comp]; + + uint32_t flags = 0; + if (p->comp[comp].com_pin.reg) // we got a physical pin + flags |= AVR_IOPORT_OUTPUT; + AVR_LOG(avr, LOG_TRACE, "Timer comp: irq %p, mode %d @%d\n", irq, mode, when); + switch (mode) { + case avr_timer_com_normal: // Normal mode OCnA disconnected + break; + case avr_timer_com_toggle: // Toggle OCnA on compare match + if (p->comp[comp].com_pin.reg) // we got a physical pin + avr_raise_irq(irq, + flags | + (avr_regbit_get(avr, p->comp[comp].com_pin) ? 0 : 1)); + else // no pin, toggle the IRQ anyway + avr_raise_irq(irq, + p->io.irq[TIMER_IRQ_OUT_COMP + comp].value ? 0 : 1); + break; + case avr_timer_com_clear: + avr_raise_irq(irq, flags | 0); + break; + case avr_timer_com_set: + avr_raise_irq(irq, flags | 1); + break; + } + + return p->tov_cycles ? 0 : + p->comp[comp].comp_cycles ? + when + p->comp[comp].comp_cycles : 0; +} + +static void +avr_timer_comp_on_tov( + avr_timer_t *p, + avr_cycle_count_t when, + uint8_t comp) +{ + avr_t * avr = p->io.avr; + + // check output compare mode and set/clear pins + uint8_t mode = avr_regbit_get(avr, p->comp[comp].com); + avr_irq_t * irq = &p->io.irq[TIMER_IRQ_OUT_COMP + comp]; + + // only PWM modes have special behaviour on overflow + if((p->wgm_op_mode_kind != avr_timer_wgm_pwm) && + (p->wgm_op_mode_kind != avr_timer_wgm_fast_pwm)) + return; + + switch (mode) { + case avr_timer_com_normal: // Normal mode + break; + case avr_timer_com_toggle: // toggle on compare match => on tov do nothing + break; + case avr_timer_com_clear: // clear on compare match => set on tov + avr_raise_irq(irq, 1); + break; + case avr_timer_com_set: // set on compare match => clear on tov + avr_raise_irq(irq, 0); + break; + } +} + +static avr_cycle_count_t +avr_timer_compa( + struct avr_t * avr, + avr_cycle_count_t when, + void * param) +{ + return avr_timer_comp((avr_timer_t*)param, when, AVR_TIMER_COMPA, 1); +} + +static avr_cycle_count_t +avr_timer_compb( + struct avr_t * avr, + avr_cycle_count_t when, + void * param) +{ + return avr_timer_comp((avr_timer_t*)param, when, AVR_TIMER_COMPB, 1); +} + +static avr_cycle_count_t +avr_timer_compc( + struct avr_t * avr, + avr_cycle_count_t when, + void * param) +{ + return avr_timer_comp((avr_timer_t*)param, when, AVR_TIMER_COMPC, 1); +} + +static void +avr_timer_irq_ext_clock( + struct avr_irq_t * irq, + uint32_t value, + void * param) +{ + avr_timer_t * p = (avr_timer_t *)param; + avr_t * avr = p->io.avr; + + if ((p->ext_clock_flags & AVR_TIMER_EXTCLK_FLAG_VIRT) || !p->tov_top) + return; // we are clocked internally (actually should never come here) + + int bing = 0; + if (p->ext_clock_flags & AVR_TIMER_EXTCLK_FLAG_EDGE) { // clock on rising edge + if (!irq->value && value) + bing++; + } else { // clock on falling edge + if (irq->value && !value) + bing++; + } + if (!bing) + return; + + //AVR_LOG(avr, LOG_TRACE, "%s Timer%c tick, tcnt=%i\n", __func__, p->name, p->tov_base); + + p->ext_clock_flags |= AVR_TIMER_EXTCLK_FLAG_STARTED; + + static const avr_cycle_timer_t dispatch[AVR_TIMER_COMP_COUNT] = + { avr_timer_compa, avr_timer_compb, avr_timer_compc }; + + int overflow = 0; + /** + * + * Datasheet excerpt (Compare Match Output Unit): + * "The 16-bit comparator continuously compares TCNT1 with the Output Compare Regis- + ter (OCR1x). If TCNT equals OCR1x the comparator signals a match. A match will set + the Output Compare Flag (OCF1x) at the next timer clock cycle. If enabled (OCIE1x = + 1), the Output Compare Flag generates an output compare interrupt." + Thus, comparators should go before incementing the counter to use counter value + from the previous cycle. + */ + for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) { + if (p->wgm_op_mode_kind != avr_timer_wgm_ctc) { + if ((p->mode.top == avr_timer_wgm_reg_ocra) && (compi == 0)) + continue; // ocra used to define TOP + } + if (p->comp[compi].comp_cycles && (p->tov_base == p->comp[compi].comp_cycles)) { + dispatch[compi](avr, avr->cycle, param); + if (p->wgm_op_mode_kind == avr_timer_wgm_ctc) + p->tov_base = 0; + } + } + + switch (p->wgm_op_mode_kind) { + case avr_timer_wgm_fc_pwm: // in the avr_timer_write_ocr comment "OCR is not used here" - why? + case avr_timer_wgm_pwm: + if ((p->ext_clock_flags & AVR_TIMER_EXTCLK_FLAG_REVDIR) != 0) { + --p->tov_base; + if (p->tov_base == 0) { + // overflow occured + p->ext_clock_flags &= ~AVR_TIMER_EXTCLK_FLAG_REVDIR; // restore forward count direction + overflow = 1; + } + } + else { + if (++p->tov_base >= p->tov_top) { + p->ext_clock_flags |= AVR_TIMER_EXTCLK_FLAG_REVDIR; // prepare to count down + } + } + break; + case avr_timer_wgm_fast_pwm: + if (++p->tov_base == p->tov_top) { + overflow = 1; + if (p->mode.top == avr_timer_wgm_reg_icr) + avr_raise_interrupt(avr, &p->icr); + else if (p->mode.top == avr_timer_wgm_reg_ocra) + avr_raise_interrupt(avr, &p->comp[0].interrupt); + } + else if (p->tov_base > p->tov_top) { + p->tov_base = 0; + } + break; + case avr_timer_wgm_ctc: + { + int max = (1 << p->wgm_op[0].size)-1; + if (++p->tov_base > max) { + // overflow occured + p->tov_base = 0; + overflow = 1; + } + } + break; + default: + if (++p->tov_base > p->tov_top) { + // overflow occured + p->tov_base = 0; + overflow = 1; + } + break; + } + + if (overflow) { + for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) { + if (p->comp[compi].comp_cycles) { + if (p->mode.top == avr_timer_wgm_reg_ocra && compi == 0) + continue; + avr_timer_comp_on_tov(p, 0, compi); + } + } + avr_raise_interrupt(avr, &p->overflow); + } + +} + +// timer overflow +static avr_cycle_count_t +avr_timer_tov( + struct avr_t * avr, + avr_cycle_count_t when, + void * param) +{ + avr_timer_t * p = (avr_timer_t *)param; + int start = p->tov_base == 0; + + avr_cycle_count_t next = when; + if (((p->ext_clock_flags & (AVR_TIMER_EXTCLK_FLAG_AS2 | AVR_TIMER_EXTCLK_FLAG_TN)) != 0) + && (p->tov_cycles_fract != 0.0f)) { + p->phase_accumulator += p->tov_cycles_fract; + if (p->phase_accumulator >= 1.0f) { + ++next; + p->phase_accumulator -= 1.0f; + } else if (p->phase_accumulator <= -1.0f) { + --next; + p->phase_accumulator += 1.0f; + } + } + + if (!start) + avr_raise_interrupt(avr, &p->overflow); + p->tov_base = when; + + static const avr_cycle_timer_t dispatch[AVR_TIMER_COMP_COUNT] = + { avr_timer_compa, avr_timer_compb, avr_timer_compc }; + + for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) { + if (p->comp[compi].comp_cycles) { + if (p->comp[compi].comp_cycles < p->tov_cycles && p->comp[compi].comp_cycles >= (avr->cycle - when)) { + avr_timer_comp_on_tov(p, when, compi); + avr_cycle_timer_register(avr, + p->comp[compi].comp_cycles - (avr->cycle - next), + dispatch[compi], p); + } else if (p->tov_cycles == p->comp[compi].comp_cycles && !start) + dispatch[compi](avr, when, param); + } + } + + return next + p->tov_cycles; +} + +static uint16_t +_avr_timer_get_current_tcnt( + avr_timer_t * p) +{ + avr_t * avr = p->io.avr; + if (!(p->ext_clock_flags & (AVR_TIMER_EXTCLK_FLAG_TN | AVR_TIMER_EXTCLK_FLAG_AS2)) || + (p->ext_clock_flags & AVR_TIMER_EXTCLK_FLAG_VIRT) + ) { + if (p->tov_cycles) { + uint64_t when = avr->cycle - p->tov_base; + + return (when * (((uint32_t)p->tov_top)+1)) / p->tov_cycles; + } + } + else { + if (p->tov_top) + return p->tov_base; + } + return 0; +} + +static uint8_t +avr_timer_tcnt_read( + struct avr_t * avr, + avr_io_addr_t addr, + void * param) +{ + avr_timer_t * p = (avr_timer_t *)param; + // made to trigger potential watchpoints + + uint16_t tcnt = _avr_timer_get_current_tcnt(p); + + avr->data[p->r_tcnt] = tcnt; + if (p->r_tcnth) + avr->data[p->r_tcnth] = tcnt >> 8; + + return avr_core_watch_read(avr, addr); +} + +static inline void +avr_timer_cancel_all_cycle_timers( + struct avr_t * avr, + avr_timer_t *timer, + const uint8_t clear_timers) +{ + if(clear_timers) { + for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) + timer->comp[compi].comp_cycles = 0; + timer->tov_cycles = 0; + } + + + avr_cycle_timer_cancel(avr, avr_timer_tov, timer); + avr_cycle_timer_cancel(avr, avr_timer_compa, timer); + avr_cycle_timer_cancel(avr, avr_timer_compb, timer); + avr_cycle_timer_cancel(avr, avr_timer_compc, timer); +} + +static void +avr_timer_tcnt_write( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_timer_t * p = (avr_timer_t *)param; + avr_core_watch_write(avr, addr, v); + uint16_t tcnt = _timer_get_tcnt(p); + + if (!p->tov_top) + return; + + if (tcnt >= p->tov_top) + tcnt = 0; + + if (!(p->ext_clock_flags & (AVR_TIMER_EXTCLK_FLAG_TN | AVR_TIMER_EXTCLK_FLAG_AS2)) || + (p->ext_clock_flags & AVR_TIMER_EXTCLK_FLAG_VIRT) + ) { + // internal or virtual clock + + // this involves some magicking + // cancel the current timers, recalculate the "base" we should be at, reset the + // timer base as it should, and re-schedule the timers using that base. + + avr_timer_cancel_all_cycle_timers(avr, p, 0); + + uint64_t cycles = (tcnt * p->tov_cycles) / p->tov_top; + + // printf("%s-%c %d/%d -- cycles %d/%d\n", __FUNCTION__, p->name, tcnt, p->tov_top, (uint32_t)cycles, (uint32_t)p->tov_cycles); + + // this reset the timers bases to the new base + if (p->tov_cycles > 1) { + avr_cycle_timer_register(avr, p->tov_cycles - cycles, avr_timer_tov, p); + p->tov_base = 0; + avr_timer_tov(avr, avr->cycle - cycles, p); + } + + // tcnt = ((avr->cycle - p->tov_base) * p->tov_top) / p->tov_cycles; + // printf("%s-%c new tnt derive to %d\n", __FUNCTION__, p->name, tcnt); + } + else { + // clocked externally + p->tov_base = tcnt; + } +} + +static void +avr_timer_configure( + avr_timer_t * p, + uint32_t prescaler, + uint32_t top, + uint8_t reset) +{ + p->tov_top = top; + + avr_t * avr = p->io.avr; + float resulting_clock = 0.0f; // used only for trace + float tov_cycles_exact = 0; + + uint8_t as2 = p->ext_clock_flags & AVR_TIMER_EXTCLK_FLAG_AS2; + uint8_t use_ext_clock = as2 || (p->ext_clock_flags & AVR_TIMER_EXTCLK_FLAG_TN); + uint8_t virt_ext_clock = use_ext_clock && (p->ext_clock_flags & AVR_TIMER_EXTCLK_FLAG_VIRT); + + if (!use_ext_clock) { + if (prescaler != 0) + resulting_clock = (float)avr->frequency / prescaler; + p->tov_cycles = prescaler * (top+1); + p->tov_cycles_fract = 0.0f; + tov_cycles_exact = p->tov_cycles; + } else { + if (!virt_ext_clock) { + p->tov_cycles = 0; + p->tov_cycles_fract = 0.0f; + } else { + if (prescaler != 0) + resulting_clock = p->ext_clock / prescaler; + tov_cycles_exact = (float)avr->frequency / p->ext_clock * prescaler * (top+1); + // p->tov_cycles = round(tov_cycles_exact); -- don't want libm! + p->tov_cycles = tov_cycles_exact + .5f; // Round to integer + p->tov_cycles_fract = tov_cycles_exact - p->tov_cycles; + } + } + + if (p->trace) { + if (!use_ext_clock || virt_ext_clock) { + // clocked internally + AVR_LOG(avr, LOG_TRACE, "TIMER: %s-%c TOP %.2fHz = %d cycles = %dusec\n", // TOP there means Timer Overflows Persec ? + __FUNCTION__, p->name, ((float)avr->frequency / tov_cycles_exact), + (int)p->tov_cycles, (int)avr_cycles_to_usec(avr, p->tov_cycles)); + } else { + // clocked externally from the Tn pin + AVR_LOG(avr, LOG_TRACE, "TIMER: %s-%c use ext clock, TOP=%d\n", + __FUNCTION__, p->name, (int)p->tov_top + ); + } + } + + for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) { + if (!p->comp[compi].r_ocr) + continue; + uint32_t ocr = _timer_get_ocr(p, compi); + //uint32_t comp_cycles = clock * (ocr + 1); + uint32_t comp_cycles; + if (virt_ext_clock) + comp_cycles = (uint32_t)((float)avr->frequency / p->ext_clock * prescaler * (ocr+1)); + else + comp_cycles = prescaler * (ocr + 1); + + p->comp[compi].comp_cycles = 0; + + if (p->trace & (avr_timer_trace_compa << compi)) { + if (!use_ext_clock || virt_ext_clock) { + printf("%s-%c clock %f top %d OCR%c %d\n", __FUNCTION__, p->name, + resulting_clock, top, 'A'+compi, ocr); + } else { + AVR_LOG(avr, LOG_TRACE, "%s timer%c clock via ext pin, TOP=%d OCR%c=%d\n", + __FUNCTION__, p->name, top, 'A'+compi, ocr); + } + } + if (ocr <= top) { + p->comp[compi].comp_cycles = comp_cycles; + + if (p->trace & (avr_timer_trace_compa << compi)) printf( + "TIMER: %s-%c %c %.2fHz = %d cycles\n", + __FUNCTION__, p->name, + 'A'+compi, resulting_clock / (ocr+1), + (int)comp_cycles); + } + } + + if (!use_ext_clock || virt_ext_clock) { + if (p->tov_cycles > 1) { + if (reset) { + avr_cycle_timer_register(avr, p->tov_cycles, avr_timer_tov, p); + // calling it once, with when == 0 tells it to arm the A/B/C timers if needed + p->tov_base = 0; + avr_timer_tov(avr, avr->cycle, p); + p->phase_accumulator = 0.0f; + } else { + uint64_t orig_tov_base = p->tov_base; + avr_cycle_timer_register(avr, p->tov_cycles - (avr->cycle - orig_tov_base), avr_timer_tov, p); + // calling it once, with when == 0 tells it to arm the A/B/C timers if needed + p->tov_base = 0; + avr_timer_tov(avr, orig_tov_base, p); + } + } + } else { + if (reset) + p->tov_base = 0; + } + + if (reset) { + avr_ioport_getirq_t req = { + .bit = p->ext_clock_pin + }; + if (avr_ioctl(p->io.avr, AVR_IOCTL_IOPORT_GETIRQ_REGBIT, &req) > 0) { + // got an IRQ for the Tn input clock pin + if (use_ext_clock && !virt_ext_clock) { + if (p->trace) + AVR_LOG(p->io.avr, LOG_TRACE, "%s: timer%c connecting T%c pin IRQ %d\n", __FUNCTION__, p->name, p->name, req.irq[0]->irq); + avr_irq_register_notify(req.irq[0], avr_timer_irq_ext_clock, p); + } else { + if (p->trace) + AVR_LOG(p->io.avr, LOG_TRACE, "%s: timer%c disconnecting T%c pin IRQ %d\n", __FUNCTION__, p->name, p->name, req.irq[0]->irq); + avr_irq_unregister_notify(req.irq[0], avr_timer_irq_ext_clock, p); + } + } + } + +} + +static void +avr_timer_reconfigure( + avr_timer_t * p, uint8_t reset) +{ + avr_t * avr = p->io.avr; + + // cancel everything + avr_timer_cancel_all_cycle_timers(avr, p, 1); + + switch (p->wgm_op_mode_kind) { + case avr_timer_wgm_normal: + avr_timer_configure(p, p->cs_div_value, p->wgm_op_mode_size, reset); + break; + case avr_timer_wgm_fc_pwm: + avr_timer_configure(p, p->cs_div_value, p->wgm_op_mode_size, reset); + break; + case avr_timer_wgm_ctc: { + avr_timer_configure(p, p->cs_div_value, _timer_get_ocr(p, AVR_TIMER_COMPA), reset); + } break; + case avr_timer_wgm_pwm: { + uint16_t top = (p->mode.top == avr_timer_wgm_reg_ocra) ? + _timer_get_ocr(p, AVR_TIMER_COMPA) : _timer_get_icr(p); + avr_timer_configure(p, p->cs_div_value, top, reset); + } break; + case avr_timer_wgm_fast_pwm: { + uint16_t top = + (p->mode.top == avr_timer_wgm_reg_icr) ? _timer_get_icr(p) : + p->wgm_op_mode_size; + avr_timer_configure(p, p->cs_div_value, top, reset); + } break; + case avr_timer_wgm_none: + avr_timer_configure(p, p->cs_div_value, p->wgm_op_mode_size, reset); + break; + default: { + uint8_t mode = avr_regbit_get_array(avr, p->wgm, ARRAY_SIZE(p->wgm)); + AVR_LOG(avr, LOG_WARNING, "TIMER: %s-%c unsupported timer mode wgm=%d (%d)\n", + __FUNCTION__, p->name, mode, p->mode.kind); + } + } +} + +static void +avr_timer_write_ocr( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_timer_comp_p comp = (avr_timer_comp_p)param; + avr_timer_t *timer = comp->timer; + uint16_t oldv; + + /* check to see if the OCR values actually changed */ + oldv = _timer_get_comp_ocr(avr, comp); + avr_core_watch_write(avr, addr, v); + + switch (timer->wgm_op_mode_kind) { + case avr_timer_wgm_normal: + avr_timer_reconfigure(timer, 0); + break; + case avr_timer_wgm_fc_pwm: // OCR is not used here + avr_timer_reconfigure(timer, 0); + break; + case avr_timer_wgm_ctc: + avr_timer_reconfigure(timer, 0); + break; + case avr_timer_wgm_pwm: + if (timer->mode.top != avr_timer_wgm_reg_ocra) { + avr_raise_irq(timer->io.irq + TIMER_IRQ_OUT_PWM0, _timer_get_ocr(timer, AVR_TIMER_COMPA)); + } else { + avr_timer_reconfigure(timer, 0); // if OCRA is the top, reconfigure needed + } + avr_raise_irq(timer->io.irq + TIMER_IRQ_OUT_PWM1, _timer_get_ocr(timer, AVR_TIMER_COMPB)); + if (sizeof(timer->comp)>2) + avr_raise_irq(timer->io.irq + TIMER_IRQ_OUT_PWM2, _timer_get_ocr(timer, AVR_TIMER_COMPC)); + break; + case avr_timer_wgm_fast_pwm: + if (oldv != _timer_get_comp_ocr(avr, comp)) + avr_timer_reconfigure(timer, 0); + avr_raise_irq(timer->io.irq + TIMER_IRQ_OUT_PWM0, + _timer_get_ocr(timer, AVR_TIMER_COMPA)); + avr_raise_irq(timer->io.irq + TIMER_IRQ_OUT_PWM1, + _timer_get_ocr(timer, AVR_TIMER_COMPB)); + if (sizeof(timer->comp)>2) + avr_raise_irq(timer->io.irq + TIMER_IRQ_OUT_PWM2, + _timer_get_ocr(timer, AVR_TIMER_COMPC)); + break; + default: + AVR_LOG(avr, LOG_WARNING, "TIMER: %s-%c mode %d UNSUPPORTED\n", + __FUNCTION__, timer->name, timer->mode.kind); + avr_timer_reconfigure(timer, 0); + break; + } +} + +static void +avr_timer_write( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_timer_t * p = (avr_timer_t *)param; + + uint8_t as2 = avr_regbit_get(avr, p->as2); + uint8_t cs = avr_regbit_get_array(avr, p->cs, ARRAY_SIZE(p->cs)); + uint8_t mode = avr_regbit_get_array(avr, p->wgm, ARRAY_SIZE(p->wgm)); + + avr_core_watch_write(avr, addr, v); + + uint8_t new_as2 = avr_regbit_get(avr, p->as2); + uint8_t new_cs = avr_regbit_get_array(avr, p->cs, ARRAY_SIZE(p->cs)); + uint8_t new_mode = avr_regbit_get_array(avr, p->wgm, ARRAY_SIZE(p->wgm)); + + // only reconfigure the timer if "relevant" bits have changed + // this prevent the timer reset when changing the edge detector + // or other minor bits + if (new_cs != cs || new_mode != mode || new_as2 != as2) { + /* cs */ + if (new_cs == 0) { + p->cs_div_value = 0; // reset prescaler + // cancel everything + avr_timer_cancel_all_cycle_timers(avr, p, 1); + + AVR_LOG(avr, LOG_TRACE, "TIMER: %s-%c clock turned off\n", + __func__, p->name); + return; + } + + p->ext_clock_flags &= ~(AVR_TIMER_EXTCLK_FLAG_TN | AVR_TIMER_EXTCLK_FLAG_EDGE + | AVR_TIMER_EXTCLK_FLAG_AS2 | AVR_TIMER_EXTCLK_FLAG_STARTED); + if (p->ext_clock_pin.reg + && (p->cs_div[new_cs] == AVR_TIMER_EXTCLK_CHOOSE)) { + // Special case: external clock source chosen, prescale divider irrelevant. + p->cs_div_value = 1; + p->ext_clock_flags |= AVR_TIMER_EXTCLK_FLAG_TN | (new_cs & AVR_TIMER_EXTCLK_FLAG_EDGE); + } else { + p->cs_div_value = 1 << p->cs_div[new_cs]; + if (new_as2) { + //p->cs_div_value = (uint32_t)((uint64_t)avr->frequency * (1 << p->cs_div[new_cs]) / 32768); + p->ext_clock_flags |= AVR_TIMER_EXTCLK_FLAG_AS2 | AVR_TIMER_EXTCLK_FLAG_EDGE; + } + } + + /* mode */ + p->mode = p->wgm_op[new_mode]; + p->wgm_op_mode_kind = p->mode.kind; + p->wgm_op_mode_size = (1 << p->mode.size) - 1; + + avr_timer_reconfigure(p, 1); + } +} + +/* + * write to the "force output compare" bits + */ +static void avr_timer_write_foc(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param) +{ + avr_timer_t * p = (avr_timer_t *)param; + + /* These are strobe writes, so just decode them, don't store them */ + + for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) { + if ((addr == p->comp[compi].foc.reg) && + (v & (1 << p->comp[compi].foc.bit))) { + avr_timer_comp(p, avr->cycle, compi, 0); + } + } +} + +/* + * write to the TIFR register. Watch for code that writes "1" to clear + * pending interrupts. + */ +static void +avr_timer_write_pending( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_timer_t * p = (avr_timer_t *)param; + + // All bits in this register are assumed to be write-1-to-clear. + + if (addr == p->overflow.raised.reg && + avr_regbit_from_value(avr, p->overflow.raised, v)) { + avr_clear_interrupt(avr, &p->overflow); + } + if (addr == p->icr.raised.reg && + avr_regbit_from_value(avr, p->icr.raised, v)) { + avr_clear_interrupt(avr, &p->icr); + } + + for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) { + if (addr == p->comp[compi].interrupt.raised.reg && + avr_regbit_from_value(avr, p->comp[compi].interrupt.raised, + v)) { + avr_clear_interrupt(avr, &p->comp[compi].interrupt); + } + } +} + +static void +avr_timer_irq_icp( + struct avr_irq_t * irq, + uint32_t value, + void * param) +{ + avr_timer_t * p = (avr_timer_t *)param; + avr_t * avr = p->io.avr; + + // input capture disabled when ICR is used as top + if (p->mode.top == avr_timer_wgm_reg_icr) + return; + int bing = 0; + if (avr_regbit_get(avr, p->ices)) { // rising edge + if (!irq->value && value) + bing++; + } else { // default, falling edge + if (irq->value && !value) + bing++; + } + if (!bing) + return; + // get current TCNT, copy it to ICR, and raise interrupt + uint16_t tcnt = _avr_timer_get_current_tcnt(p); + avr->data[p->r_icr] = tcnt; + if (p->r_icrh) + avr->data[p->r_icrh] = tcnt >> 8; + avr_raise_interrupt(avr, &p->icr); +} + +static int +avr_timer_ioctl( + avr_io_t * port, + uint32_t ctl, + void * io_param) +{ + avr_timer_t * p = (avr_timer_t *)port; + int res = -1; + + if (ctl == AVR_IOCTL_TIMER_SET_TRACE(p->name)) { + /* Allow setting individual trace flags */ + p->trace = *((uint32_t*)io_param); + res = 0; + } else if (ctl == AVR_IOCTL_TIMER_SET_FREQCLK(p->name)) { + float new_freq = *((float*)io_param); + if (new_freq >= 0.0f) { + if (p->as2.reg) { + if (new_freq <= port->avr->frequency/4) { + p->ext_clock = new_freq; + res = 0; + } + } else if (p->ext_clock_pin.reg) { + if (new_freq <= port->avr->frequency/2) { + p->ext_clock = new_freq; + res = 0; + } + } + } + } else if (ctl == AVR_IOCTL_TIMER_SET_VIRTCLK(p->name)) { + uint8_t new_val = *((uint8_t*)io_param); + if (!new_val) { + avr_ioport_getirq_t req_timer_clock_pin = { + .bit = p->ext_clock_pin + }; + if (avr_ioctl(p->io.avr, AVR_IOCTL_IOPORT_GETIRQ_REGBIT, &req_timer_clock_pin) > 0) { + p->ext_clock_flags &= ~AVR_TIMER_EXTCLK_FLAG_VIRT; + res = 0; + } + } else { + p->ext_clock_flags |= AVR_TIMER_EXTCLK_FLAG_VIRT; + res = 0; + } + } + if (res >= 0) + avr_timer_reconfigure(p, 0); // virtual clock: attempt to follow frequency change preserving the phase + return res; +} + +static void +avr_timer_reset( + avr_io_t * port) +{ + avr_timer_t * p = (avr_timer_t *)port; + avr_timer_cancel_all_cycle_timers(p->io.avr, p, 0); + + // check to see if the comparators have a pin output. If they do, + // (try) to get the ioport corresponding IRQ and connect them + // they will automagically be triggered when the comparator raises + // it's own IRQ + for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) { + p->comp[compi].comp_cycles = 0; + + avr_ioport_getirq_t req = { + .bit = p->comp[compi].com_pin + }; + if (avr_ioctl(port->avr, AVR_IOCTL_IOPORT_GETIRQ_REGBIT, &req) > 0) { + // cool, got an IRQ + //printf("%s-%c COMP%c Connecting PIN IRQ %d\n", + // __func__, p->name, 'A'+compi, req.irq[0]->irq); + avr_connect_irq(&port->irq[TIMER_IRQ_OUT_COMP + compi], req.irq[0]); + } + } + + avr_irq_register_notify(port->irq + TIMER_IRQ_IN_ICP, avr_timer_irq_icp, p); + + avr_ioport_getirq_t req = { + .bit = p->icp + }; + if (avr_ioctl(port->avr, AVR_IOCTL_IOPORT_GETIRQ_REGBIT, &req) > 0) { + // cool, got an IRQ for the input capture pin + //printf("%s-%c ICP Connecting PIN IRQ %d\n", __func__, p->name, req.irq[0]->irq); + avr_connect_irq(req.irq[0], port->irq + TIMER_IRQ_IN_ICP); + } + p->ext_clock_flags &= ~(AVR_TIMER_EXTCLK_FLAG_STARTED | AVR_TIMER_EXTCLK_FLAG_TN | + AVR_TIMER_EXTCLK_FLAG_AS2 | AVR_TIMER_EXTCLK_FLAG_REVDIR); + +} + +static const char * irq_names[TIMER_IRQ_COUNT] = { + [TIMER_IRQ_OUT_PWM0] = "8>pwm0", + [TIMER_IRQ_OUT_PWM1] = "8>pwm1", + [TIMER_IRQ_OUT_PWM2] = "8>pwm2", + [TIMER_IRQ_IN_ICP] = "<icp", + [TIMER_IRQ_OUT_COMP + 0] = ">compa", + [TIMER_IRQ_OUT_COMP + 1] = ">compb", + [TIMER_IRQ_OUT_COMP + 2] = ">compc", +}; + +static avr_io_t _io = { + .kind = "timer", + .irq_names = irq_names, + .reset = avr_timer_reset, + .ioctl = avr_timer_ioctl, +}; + +void +avr_timer_init( + avr_t * avr, + avr_timer_t * p) +{ + p->io = _io; + + avr_register_io(avr, &p->io); + avr_register_vector(avr, &p->overflow); + avr_register_vector(avr, &p->icr); + + // allocate this module's IRQ + avr_io_setirqs(&p->io, AVR_IOCTL_TIMER_GETIRQ(p->name), TIMER_IRQ_COUNT, NULL); + + // marking IRQs as "filtered" means they don't propagate if the + // new value raised is the same as the last one.. in the case of the + // pwm value it makes sense not to bother. + p->io.irq[TIMER_IRQ_OUT_PWM0].flags |= IRQ_FLAG_FILTERED; + p->io.irq[TIMER_IRQ_OUT_PWM1].flags |= IRQ_FLAG_FILTERED; + p->io.irq[TIMER_IRQ_OUT_PWM2].flags |= IRQ_FLAG_FILTERED; + + if (p->wgm[0].reg) // these are not present on older AVRs + avr_register_io_write(avr, p->wgm[0].reg, avr_timer_write, p); + if (p->wgm[1].reg && + (p->wgm[1].reg != p->wgm[0].reg)) + avr_register_io_write(avr, p->wgm[1].reg, avr_timer_write, p); + if (p->wgm[2].reg && + (p->wgm[2].reg != p->wgm[0].reg) && + (p->wgm[2].reg != p->wgm[1].reg)) + avr_register_io_write(avr, p->wgm[2].reg, avr_timer_write, p); + if (p->wgm[3].reg && + (p->wgm[3].reg != p->wgm[0].reg) && + (p->wgm[3].reg != p->wgm[1].reg) && + (p->wgm[3].reg != p->wgm[2].reg)) + avr_register_io_write(avr, p->wgm[3].reg, avr_timer_write, p); + + avr_register_io_write(avr, p->cs[0].reg, avr_timer_write, p); + if (p->cs[1].reg && + (p->cs[1].reg != p->cs[0].reg)) + avr_register_io_write(avr, p->cs[1].reg, avr_timer_write, p); + if (p->cs[2].reg && + (p->cs[2].reg != p->cs[0].reg) && (p->cs[2].reg != p->cs[1].reg)) + avr_register_io_write(avr, p->cs[2].reg, avr_timer_write, p); + if (p->cs[3].reg && + (p->cs[3].reg != p->cs[0].reg) && + (p->cs[3].reg != p->cs[1].reg) && + (p->cs[3].reg != p->cs[2].reg)) + avr_register_io_write(avr, p->cs[3].reg, avr_timer_write, p); + + if (p->as2.reg) // as2 signifies timer/counter 2... therefore must check for register. + avr_register_io_write(avr, p->as2.reg, avr_timer_write, p); + + // this assumes all the "pending" interrupt bits are in the same + // register. Might not be true on all devices ? + avr_register_io_write(avr, p->overflow.raised.reg, avr_timer_write_pending, p); + + /* + * Even if the timer is 16 bits, we don't care to have watches on the + * high bytes because the datasheet says that the low address is always + * the trigger. + */ + for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) { + p->comp[compi].timer = p; + + avr_register_vector(avr, &p->comp[compi].interrupt); + + if (p->comp[compi].r_ocr) // not all timers have all comparators + avr_register_io_write(avr, p->comp[compi].r_ocr, avr_timer_write_ocr, &p->comp[compi]); + if (p->comp[compi].foc.reg) + avr_register_io_write(avr, p->comp[compi].foc.reg, avr_timer_write_foc, p); + } + avr_register_io_write(avr, p->r_tcnt, avr_timer_tcnt_write, p); + avr_register_io_read(avr, p->r_tcnt, avr_timer_tcnt_read, p); + + if (p->as2.reg) { + p->ext_clock_flags = AVR_TIMER_EXTCLK_FLAG_VIRT; + p->ext_clock = 32768.0f; + } else { + p->ext_clock_flags = 0; + p->ext_clock = 0.0f; + } +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_timer.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_timer.h new file mode 100644 index 0000000..837936c --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_timer.h @@ -0,0 +1,176 @@ +/* + avr_timer.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __AVR_TIMER_H__ +#define __AVR_TIMER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sim_avr.h" + +enum { + AVR_TIMER_COMPA = 0, + AVR_TIMER_COMPB, + AVR_TIMER_COMPC, + + AVR_TIMER_COMP_COUNT +}; + +enum { + TIMER_IRQ_OUT_PWM0 = 0, + TIMER_IRQ_OUT_PWM1, + TIMER_IRQ_OUT_PWM2, + TIMER_IRQ_IN_ICP, // input capture + TIMER_IRQ_OUT_COMP, // comparator pins output IRQ + + TIMER_IRQ_COUNT = TIMER_IRQ_OUT_COMP + AVR_TIMER_COMP_COUNT +}; + +// Get the internal IRQ corresponding to the INT +#define AVR_IOCTL_TIMER_GETIRQ(_name) AVR_IOCTL_DEF('t','m','r',(_name)) + +// add timer number/name (character) to set tracing flags +#define AVR_IOCTL_TIMER_SET_TRACE(_number) AVR_IOCTL_DEF('t','m','t',(_number)) +// enforce using virtual clock generator when external clock is chosen by firmware +#define AVR_IOCTL_TIMER_SET_VIRTCLK(_number) AVR_IOCTL_DEF('t','m','v',(_number)) +// set frequency of the virtual clock generator +#define AVR_IOCTL_TIMER_SET_FREQCLK(_number) AVR_IOCTL_DEF('t','m','f',(_number)) + +// Waveform generation modes +enum { + avr_timer_wgm_none = 0, // invalid mode + avr_timer_wgm_normal, + avr_timer_wgm_ctc, + avr_timer_wgm_pwm, + avr_timer_wgm_fast_pwm, + avr_timer_wgm_fc_pwm, +}; + +// Compare output modes +enum { + avr_timer_com_normal = 0,// Normal mode, OCnx disconnected + avr_timer_com_toggle, // Toggle OCnx on compare match + avr_timer_com_clear, // clear OCnx on compare match + avr_timer_com_set, // set OCnx on compare match + +}; + +enum { + avr_timer_wgm_reg_constant = 0, + avr_timer_wgm_reg_ocra, + avr_timer_wgm_reg_icr, +}; + +typedef struct avr_timer_wgm_t { + uint32_t top: 8, bottom: 8, size : 8, kind : 8; +} avr_timer_wgm_t; + +#define AVR_TIMER_EXTCLK_CHOOSE 0x80 // marker value for cs_div specifying ext clock selection +#define AVR_TIMER_EXTCLK_FLAG_TN 0x80 // Tn external clock chosen +#define AVR_TIMER_EXTCLK_FLAG_STARTED 0x40 // peripheral started +#define AVR_TIMER_EXTCLK_FLAG_REVDIR 0x20 // reverse counting (decrement) +#define AVR_TIMER_EXTCLK_FLAG_AS2 0x10 // asynchronous external clock chosen +#define AVR_TIMER_EXTCLK_FLAG_VIRT 0x08 // don't use the input pin, generate clock internally +#define AVR_TIMER_EXTCLK_FLAG_EDGE 0x01 // use the rising edge + +#define AVR_TIMER_WGM_NORMAL8() { .kind = avr_timer_wgm_normal, .size=8 } +#define AVR_TIMER_WGM_NORMAL16() { .kind = avr_timer_wgm_normal, .size=16 } +#define AVR_TIMER_WGM_CTC() { .kind = avr_timer_wgm_ctc, .top = avr_timer_wgm_reg_ocra } +#define AVR_TIMER_WGM_ICCTC() { .kind = avr_timer_wgm_ctc, .top = avr_timer_wgm_reg_icr } +#define AVR_TIMER_WGM_FASTPWM8() { .kind = avr_timer_wgm_fast_pwm, .size=8 } +#define AVR_TIMER_WGM_FASTPWM9() { .kind = avr_timer_wgm_fast_pwm, .size=9 } +#define AVR_TIMER_WGM_FASTPWM10() { .kind = avr_timer_wgm_fast_pwm, .size=10 } +#define AVR_TIMER_WGM_FCPWM8() { .kind = avr_timer_wgm_fc_pwm, .size=8 } +#define AVR_TIMER_WGM_FCPWM9() { .kind = avr_timer_wgm_fc_pwm, .size=9 } +#define AVR_TIMER_WGM_FCPWM10() { .kind = avr_timer_wgm_fc_pwm, .size=10 } +#define AVR_TIMER_WGM_OCPWM() { .kind = avr_timer_wgm_pwm, .top = avr_timer_wgm_reg_ocra } +#define AVR_TIMER_WGM_ICPWM() { .kind = avr_timer_wgm_pwm, .top = avr_timer_wgm_reg_icr } +#define AVR_TIMER_WGM_ICFASTPWM() { .kind = avr_timer_wgm_fast_pwm, .top = avr_timer_wgm_reg_icr } + +typedef struct avr_timer_comp_t { + avr_int_vector_t interrupt; // interrupt vector + struct avr_timer_t *timer; // parent timer + avr_io_addr_t r_ocr; // comparator register low byte + avr_io_addr_t r_ocrh; // comparator register hi byte + avr_regbit_t com; // comparator output mode registers + avr_regbit_t com_pin; // where comparator output is connected + uint64_t comp_cycles; + avr_regbit_t foc; // "force compare match" strobe +} avr_timer_comp_t, *avr_timer_comp_p; + +enum { + avr_timer_trace_ocr = (1 << 0), + avr_timer_trace_tcnt = (1 << 1), + + avr_timer_trace_compa = (1 << 8), + avr_timer_trace_compb = (1 << 9), + avr_timer_trace_compc = (1 << 10), +}; + +typedef struct avr_timer_t { + avr_io_t io; + char name; + uint32_t trace; // debug trace + + avr_regbit_t disabled; // bit in the PRR + + avr_io_addr_t r_tcnt, r_icr; + avr_io_addr_t r_tcnth, r_icrh; + + avr_regbit_t wgm[4]; + avr_timer_wgm_t wgm_op[16]; + avr_timer_wgm_t mode; + int wgm_op_mode_kind; + uint32_t wgm_op_mode_size; + + avr_regbit_t as2; // asynchronous clock 32khz + avr_regbit_t cs[4]; // specify control register bits choosing clock sourcre + uint8_t cs_div[16]; // translate control register value to clock prescaler (orders of 2 exponent) + uint32_t cs_div_value; + + avr_regbit_t ext_clock_pin; // external clock input pin, to link IRQs + uint8_t ext_clock_flags; // holds AVR_TIMER_EXTCLK_FLAG_ON, AVR_TIMER_EXTCLK_FLAG_EDGE and other ext. clock mode flags + float ext_clock; // external clock frequency, e.g. 32768Hz + + avr_regbit_t icp; // input capture pin, to link IRQs + avr_regbit_t ices; // input capture edge select + + avr_timer_comp_t comp[AVR_TIMER_COMP_COUNT]; + + avr_int_vector_t overflow; // overflow + avr_int_vector_t icr; // input capture + + uint64_t tov_cycles; // number of cycles from zero to overflow + float tov_cycles_fract; // fractional part for external clock with non int ratio to F_CPU + float phase_accumulator; + uint64_t tov_base; // MCU cycle when the last overflow occured; when clocked externally holds external clock count + uint16_t tov_top; // current top value to calculate tnct +} avr_timer_t; + +void avr_timer_init(avr_t * avr, avr_timer_t * port); + +#ifdef __cplusplus +}; +#endif + +#endif /*__AVR_TIMER_H__*/ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_twi.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_twi.c new file mode 100644 index 0000000..521c03c --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_twi.c @@ -0,0 +1,521 @@ +/* + avr_twi.c + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include "avr_twi.h" + +/* + * This block respectfully nicked straight out from the Atmel sample + * code for AVR315. Typos and all. + * There is no copyright notice on the original file. + */ +/**************************************************************************** + TWI State codes +****************************************************************************/ +// General TWI Master status codes +#define TWI_START 0x08 // START has been transmitted +#define TWI_REP_START 0x10 // Repeated START has been transmitted +#define TWI_ARB_LOST 0x38 // Arbitration lost + +// TWI Master Transmitter status codes +#define TWI_MTX_ADR_ACK 0x18 // SLA+W has been transmitted and ACK received +#define TWI_MTX_ADR_NACK 0x20 // SLA+W has been transmitted and NACK received +#define TWI_MTX_DATA_ACK 0x28 // Data byte has been transmitted and ACK received +#define TWI_MTX_DATA_NACK 0x30 // Data byte has been transmitted and NACK received + +// TWI Master Receiver status codes +#define TWI_MRX_ADR_ACK 0x40 // SLA+R has been transmitted and ACK received +#define TWI_MRX_ADR_NACK 0x48 // SLA+R has been transmitted and NACK received +#define TWI_MRX_DATA_ACK 0x50 // Data byte has been received and ACK transmitted +#define TWI_MRX_DATA_NACK 0x58 // Data byte has been received and NACK transmitted + +// TWI Slave Transmitter status codes +#define TWI_STX_ADR_ACK 0xA8 // Own SLA+R has been received; ACK has been returned +#define TWI_STX_ADR_ACK_M_ARB_LOST 0xB0 // Arbitration lost in SLA+R/W as Master; own SLA+R has been received; ACK has been returned +#define TWI_STX_DATA_ACK 0xB8 // Data byte in TWDR has been transmitted; ACK has been received +#define TWI_STX_DATA_NACK 0xC0 // Data byte in TWDR has been transmitted; NOT ACK has been received +#define TWI_STX_DATA_ACK_LAST_BYTE 0xC8 // Last data byte in TWDR has been transmitted (TWEA = �0�); ACK has been received + +// TWI Slave Receiver status codes +#define TWI_SRX_ADR_ACK 0x60 // Own SLA+W has been received ACK has been returned +#define TWI_SRX_ADR_ACK_M_ARB_LOST 0x68 // Arbitration lost in SLA+R/W as Master; own SLA+W has been received; ACK has been returned +#define TWI_SRX_GEN_ACK 0x70 // General call address has been received; ACK has been returned +#define TWI_SRX_GEN_ACK_M_ARB_LOST 0x78 // Arbitration lost in SLA+R/W as Master; General call address has been received; ACK has been returned +#define TWI_SRX_ADR_DATA_ACK 0x80 // Previously addressed with own SLA+W; data has been received; ACK has been returned +#define TWI_SRX_ADR_DATA_NACK 0x88 // Previously addressed with own SLA+W; data has been received; NOT ACK has been returned +#define TWI_SRX_GEN_DATA_ACK 0x90 // Previously addressed with general call; data has been received; ACK has been returned +#define TWI_SRX_GEN_DATA_NACK 0x98 // Previously addressed with general call; data has been received; NOT ACK has been returned +#define TWI_SRX_STOP_RESTART 0xA0 // A STOP condition or repeated START condition has been received while still addressed as Slave + +// TWI Miscellaneous status codes +#define TWI_NO_STATE 0xF8 // No relevant state information available; TWINT = �0� +#define TWI_BUS_ERROR 0x00 // Bus error due to an illegal START or STOP condition + +#define AVR_TWI_DEBUG 1 + +static inline void +_avr_twi_status_set( + avr_twi_t * p, + uint8_t v, + int interrupt) +{ + avr_regbit_setto_raw(p->io.avr, p->twsr, v); +#if AVR_TWI_DEBUG + AVR_TRACE(p->io.avr, "%s %02x\n", __func__, v); +#endif + avr_raise_irq(p->io.irq + TWI_IRQ_STATUS, v); + if (interrupt) + avr_raise_interrupt(p->io.avr, &p->twi); +} + +static __attribute__ ((unused)) inline uint8_t +_avr_twi_status_get( + avr_twi_t * p) +{ + return avr_regbit_get_raw(p->io.avr, p->twsr); +} + +static avr_cycle_count_t +avr_twi_set_state_timer( + struct avr_t * avr, + avr_cycle_count_t when, + void * param) +{ + avr_twi_t * p = (avr_twi_t *)param; + _avr_twi_status_set(p, p->next_twstate, 1); + p->next_twstate = 0; + return 0; +} + +// Quick exponent helper for integer values > 0. +static uint32_t _avr_twi_quick_exp(uint8_t base, uint8_t exp) +{ + uint32_t result = 1; + for (uint8_t i=exp; i>0; i--) + result *= base; + return result; +} + +/* + * This is supposed to trigger a timer whose duration is a multiple + * of 'twi' clock cycles, which should be derived from the prescaler + * (100khz, 400khz etc). + * Right now it cheats and uses one twi cycle == one usec. + */ + +static void +_avr_twi_delay_state( + avr_twi_t * p, + int twi_cycles, + uint8_t state) +{ + p->next_twstate = state; + uint8_t prescale = avr_regbit_get(p->io.avr, p->twps); + uint16_t bitrate = p->io.avr->data[p->r_twbr]; + uint32_t clockdiv = 16u+((bitrate<<1u)*_avr_twi_quick_exp(4,prescale)); + //One TWI cycle is "clockdiv" AVR Cycles. So we can wait in these directly. + // printf("Waiting %d cycles\n",clockdiv*twi_cycles); + avr_cycle_timer_register( + p->io.avr, twi_cycles*clockdiv, avr_twi_set_state_timer, p); +} + +static void +avr_twi_write( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_twi_t * p = (avr_twi_t *)param; + + uint8_t twen = avr_regbit_get(avr, p->twen); + uint8_t twsta = avr_regbit_get(avr, p->twsta); + uint8_t twsto = avr_regbit_get(avr, p->twsto); + uint8_t twint = avr_regbit_get(avr, p->twi.raised); + + avr_core_watch_write(avr, addr, v); +#if AVR_TWI_DEBUG + AVR_TRACE(avr, "%s %02x START:%d STOP:%d ACK:%d INT:%d TWSR:%02x (state %02x)\n", + __func__, v, + avr_regbit_get(avr, p->twsta), + avr_regbit_get(avr, p->twsto), + avr_regbit_get(avr, p->twea), + avr_regbit_get(avr, p->twi.raised), + avr_regbit_get_raw(p->io.avr, p->twsr), p->state); +#endif + if (twen != avr_regbit_get(avr, p->twen)) { + twen = !twen; + if (!twen) { // if we were running, now now are not + avr_regbit_clear(avr, p->twea); + avr_regbit_clear(avr, p->twsta); + avr_regbit_clear(avr, p->twsto); + avr_clear_interrupt(avr, &p->twi); + avr_core_watch_write(avr, p->r_twdr, 0xff); + _avr_twi_status_set(p, TWI_NO_STATE, 0); + p->state = 0; + p->peer_addr = 0; + } + AVR_TRACE(avr, "TWEN: %d\n", twen); + if (avr->data[p->r_twar]) { + AVR_TRACE(avr, "TWEN Slave: %02x&%02x\n", avr->data[p->r_twar] >> 1, avr->data[p->r_twamr] >> 1); + p->state |= TWI_COND_SLAVE; + } + } + if (!twen) + return; + + uint8_t cleared = avr_regbit_get(avr, p->twi.raised); + + /*int cleared = */ + avr_clear_interrupt_if(avr, &p->twi, twint); +// AVR_TRACE(avr, "cleared %d\n", cleared); + + if (!twsto && avr_regbit_get(avr, p->twsto)) { + // generate a stop condition +#if AVR_TWI_DEBUG + AVR_TRACE(avr, "<<<<< I2C stop\n"); +#endif + if (p->state) { // doing stuff + if (p->state & TWI_COND_START) { + avr_raise_irq(p->io.irq + TWI_IRQ_OUTPUT, + avr_twi_irq_msg(TWI_COND_STOP, p->peer_addr, 1)); + } + } + /* clear stop condition regardless of status */ + avr_regbit_clear(avr, p->twsto); + _avr_twi_status_set(p, TWI_NO_STATE, 0); + p->state = 0; + } + if (!twsta && avr_regbit_get(avr, p->twsta)) { +#if AVR_TWI_DEBUG + AVR_TRACE(avr, ">>>>> I2C %sstart\n", p->state & TWI_COND_START ? "RE" : ""); +#endif + // generate a start condition + if (p->state & TWI_COND_START) + _avr_twi_delay_state(p, 0, TWI_REP_START); + else + _avr_twi_delay_state(p, 0, TWI_START); + p->peer_addr = 0; + p->state = TWI_COND_START; + } + + int data = cleared && + !avr_regbit_get(avr, p->twsta) && + !avr_regbit_get(avr, p->twsto); + + if (!data) + return; + + int do_read = p->peer_addr & 1; + int do_ack = avr_regbit_get(avr, p->twea) != 0; + + if (p->state & TWI_COND_SLAVE) { + // writing or reading a byte + if (p->state & TWI_COND_ADDR) { +#if AVR_TWI_DEBUG + if (do_read) + AVR_TRACE(avr, "I2C slave READ byte\n"); + else + AVR_TRACE(avr, "I2C slave WRITE byte\n"); +#endif + if (do_read) { + if (p->state & TWI_COND_WRITE) { + avr_raise_irq(p->io.irq + TWI_IRQ_OUTPUT, + avr_twi_irq_msg(TWI_COND_READ | TWI_COND_ACK, p->peer_addr, avr->data[p->r_twdr])); + } +#if AVR_TWI_DEBUG + else + AVR_TRACE(avr, "I2C latch is not ready, do nothing\n"); +#endif + } else { + avr_raise_irq(p->io.irq + TWI_IRQ_OUTPUT, + avr_twi_irq_msg(TWI_COND_ACK, p->peer_addr, 0)); + } + avr_raise_irq(p->io.irq + TWI_IRQ_OUTPUT, + avr_twi_irq_msg(TWI_COND_ADDR + (do_ack ? TWI_COND_ACK : 0), p->peer_addr, avr->data[p->r_twdr])); + } else { // address, acknowledge it + p->state |= TWI_COND_ADDR; + avr_raise_irq(p->io.irq + TWI_IRQ_OUTPUT, + avr_twi_irq_msg( + TWI_COND_ADDR | + (do_ack ? TWI_COND_ACK : 0) | + (p->state & TWI_COND_WRITE ? TWI_COND_READ : 0), + p->peer_addr, avr->data[p->r_twdr])); + } + } else { + + // writing or reading a byte + if (p->state & TWI_COND_ADDR) { +#if AVR_TWI_DEBUG + if (do_read) + AVR_TRACE(avr, "I2C READ byte from %02x\n", p->peer_addr); + else + AVR_TRACE(avr, "I2C WRITE byte %02x to %02x\n", avr->data[p->r_twdr], p->peer_addr); +#endif + // a normal data byte + uint8_t msgv = do_read ? TWI_COND_READ : TWI_COND_WRITE; + + if (do_ack) + msgv |= TWI_COND_ACK; + + p->state &= ~TWI_COND_ACK; // clear ACK bit + + AVR_TRACE(avr, "state %02x want %02x\n", p->state, msgv); + // if the latch is ready... as set by writing/reading the TWDR + if (p->state & msgv) { + + // we send an IRQ and we /expect/ a slave to reply + // immediately via an IRQ to set the COND_ACK bit + // otherwise it's assumed it's been nacked... + avr_raise_irq(p->io.irq + TWI_IRQ_OUTPUT, + avr_twi_irq_msg(msgv, p->peer_addr, avr->data[p->r_twdr])); + + if (do_read) { // read ? + _avr_twi_delay_state(p, 9, + msgv & TWI_COND_ACK ? + TWI_MRX_DATA_ACK : TWI_MRX_DATA_NACK); + } else { + _avr_twi_delay_state(p, 9, + p->state & TWI_COND_ACK ? + TWI_MTX_DATA_ACK : TWI_MTX_DATA_NACK); + } + } +#if AVR_TWI_DEBUG + else + AVR_TRACE(avr, "I2C latch is not ready, do nothing\n"); +#endif + } else if (p->state) { +#if AVR_TWI_DEBUG + AVR_TRACE(avr, "I2C Master address %02x\n", avr->data[p->r_twdr]); +#endif + // send the address + p->state |= TWI_COND_ADDR; + p->peer_addr = avr->data[p->r_twdr]; + p->state &= ~TWI_COND_ACK; // clear ACK bit + + // we send an IRQ and we /expect/ a slave to reply + // immediately via an IRQ tp set the COND_ACK bit + // otherwise it's assumed it's been nacked... + avr_raise_irq(p->io.irq + TWI_IRQ_OUTPUT, + avr_twi_irq_msg(TWI_COND_START, p->peer_addr, 0)); + + if (p->peer_addr & 1) { // read ? + p->state |= TWI_COND_READ; // always allow read to start with + _avr_twi_delay_state(p, 9, + p->state & TWI_COND_ACK ? + TWI_MRX_ADR_ACK : TWI_MRX_ADR_NACK); + } else { + if(p->state & TWI_COND_ADDR){ + _avr_twi_delay_state(p, 0, + p->state & TWI_COND_ACK ? + TWI_MTX_ADR_ACK : TWI_MTX_ADR_NACK); + }else{ + _avr_twi_delay_state(p, 9, + p->state & TWI_COND_ACK ? + TWI_MTX_DATA_ACK : TWI_MTX_DATA_NACK); + } + } + } + p->state &= ~TWI_COND_WRITE; + } +} + +/* + * Write data to the latch, tell the system we have something + * to send next + */ +static void +avr_twi_write_data( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_twi_t * p = (avr_twi_t *)param; + + avr_core_watch_write(avr, addr, v); + // tell system we have something in the write latch + p->state |= TWI_COND_WRITE; +} + +/* + * Read data from the latch, tell the system can receive a new byte + */ +static uint8_t +avr_twi_read_data( + struct avr_t * avr, + avr_io_addr_t addr, + void * param) +{ + avr_twi_t * p = (avr_twi_t *)param; + + // tell system we can receive another byte + p->state |= TWI_COND_READ; + return avr->data[p->r_twdr]; +} + +/* + * prevent code from rewriting out status bits, since we actually use them! + */ +static void +avr_twi_write_status( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_twi_t * p = (avr_twi_t *)param; + uint8_t sr = avr_regbit_get(avr, p->twsr); + uint8_t c = avr_regbit_get(avr, p->twps); + + avr_core_watch_write(avr, addr, v); + avr_regbit_setto(avr, p->twsr, sr); // force restore + + if (c != avr_regbit_get(avr, p->twps)) { + // prescaler bits changed... + } +} + +static void +avr_twi_irq_input( + struct avr_irq_t * irq, + uint32_t value, + void * param) +{ + avr_twi_t * p = (avr_twi_t *)param; + avr_t * avr = p->io.avr; + + // check to see if we are enabled + if (!avr_regbit_get(avr, p->twen)) + return; + avr_twi_msg_irq_t msg; + msg.u.v = value; + + AVR_TRACE(avr, "%s %08x\n", __func__, value); + + // receiving an attempt at waking a slave + if (msg.u.twi.msg & TWI_COND_START) { + p->state = 0; + p->peer_addr = 0; + if (msg.u.twi.msg & TWI_COND_ADDR) { + uint8_t mask = ~avr->data[p->r_twamr] >> 1; + AVR_TRACE(avr, "I2C slave start %2x (want %02x&%02x)\n", + msg.u.twi.addr, avr->data[p->r_twar] >> 1, mask); + p->peer_addr = msg.u.twi.addr & mask; + if (p->peer_addr == ((avr->data[p->r_twar] >> 1) & mask)) { + // address match, we're talking + p->state = TWI_COND_SLAVE; + // INVERSE logic here + if (!(msg.u.twi.msg & TWI_COND_WRITE)) + p->peer_addr |= 1; + _avr_twi_delay_state(p, 9, + msg.u.twi.msg & TWI_COND_WRITE ? + TWI_SRX_ADR_ACK : TWI_STX_ADR_ACK ); + } + } else { + // "general call" address + AVR_TRACE(avr, "I2C slave start without address?\n"); + if (avr->data[p->r_twar] & 1) { + // TODO + } + } + } + if (msg.u.twi.msg & TWI_COND_STOP) { + _avr_twi_delay_state(p, 9, + msg.u.twi.msg & TWI_COND_WRITE ? + TWI_SRX_ADR_ACK : TWI_STX_ADR_ACK ); + } + // receiving an acknowledge bit + if (msg.u.twi.msg & TWI_COND_ACK) { +#if AVR_TWI_DEBUG + AVR_TRACE(avr, "I2C received ACK:%d\n", msg.u.twi.data & 1); +#endif + if (msg.u.twi.data & 1) + p->state |= TWI_COND_ACK; + else + p->state &= ~TWI_COND_ACK; + } + if (p->state & TWI_COND_SLAVE) { + if (msg.u.twi.msg & TWI_COND_WRITE) { + avr->data[p->r_twdr] = msg.u.twi.data; + _avr_twi_delay_state(p, 9, TWI_SRX_ADR_DATA_ACK ); + } + } else { + // receive a data byte from a slave + if (msg.u.twi.msg & TWI_COND_READ) { +#if AVR_TWI_DEBUG + AVR_TRACE(avr, "I2C received %02x\n", msg.u.twi.data); +#endif + avr->data[p->r_twdr] = msg.u.twi.data; + } + } +} + +void avr_twi_reset(struct avr_io_t *io) +{ + avr_twi_t * p = (avr_twi_t *)io; + avr_irq_register_notify(p->io.irq + TWI_IRQ_INPUT, avr_twi_irq_input, p); + p->state = p->peer_addr = 0; + avr_regbit_setto_raw(p->io.avr, p->twsr, TWI_NO_STATE); +} + +static const char * irq_names[TWI_IRQ_COUNT] = { + [TWI_IRQ_INPUT] = "8<input", + [TWI_IRQ_OUTPUT] = "32>output", + [TWI_IRQ_STATUS] = "8>status", +}; + +static avr_io_t _io = { + .kind = "twi", + .reset = avr_twi_reset, + .irq_names = irq_names, +}; + +void avr_twi_init(avr_t * avr, avr_twi_t * p) +{ + p->io = _io; + avr_register_io(avr, &p->io); + avr_register_vector(avr, &p->twi); + + //printf("%s TWI%c init\n", __FUNCTION__, p->name); + + // allocate this module's IRQ + avr_io_setirqs(&p->io, AVR_IOCTL_TWI_GETIRQ(p->name), TWI_IRQ_COUNT, NULL); + + avr_register_io_write(avr, p->twen.reg, avr_twi_write, p); + avr_register_io_write(avr, p->r_twdr, avr_twi_write_data, p); + avr_register_io_read(avr, p->r_twdr, avr_twi_read_data, p); + avr_register_io_write(avr, p->twsr.reg, avr_twi_write_status, p); +} + +uint32_t +avr_twi_irq_msg( + uint8_t msg, + uint8_t addr, + uint8_t data) +{ + avr_twi_msg_irq_t _msg = { + .u.twi.msg = msg, + .u.twi.addr = addr, + .u.twi.data = data, + }; + return _msg.u.v; +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_twi.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_twi.h new file mode 100644 index 0000000..8b37ba3 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_twi.h @@ -0,0 +1,116 @@ +/* + avr_twi.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __AVR_TWI_H__ +#define __AVR_TWI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sim_avr.h" + +//#include "sim_twi.h" + +enum { + TWI_IRQ_INPUT = 0, + TWI_IRQ_OUTPUT, + TWI_IRQ_STATUS, + TWI_IRQ_COUNT +}; + +enum { + TWI_COND_START = (1 << 0), + TWI_COND_STOP = (1 << 1), + TWI_COND_ADDR = (1 << 2), + TWI_COND_ACK = (1 << 3), + TWI_COND_WRITE = (1 << 4), + TWI_COND_READ = (1 << 5), + // internal state, do not use in irq messages + TWI_COND_SLAVE = (1 << 6), +}; + +typedef struct avr_twi_msg_t { + uint32_t unused : 8, + msg : 8, + addr : 8, + data : 8; +} avr_twi_msg_t; + +typedef struct avr_twi_msg_irq_t { + union { + uint32_t v; + avr_twi_msg_t twi; + } u; +} avr_twi_msg_irq_t; + +// add port number to get the real IRQ +#define AVR_IOCTL_TWI_GETIRQ(_name) AVR_IOCTL_DEF('t','w','i',(_name)) + +typedef struct avr_twi_t { + avr_io_t io; + char name; + + avr_regbit_t disabled; // bit in the PRR + + avr_io_addr_t r_twbr; // bit rate register + avr_io_addr_t r_twcr; // control register + avr_io_addr_t r_twsr; // status register + avr_io_addr_t r_twar; // address register (slave) + avr_io_addr_t r_twamr; // address mask register + avr_io_addr_t r_twdr; // data register + + avr_regbit_t twen; // twi enable bit + avr_regbit_t twea; // enable acknowledge bit + avr_regbit_t twsta; // start condition + avr_regbit_t twsto; // stop condition + avr_regbit_t twwc; // write collision + + avr_regbit_t twsr; // status registers, (5 bits) + avr_regbit_t twps; // prescaler bits (2 bits) + + avr_int_vector_t twi; // twi interrupt + + uint8_t state; + uint8_t peer_addr; + uint8_t next_twstate; +} avr_twi_t; + +void +avr_twi_init( + avr_t * avr, + avr_twi_t * port); + +/* + * Create a message value for twi including the 'msg' bitfield, + * 'addr' and data. This value is what is sent as the IRQ value + */ +uint32_t +avr_twi_irq_msg( + uint8_t msg, + uint8_t addr, + uint8_t data); + +#ifdef __cplusplus +}; +#endif + +#endif /*__AVR_TWI_H__*/ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_uart.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_uart.c new file mode 100644 index 0000000..25b6fe6 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_uart.c @@ -0,0 +1,546 @@ +/* + avr_uart.c + + Handles UART access + Right now just handle "write" to the serial port at any speed + and printf to the console when '\n' is written. + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifdef NO_COLOR + #define FONT_GREEN + #define FONT_DEFAULT +#else + #define FONT_GREEN "\e[32m" + #define FONT_DEFAULT "\e[0m" +#endif + +#include <stdio.h> +#include <unistd.h> +#include <stdint.h> +#include <stdlib.h> +#include "avr_uart.h" +#include "sim_hex.h" +#include "sim_time.h" +#include "sim_gdb.h" + +//#define TRACE(_w) _w +#ifndef TRACE +#define TRACE(_w) +#endif + +DEFINE_FIFO(uint16_t, uart_fifo); + +static inline void +avr_uart_clear_interrupt( + avr_t * avr, + avr_int_vector_t * vector) +{ + if (!vector->vector) + return; + // clear the interrupt flag even it's 'sticky' + if (avr_regbit_get(avr, vector->raised)) + avr_clear_interrupt_if(avr, vector, 0); + if (avr_regbit_get(avr, vector->raised)) + avr_regbit_clear(avr, vector->raised); +} + +static avr_cycle_count_t +avr_uart_txc_raise( + struct avr_t * avr, + avr_cycle_count_t when, + void * param) +{ + avr_uart_t * p = (avr_uart_t *)param; + if (p->tx_cnt) { + // Even if the interrupt is disabled, still raise the TXC flag + if (p->tx_cnt == 1) + avr_raise_interrupt(avr, &p->txc); + p->tx_cnt--; + } + if (p->udrc.vector) {// UDRE is disabled in the LIN mode + if (p->tx_cnt) { + if (avr_regbit_get(avr, p->udrc.raised)) { + avr_uart_clear_interrupt(avr, &p->udrc); + } + } else { + if (avr_regbit_get(avr, p->txen)) { + // Even if the interrupt is disabled, still raise the UDRE flag + avr_raise_interrupt(avr, &p->udrc); + if (!avr_regbit_get(avr, p->udrc.enable)) { + return 0; //polling mode: stop TX pump + } else // udrc (alias udre) should be rased repeatedly while output buffer is empty + return when + p->cycles_per_byte; + } else + return 0; // transfer disabled: stop TX pump + } + } + if (p->tx_cnt) + return when + p->cycles_per_byte; + return 0; // stop TX pump +} + +static avr_cycle_count_t +avr_uart_rxc_raise( + struct avr_t * avr, + avr_cycle_count_t when, + void * param) +{ + avr_uart_t * p = (avr_uart_t *)param; + if (avr_regbit_get(avr, p->rxen)) { + // rxc should be rased continiosly untill input buffer is empty + if (!uart_fifo_isempty(&p->input)) { + if (!avr_regbit_get(avr, p->rxc.raised)) { + p->rxc_raise_time = when; + p->rx_cnt = 0; + } + avr_raise_interrupt(avr, &p->rxc); + return when + p->cycles_per_byte; + } + } + return 0; +} + +static uint8_t +avr_uart_status_read( + struct avr_t * avr, + avr_io_addr_t addr, + void * param) +{ + avr_uart_t * p = (avr_uart_t *)param; + + if (addr == p->fe.reg) { + if (!uart_fifo_isempty(&p->input)) { + uint16_t d = uart_fifo_read_at(&p->input, 0); + + uint8_t st = avr->data[addr]; + + st &= ~(p->fe.mask << p->fe.bit); + if (d & UART_INPUT_FE) { + st |= p->fe.mask << p->fe.bit; + } + + avr->data[addr] = st; + } + } + + uint8_t v = avr_core_watch_read(avr, addr); + + if (addr == p->rxc.raised.reg) { + //static uint8_t old = 0xff; if (v != old) printf("UCSRA read %02x\n", v); old = v; + // + // if RX is enabled, and there is nothing to read, and + // the AVR core is reading this register, it's probably + // to poll the RXC TXC flag and spinloop + // so here we introduce a usleep to make it a bit lighter + // on CPU and let data arrive + // + uint8_t ri = !avr_regbit_get(avr, p->rxen) || !avr_regbit_get(avr, p->rxc.raised); + uint8_t ti = !avr_regbit_get(avr, p->txen) || !avr_regbit_get(avr, p->txc.raised); + + if (p->flags & AVR_UART_FLAG_POLL_SLEEP) { + + if (ri && ti) + usleep(1); + } + // if reception is idle and the fifo is empty, tell whomever there is room + if (avr_regbit_get(avr, p->rxen) && uart_fifo_isempty(&p->input)) { + avr_raise_irq(p->io.irq + UART_IRQ_OUT_XOFF, 0); + avr_raise_irq(p->io.irq + UART_IRQ_OUT_XON, 1); + } + } + + return v; +} + +static uint8_t +avr_uart_read( + struct avr_t * avr, + avr_io_addr_t addr, + void * param) +{ + avr_uart_t * p = (avr_uart_t *)param; + uint8_t v = 0; + + if (!avr_regbit_get(avr, p->rxen) || + !avr_regbit_get(avr, p->rxc.raised) // rxc flag not raised - nothing to read! + ) { + AVR_LOG(avr, LOG_TRACE, "UART%c: attempt to read empty rx buffer\n", p->name); + avr->data[addr] = 0; + // made to trigger potential watchpoints + avr_core_watch_read(avr, addr); + //return 0; + goto avr_uart_read_check; + } + if (!uart_fifo_isempty(&p->input)) { // probably redundant check + v = (uint8_t)uart_fifo_read(&p->input) & 0xFF; + p->rx_cnt++; + if ((p->rx_cnt > 1) && // UART actually has 2-character rx buffer + ((avr->cycle-p->rxc_raise_time)/p->rx_cnt < p->cycles_per_byte)) { + // prevent the firmware from reading input characters with non-realistic high speed + avr_uart_clear_interrupt(avr, &p->rxc); + p->rx_cnt = 0; + } + } else { + AVR_LOG(avr, LOG_TRACE, "UART%c: BUG: rxc raised with empty rx buffer\n", p->name); + } + +// TRACE(printf("UART read %02x %s\n", v, uart_fifo_isempty(&p->input) ? "EMPTY!" : "");) + avr->data[addr] = v; + // made to trigger potential watchpoints + v = avr_core_watch_read(avr, addr); + +avr_uart_read_check: + if (uart_fifo_isempty(&p->input)) { + avr_cycle_timer_cancel(avr, avr_uart_rxc_raise, p); + avr_uart_clear_interrupt(avr, &p->rxc); + avr_raise_irq(p->io.irq + UART_IRQ_OUT_XOFF, 0); + avr_raise_irq(p->io.irq + UART_IRQ_OUT_XON, 1); + } + if (!uart_fifo_isfull(&p->input)) { + avr_regbit_clear(avr, p->dor); + } + + return v; +} + +static void +avr_uart_baud_write( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_uart_t * p = (avr_uart_t *)param; + avr_core_watch_write(avr, addr, v); + uint32_t val = avr_regbit_get(avr,p->ubrrl) | (avr_regbit_get(avr,p->ubrrh) << 8); + + const int databits[] = { 5,6,7,8, /* 'reserved', assume 8 */8,8,8, 9 }; + int db = databits[avr_regbit_get(avr, p->ucsz) | (avr_regbit_get(avr, p->ucsz2) << 2)]; + int sb = 1 + avr_regbit_get(avr, p->usbs); + int word_size = 1 /* start */ + db /* data bits */ + 1 /* parity */ + sb /* stops */; + int cycles_per_bit = (val+1)*8; + if (!avr_regbit_get(avr, p->u2x)) + cycles_per_bit *= 2; + double baud = ((double)avr->frequency) / cycles_per_bit; // can be less than 1 + p->cycles_per_byte = cycles_per_bit * word_size; + + AVR_LOG(avr, LOG_TRACE, "UART: %c configured to %04x = %.4f bps (x%d), %d data %d stop\n", + p->name, val, baud, avr_regbit_get(avr, p->u2x)?2:1, db, sb); + AVR_LOG(avr, LOG_TRACE, "UART: Roughly %d usec per byte\n", + avr_cycles_to_usec(avr, p->cycles_per_byte)); +} + +static void +avr_uart_udr_write( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_uart_t * p = (avr_uart_t *)param; + + // The byte to be sent should NOT be written there, + // the value written could never be read back. + //avr_core_watch_write(avr, addr, v); + if (avr->gdb) { + avr_gdb_handle_watchpoints(avr, addr, AVR_GDB_WATCH_WRITE); + } + + //avr_cycle_timer_cancel(avr, avr_uart_txc_raise, p); // synchronize tx pump + if (p->udrc.vector && avr_regbit_get(avr, p->udrc.raised)) { + avr_uart_clear_interrupt(avr, &p->udrc); + } + + if (p->flags & AVR_UART_FLAG_STDIO) { + const int maxsize = 256; + if (!p->stdio_out) + p->stdio_out = malloc(maxsize); + p->stdio_out[p->stdio_len++] = v < ' ' ? '.' : v; + p->stdio_out[p->stdio_len] = 0; + if (v == '\n' || p->stdio_len == maxsize) { + p->stdio_len = 0; + AVR_LOG(avr, LOG_OUTPUT, + FONT_GREEN "%s\n" FONT_DEFAULT, p->stdio_out); + } + } + TRACE(printf("UDR%c(%02x) = %02x\n", p->name, addr, v);) + // tell other modules we are "outputting" a byte + if (avr_regbit_get(avr, p->txen)) { + avr_raise_irq(p->io.irq + UART_IRQ_OUTPUT, v); + p->tx_cnt++; + if (p->tx_cnt > 2) // AVR actually has 1-character UART tx buffer, plus shift register + AVR_LOG(avr, LOG_TRACE, + "UART%c: tx buffer overflow %d\n", + p->name, (int)p->tx_cnt); + if (avr_cycle_timer_status(avr, avr_uart_txc_raise, p) == 0) + avr_cycle_timer_register(avr, p->cycles_per_byte, + avr_uart_txc_raise, p); // start the tx pump + } +} + + +static void +avr_uart_write( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_uart_t * p = (avr_uart_t *)param; + + uint8_t masked_v = v; + uint8_t clear_txc = 0; + uint8_t clear_rxc = 0; + + // exclude these locations from direct write: + if (p->udrc.raised.reg == addr) { + masked_v &= ~(p->udrc.raised.mask << p->udrc.raised.bit); + masked_v |= avr_regbit_get_raw(avr, p->udrc.raised); + } + if (p->txc.raised.reg == addr) { + uint8_t mask = p->txc.raised.mask << p->txc.raised.bit; + masked_v &= ~(mask); + masked_v |= avr_regbit_get_raw(avr, p->txc.raised); + // it can be cleared by writing a one to its bit location + if (v & mask) + clear_txc = 1; + } + if (p->rxc.raised.reg == addr) { + uint8_t mask = p->rxc.raised.mask << p->rxc.raised.bit; + masked_v &= ~(mask); + masked_v |= avr_regbit_get_raw(avr, p->rxc.raised); + if (!p->udrc.vector) { + // In the LIN mode it can be cleared by writing a one to its bit location + if (v & mask) + clear_rxc = 1; + } + } + // mainly to prevent application to confuse itself + // by writing something there and reading it back: + if (p->fe.reg == addr) { + masked_v &= ~(p->fe.mask << p->fe.bit); + masked_v |= avr_regbit_get_raw(avr, p->fe); + } + if (p->dor.reg == addr) { + masked_v &= ~(p->dor.mask << p->dor.bit); + //masked_v |= avr_regbit_get_raw(avr, p->dor); + } + if (p->upe.reg == addr) { + masked_v &= ~(p->upe.mask << p->upe.bit); + masked_v |= avr_regbit_get_raw(avr, p->upe); + } + if (p->rxb8.reg == addr) { + masked_v &= ~(p->rxb8.mask << p->rxb8.bit); + masked_v |= avr_regbit_get_raw(avr, p->rxb8); + } + + uint8_t txen = avr_regbit_get(avr, p->txen); + uint8_t rxen = avr_regbit_get(avr, p->rxen); + uint8_t udrce = avr_regbit_get(avr, p->udrc.enable); + // Now write whatever bits could be writen directly. + // It is necessary anyway, to trigger potential watchpoints. + avr_core_watch_write(avr, addr, masked_v); + uint8_t new_txen = avr_regbit_get(avr, p->txen); + uint8_t new_rxen = avr_regbit_get(avr, p->rxen); + uint8_t new_udrce = avr_regbit_get(avr, p->udrc.enable); + if (p->udrc.vector && (!udrce && new_udrce) && new_txen) { + // If enabling the UDRC (alias is UDRE) interrupt, raise it immediately if FIFO is empty. + // If the FIFO is not empty (clear timer is flying) we don't + // need to raise the interrupt, it will happen when the timer + // is fired. + if (avr_cycle_timer_status(avr, avr_uart_txc_raise, p) == 0) + avr_raise_interrupt(avr, &p->udrc); + } + if (clear_txc) + avr_uart_clear_interrupt(avr, &p->txc); + if (clear_rxc) + avr_uart_clear_interrupt(avr, &p->rxc); + + ///TODO: handle the RxD & TxD pins function override + + if (new_rxen != rxen) { + if (new_rxen) { + if (uart_fifo_isempty(&p->input)) { + // if reception is enabled and the fifo is empty, tell whomever there is room + avr_raise_irq(p->io.irq + UART_IRQ_OUT_XOFF, 0); + avr_raise_irq(p->io.irq + UART_IRQ_OUT_XON, 1); + } + } else { + avr_raise_irq(p->io.irq + UART_IRQ_OUT_XOFF, 1); + avr_cycle_timer_cancel(avr, avr_uart_rxc_raise, p); + // flush the Receive Buffer + uart_fifo_reset(&p->input); + // clear the rxc interrupt flag + avr_uart_clear_interrupt(avr, &p->rxc); + } + } + if (new_txen != txen) { + if (p->udrc.vector && !new_txen) { + avr_uart_clear_interrupt(avr, &p->udrc); + } else { + avr_regbit_set(avr, p->udrc.raised); + } + } +} + +static void +avr_uart_irq_input( + struct avr_irq_t * irq, + uint32_t value, + void * param) +{ + avr_uart_t * p = (avr_uart_t *)param; + avr_t * avr = p->io.avr; + + // check to see if receiver is enabled + if (!avr_regbit_get(avr, p->rxen)) + return; + + // reserved/not implemented: + //avr_regbit_clear(avr, p->fe); + //avr_regbit_clear(avr, p->upe); + //avr_regbit_clear(avr, p->rxb8); + + if (uart_fifo_isempty(&p->input) && + (avr_cycle_timer_status(avr, avr_uart_rxc_raise, p) == 0) + ) { + avr_cycle_timer_register(avr, p->cycles_per_byte, avr_uart_rxc_raise, p); // start the rx pump + p->rx_cnt = 0; + avr_regbit_clear(avr, p->dor); + } else if (uart_fifo_isfull(&p->input)) { + avr_regbit_setto(avr, p->dor, 1); + } + if (!avr_regbit_get(avr, p->dor)) { // otherwise newly received character must be rejected + uart_fifo_write(&p->input, value); // add to fifo + } else { + AVR_LOG(avr, LOG_ERROR, "UART%c: %s: RX buffer overrun, lost char=%c=0x%02X\n", p->name, __func__, + (char)value, (uint8_t)value ); + } + + TRACE(printf("UART IRQ in %02x (%d/%d) %s\n", value, p->input.read, p->input.write, uart_fifo_isfull(&p->input) ? "FULL!!" : "");) + + if (uart_fifo_isfull(&p->input)) + avr_raise_irq(p->io.irq + UART_IRQ_OUT_XOFF, 1); +} + + +void +avr_uart_reset( + struct avr_io_t *io) +{ + avr_uart_t * p = (avr_uart_t *)io; + avr_t * avr = p->io.avr; + if (p->udrc.vector) { + avr_regbit_set(avr, p->udrc.raised); + avr_regbit_clear(avr, p->dor); + } + avr_uart_clear_interrupt(avr, &p->txc); + avr_uart_clear_interrupt(avr, &p->rxc); + avr_irq_register_notify(p->io.irq + UART_IRQ_INPUT, avr_uart_irq_input, p); + avr_cycle_timer_cancel(avr, avr_uart_rxc_raise, p); + avr_cycle_timer_cancel(avr, avr_uart_txc_raise, p); + uart_fifo_reset(&p->input); + p->tx_cnt = 0; + + avr_regbit_set(avr, p->ucsz); + avr_regbit_clear(avr, p->ucsz2); + + // DEBUG allow printf without fiddling with enabling the uart + avr_regbit_set(avr, p->txen); + p->cycles_per_byte = avr_usec_to_cycles(avr, 100); +} + +static int +avr_uart_ioctl( + struct avr_io_t * port, + uint32_t ctl, + void * io_param) +{ + avr_uart_t * p = (avr_uart_t *)port; + int res = -1; + + if (!io_param) + return res; + + if (ctl == AVR_IOCTL_UART_SET_FLAGS(p->name)) { + p->flags = *(uint32_t*)io_param; + res = 0; + } + if (ctl == AVR_IOCTL_UART_GET_FLAGS(p->name)) { + *(uint32_t*)io_param = p->flags; + res = 0; + } + + return res; +} + +static const char * irq_names[UART_IRQ_COUNT] = { + [UART_IRQ_INPUT] = "8<in", + [UART_IRQ_OUTPUT] = "8>out", + [UART_IRQ_OUT_XON] = ">xon", + [UART_IRQ_OUT_XOFF] = ">xoff", +}; + +static avr_io_t _io = { + .kind = "uart", + .reset = avr_uart_reset, + .ioctl = avr_uart_ioctl, + .irq_names = irq_names, +}; + +void +avr_uart_init( + avr_t * avr, + avr_uart_t * p) +{ + p->io = _io; + +// printf("%s UART%c UDR=%02x\n", __FUNCTION__, p->name, p->r_udr); + + p->flags = AVR_UART_FLAG_POLL_SLEEP|AVR_UART_FLAG_STDIO; + + avr_register_io(avr, &p->io); + avr_register_vector(avr, &p->rxc); + avr_register_vector(avr, &p->txc); + avr_register_vector(avr, &p->udrc); + + // allocate this module's IRQ + avr_io_setirqs(&p->io, AVR_IOCTL_UART_GETIRQ(p->name), UART_IRQ_COUNT, NULL); + // Only call callbacks when the value change... + p->io.irq[UART_IRQ_OUT_XOFF].flags |= IRQ_FLAG_FILTERED; + + avr_register_io_write(avr, p->r_udr, avr_uart_udr_write, p); + avr_register_io_read(avr, p->r_udr, avr_uart_read, p); + + // status bits + // monitor code that reads the rxc flag, and delay it a bit + avr_register_io_read(avr, p->rxc.raised.reg, avr_uart_status_read, p); + if (p->fe.reg != p->rxc.raised.reg) + avr_register_io_read(avr, p->fe.reg, avr_uart_status_read, p); + + if (p->udrc.vector) + avr_register_io_write(avr, p->udrc.enable.reg, avr_uart_write, p); + if (p->r_ucsra) + avr_register_io_write(avr, p->r_ucsra, avr_uart_write, p); + if (p->ubrrl.reg) + avr_register_io_write(avr, p->ubrrl.reg, avr_uart_baud_write, p); + avr_register_io_write(avr, p->rxen.reg, avr_uart_write, p); +} + diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_uart.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_uart.h new file mode 100644 index 0000000..107359e --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_uart.h @@ -0,0 +1,229 @@ +/* + avr_uart.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __AVR_UART_H__ +#define __AVR_UART_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sim_avr.h" + +#include "fifo_declare.h" + +DECLARE_FIFO(uint16_t, uart_fifo, 64); + +/* + * The method of "connecting" the the UART from external code is to use 4 IRQS. + * The easy one is UART->YOU, where you will be called with the byte every time + * the AVR firmware sends one. Do whatever you like with it. + * + * The slightly more tricky one is the INPUT part. Since the AVR is quite a bit + * slower than your code most likely, there is a way for the AVR UART to tell + * you to "pause" sending it bytes when its own input buffer is full. + * So, the UART will send XON to you when its fifo is empty, XON means you can + * send as many bytes as you have until XOFF is sent. Note that these are two + * IRQs because you /will/ be called with XOFF when sending a byte in INPUT... + * So it's a reentrant process. + * + * When XOFF has been called, do not send any new bytes, they would be dropped. + * Instead wait for XON again and continue. + * See examples/parts/uart_udp.c for a full implementation + * + * Pseudo code: + * + * volatile int off = 0; + * void irq_xon() + * { + * off = 0; + * while (!off && bytes_left) + * avr_raise_irq(UART_IRQ_INPUT, a_byte); + * } + * void irq_xoff() + * { + * off = 1; + * } + * + */ +enum { + UART_IRQ_INPUT = 0, + UART_IRQ_OUTPUT, + UART_IRQ_OUT_XON, // signaled (continuously) when input fifo is not full + UART_IRQ_OUT_XOFF, // signaled when input fifo IS full + UART_IRQ_COUNT +}; + +enum { + UART_INPUT_FE = 0x8000 // framing error +}; + +// add port number to get the real IRQ +#define AVR_IOCTL_UART_GETIRQ(_name) AVR_IOCTL_DEF('u','a','r',(_name)) + +enum { + // the uart code monitors for firmware that poll on + // reception registers, and can do an atomic usleep() + // if it's detected, this helps regulating CPU + AVR_UART_FLAG_POOL_SLEEP = (1 << 0), + AVR_UART_FLAG_POLL_SLEEP = (1 << 0), // to replace pool_sleep + AVR_UART_FLAG_STDIO = (1 << 1), // print lines on the console +}; + +typedef struct avr_uart_t { + avr_io_t io; + char name; + avr_regbit_t disabled; // bit in the PRR + + avr_io_addr_t r_udr; + avr_io_addr_t r_ucsra; + avr_io_addr_t r_ucsrb; + avr_io_addr_t r_ucsrc; + + avr_regbit_t rxen; // receive enabled + avr_regbit_t txen; // transmit enable + avr_regbit_t u2x; // double UART speed + avr_regbit_t usbs; // stop bits + avr_regbit_t ucsz; // data bits + avr_regbit_t ucsz2; // data bits, continued + + // read-only bits (just to mask it out) + avr_regbit_t fe; // frame error bit + avr_regbit_t dor; // data overrun bit + avr_regbit_t upe; // parity error bit + avr_regbit_t rxb8; // receive data bit 8 + + avr_regbit_t ubrrl; + avr_regbit_t ubrrh; + + avr_int_vector_t rxc; + avr_int_vector_t txc; + avr_int_vector_t udrc; + + uart_fifo_t input; + uint8_t tx_cnt; // number of unsent characters in the output buffer + uint32_t rx_cnt; // number of characters read by app since rxc_raise_time + + uint32_t flags; + avr_cycle_count_t cycles_per_byte; + avr_cycle_count_t rxc_raise_time; // the cpu cycle when rxc flag was raised last time + + uint8_t * stdio_out; + int stdio_len; // current size in the stdio output +} avr_uart_t; + +/* takes a uint32_t* as parameter */ +#define AVR_IOCTL_UART_SET_FLAGS(_name) AVR_IOCTL_DEF('u','a','s',(_name)) +#define AVR_IOCTL_UART_GET_FLAGS(_name) AVR_IOCTL_DEF('u','a','g',(_name)) + +void avr_uart_init(avr_t * avr, avr_uart_t * port); + +#define AVR_UARTX_DECLARE(_name, _prr, _prusart) \ + .uart ## _name = { \ + .name = '0' + _name, \ + .disabled = AVR_IO_REGBIT(_prr, _prusart), \ + \ + .r_udr = UDR ## _name, \ + \ + .fe = AVR_IO_REGBIT(UCSR ## _name ## A, FE ## _name), \ + .dor = AVR_IO_REGBIT(UCSR ## _name ## A, DOR ## _name), \ + .upe = AVR_IO_REGBIT(UCSR ## _name ## A, UPE ## _name), \ + .u2x = AVR_IO_REGBIT(UCSR ## _name ## A, U2X ## _name), \ + .txen = AVR_IO_REGBIT(UCSR ## _name ## B, TXEN ## _name), \ + .rxen = AVR_IO_REGBIT(UCSR ## _name ## B, RXEN ## _name), \ + .rxb8 = AVR_IO_REGBIT(UCSR ## _name ## B, RXB8 ## _name), \ + .usbs = AVR_IO_REGBIT(UCSR ## _name ## C, USBS ## _name), \ + .ucsz = AVR_IO_REGBITS(UCSR ## _name ## C, UCSZ ## _name ## 0, 0x3), \ + .ucsz2 = AVR_IO_REGBIT(UCSR ## _name ## B, UCSZ ## _name ## 2), \ + .ubrrl = AVR_IO_REGBITS(UBRR ## _name ## L, 0,0xFF), \ + .ubrrh = AVR_IO_REGBITS(UBRR ## _name ## H, 0,0xF), \ + \ + .r_ucsra = UCSR ## _name ## A, \ + .r_ucsrb = UCSR ## _name ## B, \ + .r_ucsrc = UCSR ## _name ## C, \ + \ + .rxc = { \ + .enable = AVR_IO_REGBIT(UCSR ## _name ## B, RXCIE ## _name), \ + .raised = AVR_IO_REGBIT(UCSR ## _name ## A, RXC ## _name), \ + .vector = USART ## _name ## _RX_vect, \ + .raise_sticky = 1, \ + }, \ + .txc = { \ + .enable = AVR_IO_REGBIT(UCSR ## _name ## B, TXCIE ## _name), \ + .raised = AVR_IO_REGBIT(UCSR ## _name ## A, TXC ## _name), \ + .vector = USART ## _name ## _TX_vect, \ + }, \ + .udrc = { \ + .enable = AVR_IO_REGBIT(UCSR ## _name ## B, UDRIE ## _name), \ + .raised = AVR_IO_REGBIT(UCSR ## _name ## A, UDRE ## _name), \ + .vector = USART ## _name ## _UDRE_vect, \ + .raise_sticky = 1, \ + }, \ + } + +// This macro is for older single-interface devices where variable names are bit divergent +#define AVR_UART_DECLARE(_prr, _prusart, _upe_name, _rname_ix, _intr_c) \ + .uart = { \ + .name = '0', \ + .disabled = AVR_IO_REGBIT(_prr, _prusart), \ + .r_udr = UDR ## _rname_ix, \ + \ + .fe = AVR_IO_REGBIT(UCSR ## _rname_ix ## A, FE ## _rname_ix), \ + .dor = AVR_IO_REGBIT(UCSR ## _rname_ix ## A, DOR ## _rname_ix), \ + .upe = AVR_IO_REGBIT(UCSR ## _rname_ix ## A, _upe_name ## _rname_ix), \ + .u2x = AVR_IO_REGBIT(UCSR ## _rname_ix ## A, U2X ## _rname_ix), \ + .txen = AVR_IO_REGBIT(UCSR ## _rname_ix ## B, TXEN ## _rname_ix), \ + .rxen = AVR_IO_REGBIT(UCSR ## _rname_ix ## B, RXEN ## _rname_ix), \ + .rxb8 = AVR_IO_REGBIT(UCSR ## _rname_ix ## B, RXB8 ## _rname_ix), \ + .usbs = AVR_IO_REGBIT(UCSR ## _rname_ix ## C, USBS ## _rname_ix), \ + .ucsz = AVR_IO_REGBITS(UCSR ## _rname_ix ## C, UCSZ ## _rname_ix ## 0, 0x3), \ + .ucsz2 = AVR_IO_REGBIT(UCSR ## _rname_ix ## B, UCSZ ## _rname_ix ## 2), \ + .ubrrl = AVR_IO_REGBITS(UBRR ## _rname_ix ## L, 0,0xFF), \ + .ubrrh = AVR_IO_REGBITS(UBRR ## _rname_ix ## H, 0,0xF), \ + \ + .r_ucsra = UCSR ## _rname_ix ## A, \ + .r_ucsrb = UCSR ## _rname_ix ## B, \ + .r_ucsrc = UCSR ## _rname_ix ## C, \ + \ + .rxc = { \ + .enable = AVR_IO_REGBIT(UCSR ## _rname_ix ## B, RXCIE ## _rname_ix), \ + .raised = AVR_IO_REGBIT(UCSR ## _rname_ix ## A, RXC ## _rname_ix), \ + .vector = USART_RX ## _intr_c ## _vect, \ + .raise_sticky = 1, \ + }, \ + .txc = { \ + .enable = AVR_IO_REGBIT(UCSR ## _rname_ix ## B, TXCIE ## _rname_ix), \ + .raised = AVR_IO_REGBIT(UCSR ## _rname_ix ## A, TXC ## _rname_ix), \ + .vector = USART_TX ## _intr_c ## _vect, \ + }, \ + .udrc = { \ + .enable = AVR_IO_REGBIT(UCSR ## _rname_ix ## B, UDRIE ## _rname_ix), \ + .raised = AVR_IO_REGBIT(UCSR ## _rname_ix ## A, UDRE ## _rname_ix), \ + .vector = USART_UDRE_vect, \ + .raise_sticky = 1, \ + }, \ + } + +#ifdef __cplusplus +}; +#endif + +#endif /*__AVR_UART_H__*/ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_usb.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_usb.c new file mode 100644 index 0000000..4acbcfd --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_usb.c @@ -0,0 +1,801 @@ +/* vim: set sts=4:sw=4:ts=4:noexpandtab + avr_usb.c + + Copyright 2012 Torbjorn Tyridal <ttyridal@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +/* TODO correct reset values */ +/* TODO generate sofi every 1ms (when connected) */ +/* TODO otg support? */ +/* TODO drop bitfields? */ +/* TODO thread safe ioctls */ +/* TODO dual-bank endpoint buffers */ +/* TODO actually pay attention to endpoint memory allocation ? buggy endpoint configuration doesn't matter in the simulator now. */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include "avr_usb.h" + +enum usb_regs +{ + usbcon = 0, + udcon = 8, + udint = 9, + udien = 10, + udaddr = 11, + udfnuml = 12, + udfnumh = 13, + udmfn = 14, +// _res=15, + ueintx = 16, + uenum = 17, + uerst = 18, + ueconx = 19, + uecfg0x = 20, + uecfg1x = 21, + uesta0x = 22, + uesta1x = 23, + ueienx = 24, + uedatx = 25, + uebclx = 26, +// _res2=27, + ueint = 28, + otgtcon = 29, +}; + +union _ueintx { + struct { + uint8_t txini :1; + uint8_t stalledi :1; + uint8_t rxouti :1; + uint8_t rxstpi :1; + uint8_t nakouti :1; + uint8_t rwal :1; + uint8_t nakini :1; + uint8_t fifocon :1; + }; + uint8_t v; +}; + +struct _epstate { + union _ueintx ueintx; + uint8_t dummy1; + uint8_t dummy2; + union { + struct { + uint8_t epen :1; + uint8_t res :2; + uint8_t rstdt :1; + uint8_t stallrqc :1; + uint8_t stallrq :1; + }; + uint8_t v; + } ueconx; + union { + struct { + uint8_t epdir :1; + uint8_t res :5; + uint8_t eptype :2; + }; + uint8_t v; + } uecfg0x; + union { + struct { + uint8_t res :1; + uint8_t alloc :1; + uint8_t epbk1 :2; + uint8_t epsize :3; + uint8_t res2 :1; + }; + uint8_t v; + } uecfg1x; + union { + struct { + uint8_t nbusybk :2; + uint8_t dtseq :2; + uint8_t res :1; + uint8_t underfi :1; + uint8_t overfi :1; + uint8_t cfgok :1; + }; + uint8_t v; + } uesta0x; + union { + struct { + uint8_t curbk :2; + uint8_t ctrldir :1; + uint8_t res :5; + }; + uint8_t v; + } uesta1x; + union { + struct { + uint8_t txine :1; + uint8_t stallede :1; + uint8_t rxoute :1; + uint8_t rxstpe :1; + uint8_t nakoute :1; + uint8_t res :1; + uint8_t nakine :1; + uint8_t flerre :1; + }; + uint8_t v; + } ueienx; + + struct { + uint8_t bytes[64]; + uint8_t tail; + } bank[2]; + uint8_t current_bank; + int setup_is_read; +}; + +struct usb_internal_state { + struct _epstate ep_state[5]; + avr_int_vector_t com_vect; + avr_int_vector_t gen_vect; +}; + +const uint8_t num_endpoints = 5;//sizeof (struct usb_internal_state.ep_state) / sizeof (struct usb_internal_state.ep_state[0]); + +static uint8_t +current_ep_to_cpu( + avr_usb_t * p) +{ + return p->io.avr->data[p->r_usbcon + uenum]; +} + +static struct _epstate * +get_epstate( + avr_usb_t * p, + uint8_t ep) +{ + assert(ep < num_endpoints); + return &p->state->ep_state[ep]; +} + + +enum epints { + txini = 0, + stalledi = 1, + rxouti = 2, + rxstpi = 3, + nakouti = 4, + nakini = 6, + overfi = 10, + underfi = 11, +}; + +static void +raise_ep_interrupt( + struct avr_t * avr, + avr_usb_t * p, + uint8_t ep, + enum epints irq) +{ + struct _epstate * epstate = get_epstate(p, ep); + assert(ep < num_endpoints); + avr->data[p->r_usbcon + ueint] |= 1 << ep; + switch (irq) { + case txini: + case stalledi: + case rxouti: + case nakouti: + case nakini: + epstate->ueintx.v |= 1 << irq; + if (epstate->ueienx.v & (1 << irq)) + avr_raise_interrupt(avr, &p->state->com_vect); + break; + case rxstpi: + epstate->ueintx.v |= 1 << irq; + if (epstate->ueienx.v & (1 << irq)) + avr_raise_interrupt(avr, &p->state->com_vect); + break; + case overfi: + epstate->uesta0x.overfi = 1; + if (epstate->ueienx.flerre) + avr_raise_interrupt(avr, &p->state->com_vect); + break; + case underfi: + epstate->uesta0x.underfi = 1; + if (epstate->ueienx.flerre) + avr_raise_interrupt(avr, &p->state->com_vect); + break; + default: + assert(0); + } +} + +enum usbints { + suspi = 0, sofi = 2, eorsti = 3, wakeupi = 4, eorsmi = 5, uprsmi = 6 +}; +static void +raise_usb_interrupt( + avr_usb_t * p, + enum usbints irq) +{ + uint8_t * Rudien = &p->io.avr->data[p->r_usbcon + udien]; + uint8_t * Rudint = &p->io.avr->data[p->r_usbcon + udint]; + + switch (irq) { + case uprsmi: + case eorsmi: + case wakeupi: + case eorsti: + case sofi: + case suspi: + *Rudint |= 1 << irq; + if (*Rudien & (1 << irq)) + avr_raise_interrupt(p->io.avr, &p->state->gen_vect); + break; + default: + assert(0); + } + +} + +static void +reset_endpoints( + struct avr_t * avr, + avr_usb_t * p) +{ + memset(&p->state->ep_state[1], 0, + sizeof p->state->ep_state - sizeof p->state->ep_state[0]); +} + +static int +ep_fifo_empty( + struct _epstate * epstate) +{ + return epstate->bank[epstate->current_bank].tail == 0; +} + +static int +ep_fifo_full( + struct _epstate * epstate) +{ + return epstate->bank[epstate->current_bank].tail >= + (8 << epstate->uecfg1x.epsize); +} + +static uint8_t +ep_fifo_size( + struct _epstate * epstate) +{ + assert(epstate->ueconx.epen); + return (8 << epstate->uecfg1x.epsize); +} + +static uint8_t +ep_fifo_count( + struct _epstate * epstate) +{ + return epstate->bank[epstate->current_bank].tail; +} + +static int +ep_fifo_cpu_readbyte( + struct _epstate * epstate) +{ + uint8_t i, j; + uint8_t v = epstate->bank[epstate->current_bank].bytes[0]; + + if (!epstate->ueconx.epen) { + printf("WARNING! Adding bytes to non configured endpoint\n"); + return -1; + } + + if (ep_fifo_empty(epstate)) + return -2; + + for (i = 0, j = ep_fifo_count(epstate) - 1; i < j; i++) + epstate->bank[epstate->current_bank].bytes[i] = + epstate->bank[epstate->current_bank].bytes[i + 1]; + epstate->bank[epstate->current_bank].tail--; + return v; +} + +static int +ep_fifo_cpu_writebyte( + struct _epstate * epstate, + uint8_t v) +{ + if (!epstate->ueconx.epen) { + printf("WARNING! Adding bytes to non configured endpoint\n"); + return -1; + } + if (ep_fifo_full(epstate)) + return -2; + + epstate->bank[epstate->current_bank].bytes[epstate->bank[epstate->current_bank].tail++] = v; + return 0; +} + +static int +ep_fifo_usb_read( + struct _epstate * epstate, + uint8_t * buf) +{ + if (!epstate->ueconx.epen) { + printf("WARNING! Reading from non configured endpoint\n"); + return -1; + } + if (epstate->ueintx.txini) { + return AVR_IOCTL_USB_NAK; + } + if (epstate->ueintx.fifocon && epstate->uecfg0x.eptype != 0) { + return AVR_IOCTL_USB_NAK; + } + + int ret = epstate->bank[epstate->current_bank].tail; + memcpy(buf, epstate->bank[epstate->current_bank].bytes, + epstate->bank[epstate->current_bank].tail); + epstate->bank[epstate->current_bank].tail = 0; + return ret; +} + +static int +ep_fifo_usb_write( + struct _epstate * epstate, + uint8_t * buf, + uint8_t len) +{ + if (!epstate->ueconx.epen) { + printf("WARNING! Adding bytes to non configured endpoint\n"); + return -1; + } + + if (epstate->ueintx.rxouti) { + return AVR_IOCTL_USB_NAK; + } + if (epstate->ueintx.fifocon && epstate->uecfg0x.eptype != 0) { + return AVR_IOCTL_USB_NAK; + } + + if (len > ep_fifo_size(epstate)) { + printf("EP OVERFI\n"); + len = sizeof epstate->bank[epstate->current_bank].bytes; + } + memcpy(epstate->bank[epstate->current_bank].bytes, buf, len); + epstate->bank[epstate->current_bank].tail = len; + + return 0; +} + +static uint8_t +avr_usb_ep_read_bytecount( + struct avr_t * avr, + avr_io_addr_t addr, + void * param) +{ + avr_usb_t * p = (avr_usb_t *) param; + return ep_fifo_count(get_epstate(p, current_ep_to_cpu(p))); +} + +static void +avr_usb_udaddr_write( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + if (v & 0x80) + AVR_LOG(avr, LOG_TRACE, "USB: Activate address %d\n", v & 0x7f); + avr_core_watch_write(avr, addr, v); +} + +static void +avr_usb_udcon_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param) +{ + avr_usb_t * p = (avr_usb_t *)param; + + if(avr->data[addr]&1 && !(v&1)) + avr_raise_irq(p->io.irq + USB_IRQ_ATTACH, !(v&1)); + avr_core_watch_write(avr, addr, v); +} + +static void +avr_usb_uenum_write( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + assert(v < num_endpoints); + avr_core_watch_write(avr, addr, v); +} + +static uint8_t +avr_usb_ep_read_ueintx( + struct avr_t * avr, + avr_io_addr_t addr, + void * param) +{ + avr_usb_t * p = (avr_usb_t *) param; + uint8_t ep = current_ep_to_cpu(p); + + if (p->state->ep_state[ep].uecfg0x.epdir) + p->state->ep_state[ep].ueintx.rwal = !ep_fifo_full(get_epstate(p, ep)); + else + p->state->ep_state[ep].ueintx.rwal = !ep_fifo_empty(get_epstate(p, ep)); + + return p->state->ep_state[ep].ueintx.v; +} + +static void +avr_usb_ep_write_ueintx( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_usb_t * p = (avr_usb_t *) param; + uint8_t ep = current_ep_to_cpu(p); + + union _ueintx * newstate = (union _ueintx*) &v; + union _ueintx * curstate = &p->state->ep_state[ep].ueintx; + + if (curstate->rxouti & !newstate->rxouti) + curstate->rxouti = 0; + if (curstate->txini & !newstate->txini) + curstate->txini = 0; + if (curstate->rxstpi & !newstate->rxstpi) { + curstate->txini = 1; + curstate->rxouti = 0; + curstate->rxstpi = 0; + } + if (curstate->fifocon & !newstate->fifocon) + curstate->fifocon = 0; + if (curstate->nakini & !newstate->nakini) + curstate->nakini = 0; + if (curstate->nakouti & !newstate->nakouti) + curstate->nakouti = 0; + if (curstate->stalledi & !newstate->stalledi) + curstate->stalledi = 0; + if (curstate->rwal & !newstate->rwal) + AVR_LOG(avr, LOG_WARNING, "USB: Pointless change of ueintx.rwal\n"); + + if ((curstate->v & 0xdf) == 0) + avr->data[p->r_usbcon + ueint] &= 0xff ^ (1 << ep); // mark ep0 interrupt +} + +static uint8_t +avr_usb_ep_read( + struct avr_t * avr, + avr_io_addr_t addr, + void * param) +{ + avr_usb_t * p = (avr_usb_t *) param; + uint8_t laddr = addr - p->r_usbcon; + uint8_t v; + struct _epstate * epstate = get_epstate(p, current_ep_to_cpu(p)); + + switch(laddr) { + case ueconx: v = epstate->ueconx.v; break; + case uecfg0x: v = epstate->uecfg0x.v; break; + case uecfg1x: v = epstate->uecfg1x.v; break; + case uesta0x: v = epstate->uesta0x.v; break; + case uesta1x: v = epstate->uesta1x.v; break; + case ueienx: v = epstate->ueienx.v; break; + default:assert(0); + } + return v; +} + +static void +avr_usb_ep_write( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_usb_t * p = (avr_usb_t *) param; + struct _epstate * epstate = get_epstate(p, current_ep_to_cpu(p)); + uint8_t laddr = addr - p->r_usbcon; + + switch (laddr) { + case ueconx: + if (v & 1 << 4) + epstate->ueconx.stallrq = 0; + if (v & 1 << 5) + epstate->ueconx.stallrq = 1; + epstate->ueconx.epen = (v & 1) != 0; + break; + case uecfg0x: + epstate->uecfg0x.v = v; + epstate->uesta0x.cfgok = 0; + break; + case uecfg1x: + epstate->uecfg1x.v = v; + epstate->uesta0x.cfgok = epstate->uecfg1x.alloc; + if (epstate->uecfg0x.eptype == 0) + epstate->ueintx.txini = 1; + else if (epstate->uecfg0x.epdir) { + epstate->ueintx.txini = 1; + epstate->ueintx.rwal = 1; + epstate->ueintx.fifocon = 1; + } else + epstate->ueintx.rxouti = 0; + avr_core_watch_write(avr, p->r_usbcon + uesta0x, + epstate->uesta0x.v); + break; + case uesta0x: + v = (epstate->uesta0x.v & 0x9f) + (v & (0x60 & epstate->uesta0x.v)); + epstate->uesta0x.v = v; + break; + case ueienx: + epstate->ueienx.v = v; + break; + default: + assert(0); + } +} + +static uint8_t +avr_usb_ep_read_data( + struct avr_t * avr, + avr_io_addr_t addr, + void * param) +{ + avr_usb_t * p = (avr_usb_t *) param; + int ret = ep_fifo_cpu_readbyte(get_epstate(p, current_ep_to_cpu(p))); + + if (ret < 0) { + if (ret == -2) + raise_ep_interrupt(avr, p, current_ep_to_cpu(p), underfi); + return 0; + } else + return (uint8_t) ret; +} + +static void +avr_usb_ep_write_data( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_usb_t * p = (avr_usb_t *) param; + int ret = ep_fifo_cpu_writebyte(get_epstate(p, current_ep_to_cpu(p)), v); + if (ret == 0) + return; + + if (ret == -2) + raise_ep_interrupt(avr, p, current_ep_to_cpu(p), overfi); +} + +static void +avr_usb_pll_write( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + v |= (v >> 1) & 1; + avr_core_watch_write(avr, addr, v); +} + + +avr_cycle_count_t +sof_generator( + struct avr_t * avr, + avr_cycle_count_t when, + void * param) +{ + avr_usb_t * p = (avr_usb_t *) param; + //stop sof generation if detached + if (avr->data[p->r_usbcon + udcon] & 1) + return 0; + else { + raise_usb_interrupt(p, sofi); + return when; + } +} + +static int +avr_usb_ioctl( + struct avr_io_t * io, + uint32_t ctl, + void * io_param) +{ + avr_usb_t * p = (avr_usb_t *) io; + struct avr_io_usb * d = (struct avr_io_usb*) io_param; + struct _epstate * epstate = 0; + int ret; + uint8_t ep; + + switch (ctl) { + case AVR_IOCTL_USB_READ: + ep = d->pipe & 0x7f; + epstate = get_epstate(p, ep); + + if (epstate->ueconx.stallrq) { + raise_ep_interrupt(io->avr, p, 0, stalledi); + return AVR_IOCTL_USB_STALL; + } + if (ep && !epstate->uecfg0x.epdir) + AVR_LOG(io->avr, LOG_WARNING, "USB: Reading from IN endpoint from host??\n"); + + ret = ep_fifo_usb_read(epstate, d->buf); + if (ret < 0) { + // is this correct? It makes the cdc example work. + // Linux stops polling the data ep if we send naks,but + // according to usb spec nak'ing should be ok. + if (epstate->uecfg0x.eptype == 2) { + d->sz = 0; + return 0; + } else + return ret; + } + d->sz = ret; + ret = 0; + epstate->ueintx.fifocon = 1; + raise_ep_interrupt(io->avr, p, ep, txini); + return ret; + case AVR_IOCTL_USB_WRITE: + ep = d->pipe & 0x7f; + epstate = get_epstate(p, ep); + + if (ep && epstate->uecfg0x.epdir) + AVR_LOG(io->avr, LOG_WARNING, "USB: Writing to IN endpoint from host??\n"); + + if (epstate->ueconx.stallrq) { + raise_ep_interrupt(io->avr, p, 0, stalledi); + return AVR_IOCTL_USB_STALL; + } + + ret = ep_fifo_usb_write(epstate, d->buf, d->sz); + if (ret < 0) + return ret; + + epstate->ueintx.fifocon = 1; + raise_ep_interrupt(io->avr, p, ep, rxouti); + return 0; + case AVR_IOCTL_USB_SETUP: + ep = d->pipe & 0x7f; + epstate = get_epstate(p, ep); + + epstate->ueconx.stallrq = 0; + // teensy actually depends on this (fails to ack rxouti on usb + // control read status stage) even if the datasheet clearly states + // that one should do so. + epstate->ueintx.rxouti = 0; + + ret = ep_fifo_usb_write(epstate, d->buf, d->sz); + if (ret < 0) + return ret; + raise_ep_interrupt(io->avr, p, ep, rxstpi); + + return 0; + case AVR_IOCTL_USB_RESET: + AVR_LOG(io->avr, LOG_TRACE, "USB: __USB_RESET__\n"); + reset_endpoints(io->avr, p); + raise_usb_interrupt(p, eorsti); + if (0) + avr_cycle_timer_register_usec(io->avr, 1000, sof_generator, p); + return 0; + default: + return -1; + } +} + +void +avr_usb_reset( + struct avr_io_t *io) +{ + avr_usb_t * p = (avr_usb_t *) io; + uint8_t i; + + memset(p->state->ep_state, 0, sizeof p->state->ep_state); + + for (i = 0; i < otgtcon; i++) + p->io.avr->data[p->r_usbcon + i] = 0; + + p->io.avr->data[p->r_usbcon] = 0x20; + p->io.avr->data[p->r_usbcon + udcon] = 1; + + AVR_LOG(io->avr, LOG_TRACE, "USB: %s\n", __FUNCTION__); +} + +static const char * irq_names[USB_IRQ_COUNT] = { + [USB_IRQ_ATTACH] = ">attach", +}; + +static void +avr_usb_dealloc( + struct avr_io_t * port) +{ + avr_usb_t * p = (avr_usb_t *) port; + free(p->state); +} + +static avr_io_t _io = { + .kind = "usb", + .reset = avr_usb_reset, + .irq_names = irq_names, + .ioctl = avr_usb_ioctl, + .dealloc = avr_usb_dealloc, +}; + +static void +register_io_ep_readwrite( + avr_t * avr, + avr_usb_t * p, + uint8_t laddr) +{ + avr_register_io_write(avr, p->r_usbcon + laddr, avr_usb_ep_write, p); + avr_register_io_read(avr, p->r_usbcon + laddr, avr_usb_ep_read, p); +} + +static void +register_vectors( + avr_t * avr, + avr_usb_t * p) +{ + // usb interrupts are multiplexed into just two vectors. + // we therefore need fake bits for enable & raise + + // use usbe as fake enable bit + p->state->com_vect.enable = (avr_regbit_t)AVR_IO_REGBIT(p->r_usbcon, 7); + p->state->gen_vect.enable = (avr_regbit_t)AVR_IO_REGBIT(p->r_usbcon, 7); + +// // use reserved/unused bits in usbsta as fake raised bits +// p->state->com_vect.raised = (avr_regbit_t)AVR_IO_REGBIT(p->r_usbcon+1,7); +// p->state->gen_vect.raised = (avr_regbit_t)AVR_IO_REGBIT(p->r_usbcon+1,6); + + p->state->com_vect.vector = p->usb_com_vect; + p->state->gen_vect.vector = p->usb_gen_vect; + + avr_register_vector(avr, &p->state->com_vect); + avr_register_vector(avr, &p->state->gen_vect); +} + +void avr_usb_init(avr_t * avr, avr_usb_t * p) +{ + p->io = _io; + + p->state = calloc(1, sizeof *p->state); + + avr_register_io(avr, &p->io); + register_vectors(avr, p); + // allocate this module's IRQ + avr_io_setirqs(&p->io, AVR_IOCTL_USB_GETIRQ(), USB_IRQ_COUNT, NULL); + + avr_register_io_write(avr, p->r_usbcon + udaddr, avr_usb_udaddr_write, p); + avr_register_io_write(avr, p->r_usbcon + udcon, avr_usb_udcon_write, p); + avr_register_io_write(avr, p->r_usbcon + uenum, avr_usb_uenum_write, p); + + avr_register_io_read(avr, p->r_usbcon + uedatx, avr_usb_ep_read_data, p); + avr_register_io_write(avr, p->r_usbcon + uedatx, avr_usb_ep_write_data, p); + avr_register_io_read(avr, p->r_usbcon + uebclx, avr_usb_ep_read_bytecount, p); //ro + + avr_register_io_read(avr, p->r_usbcon + ueintx, avr_usb_ep_read_ueintx, p); + avr_register_io_write(avr, p->r_usbcon + ueintx, avr_usb_ep_write_ueintx, p); + + register_io_ep_readwrite(avr, p, ueconx); + register_io_ep_readwrite(avr, p, uecfg0x); + register_io_ep_readwrite(avr, p, uecfg1x); + register_io_ep_readwrite(avr, p, uesta0x); + register_io_ep_readwrite(avr, p, uesta1x); + register_io_ep_readwrite(avr, p, ueienx); + + avr_register_io_write(avr, p->r_pllcsr, avr_usb_pll_write, p); +} + diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_usb.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_usb.h new file mode 100644 index 0000000..17e5c0d --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_usb.h @@ -0,0 +1,74 @@ +/* vim: set sts=4:sw=4:ts=4:noexpandtab + avr_usb.h + + Copyright 2012 Torbjorn Tyridal <ttyridal@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __AVR_USB_H__ +#define __AVR_USB_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sim_avr.h" + +enum { + USB_IRQ_ATTACH = 0, + USB_IRQ_COUNT +}; + +// add port number to get the real IRQ +#define AVR_IOCTL_USB_WRITE AVR_IOCTL_DEF('u','s','b','w') +#define AVR_IOCTL_USB_READ AVR_IOCTL_DEF('u','s','b','r') +#define AVR_IOCTL_USB_SETUP AVR_IOCTL_DEF('u','s','b','s') +#define AVR_IOCTL_USB_RESET AVR_IOCTL_DEF('u','s','b','R') +#define AVR_IOCTL_USB_VBUS AVR_IOCTL_DEF('u','s','b','V') +#define AVR_IOCTL_USB_GETIRQ() AVR_IOCTL_DEF('u','s','b',' ') + +struct avr_io_usb { + uint8_t pipe; //[in] + uint32_t sz; //[in/out] + uint8_t * buf; //[in/out] +}; +#define AVR_IOCTL_USB_NAK -2 +#define AVR_IOCTL_USB_STALL -3 +#define AVR_IOCTL_USB_OK 0 + +typedef struct avr_usb_t { + avr_io_t io; + char name; + avr_regbit_t disabled; // bit in the PRR + avr_regbit_t usbrf; // bit in the MCUSR + avr_io_addr_t r_usbcon; // every usb reg is an offset of this. + avr_io_addr_t r_pllcsr; + + + uint8_t usb_com_vect; + uint8_t usb_gen_vect; + + struct usb_internal_state * state; +} avr_usb_t; + +void avr_usb_init(avr_t * avr, avr_usb_t * port); + +#ifdef __cplusplus +}; +#endif + +#endif /*__AVR_USB_H__*/ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_watchdog.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_watchdog.c new file mode 100644 index 0000000..b7a5d01 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_watchdog.c @@ -0,0 +1,231 @@ +/* + avr_watchdog.c + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <stdio.h> +#include <stdlib.h> +#include "avr_watchdog.h" + +static void avr_watchdog_run_callback_software_reset(avr_t * avr) +{ + avr_reset(avr); +} + +static avr_cycle_count_t avr_watchdog_timer( + struct avr_t * avr, avr_cycle_count_t when, void * param) +{ + avr_watchdog_t * p = (avr_watchdog_t *)param; + + if (avr_regbit_get(avr, p->watchdog.enable)) { + AVR_LOG(avr, LOG_TRACE, "WATCHDOG: timer fired.\n"); + avr_raise_interrupt(avr, &p->watchdog); + return when + p->cycle_count; + } else if (avr_regbit_get(avr, p->wde)) { + AVR_LOG(avr, LOG_TRACE, + "WATCHDOG: timer fired without interrupt. Resetting\n"); + + p->reset_context.avr_run = avr->run; + p->reset_context.wdrf = 1; + + /* Ideally we would perform a reset here via 'avr_reset' + * However, returning after reset would result in an unconsistent state. + * It seems our best (and cleanest) solution is to set a temporary call + * back which can safely perform the reset for us... During reset, + * the previous callback can be restored and safely resume. + */ + avr->run = avr_watchdog_run_callback_software_reset; + } + + return 0; +} + +static avr_cycle_count_t avr_wdce_clear( + struct avr_t * avr, avr_cycle_count_t when, void * param) +{ + avr_watchdog_t * p = (avr_watchdog_t *)param; + avr_regbit_clear(p->io.avr, p->wdce); + return 0; +} + +static void avr_watchdog_set_cycle_count_and_timer( + avr_t * avr, + avr_watchdog_t * p, + uint8_t was_enabled, + int8_t old_wdp) +{ + // If nothing else, always ensure we have a valid cycle count... + uint8_t wdp = avr_regbit_get_array(avr, p->wdp, 4); + + p->cycle_count = 2048 << wdp; + p->cycle_count = (p->cycle_count * avr->frequency) / 128000; + + uint8_t wde = avr_regbit_get(avr, p->wde); + uint8_t wdie = avr_regbit_get(avr, p->watchdog.enable); + + uint8_t enable_changed = (was_enabled != (wde || wdie)); + + uint8_t wdp_changed = ((old_wdp >= 0) ? (wdp != old_wdp) : 0); + + if (!enable_changed && !wdp_changed) + return; + + static char *message[2][2] = { + { 0, "reset" }, { "enabled", "enabled and set" } }; + + if (wde || wdie) { + AVR_LOG(avr, LOG_TRACE, + "WATCHDOG: %s to %d cycles @ 128kz (* %d) = %d CPU cycles.\n", + message[enable_changed][wdp_changed], 2048 << wdp, + 1 << wdp, (int)p->cycle_count); + + avr_cycle_timer_register(avr, p->cycle_count, avr_watchdog_timer, p); + } else if (enable_changed) { + AVR_LOG(avr, LOG_TRACE, "WATCHDOG: disabled\n"); + avr_cycle_timer_cancel(avr, avr_watchdog_timer, p); + } +} + +static void avr_watchdog_write( + avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param) +{ + avr_watchdog_t * p = (avr_watchdog_t *)param; + + uint8_t old_wde = avr_regbit_get(avr, p->wde); + uint8_t old_wdie = avr_regbit_get(avr, p->watchdog.enable); + uint8_t old_wdce = avr_regbit_get(avr, p->wdce); + + uint8_t was_enabled = (old_wde || old_wdie); + + uint8_t old_v = avr->data[addr]; // allow gdb to see write... + avr_core_watch_write(avr, addr, v); + + if (old_wdce) { + uint8_t old_wdp = avr_regbit_get_array(avr, p->wdp, 4); + + // wdrf (watchdog reset flag) must be cleared before wde can be cleared. + if (avr_regbit_get(avr, p->wdrf)) + avr_regbit_set(avr, p->wde); + + avr_watchdog_set_cycle_count_and_timer(avr, p, was_enabled, old_wdp); + } else { + /* easier to change only what we need rather than check and reset + * locked/read-only bits. + */ + avr->data[addr] = old_v; + + uint8_t wdce_v = avr_regbit_from_value(avr, p->wdce, v); + uint8_t wde_v = avr_regbit_from_value(avr, p->wde, v); + + if (wdce_v && wde_v) { + avr_regbit_set(avr, p->wdce); + + avr_cycle_timer_register(avr, 4, avr_wdce_clear, p); + } else { + if (wde_v) // wde can be set but not cleared + avr_regbit_set(avr, p->wde); + + avr_regbit_setto_raw(avr, p->watchdog.enable, v); + + avr_watchdog_set_cycle_count_and_timer(avr, p, was_enabled, -1); + } + } +} + +/* + * called by the core when a WTD instruction is found + */ +static int avr_watchdog_ioctl( + struct avr_io_t * port, uint32_t ctl, void * io_param) +{ + avr_watchdog_t * p = (avr_watchdog_t *)port; + int res = -1; + + if (ctl == AVR_IOCTL_WATCHDOG_RESET) { + if (avr_regbit_get(p->io.avr, p->wde) || + avr_regbit_get(p->io.avr, p->watchdog.enable)) + avr_cycle_timer_register(p->io.avr, p->cycle_count, + avr_watchdog_timer, p); + res = 0; + } + + return res; +} + +static void avr_watchdog_irq_notify( + struct avr_irq_t * irq, + uint32_t value, + void * param) +{ + avr_watchdog_t * p = (avr_watchdog_t *)param; + avr_t * avr = p->io.avr; + + /* interrupt handling calls this twice... + * first when raised (during queuing), value = 1 + * again when cleared (after servicing), value = 0 + */ + + if (!value && avr_regbit_get(avr, p->watchdog.raised) && avr_regbit_get(avr, p->wde)) { + avr_regbit_clear(avr, p->watchdog.enable); + } +} + +static void avr_watchdog_reset(avr_io_t * port) +{ + avr_watchdog_t * p = (avr_watchdog_t *)port; + avr_t * avr = p->io.avr; + + if (p->reset_context.wdrf) { + p->reset_context.wdrf = 0; + /* + * if watchdog reset kicked, then watchdog gets restarted at + * fastest interval + */ + avr->run = p->reset_context.avr_run; + + avr_regbit_set(avr, p->wde); + avr_regbit_set(avr, p->wdrf); + avr_regbit_set_array_from_value(avr, p->wdp, 4, 0); + + avr_watchdog_set_cycle_count_and_timer(avr, p, 0, 0); + } + /* TODO could now use the two pending/running IRQs to do the same + * as before */ + avr_irq_register_notify(p->watchdog.irq, avr_watchdog_irq_notify, p); +} + +static avr_io_t _io = { + .kind = "watchdog", + .reset = avr_watchdog_reset, + .ioctl = avr_watchdog_ioctl, +}; + +void avr_watchdog_init(avr_t * avr, avr_watchdog_t * p) +{ + p->io = _io; + + avr_register_io(avr, &p->io); + avr_register_vector(avr, &p->watchdog); + + avr_register_io_write(avr, p->wdce.reg, avr_watchdog_write, p); + + p->reset_context.wdrf = 0; +} + diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_watchdog.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_watchdog.h new file mode 100644 index 0000000..da86371 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_watchdog.h @@ -0,0 +1,96 @@ +/* + avr_watchdog.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef __AVR_WATCHDOG_H___ +#define __AVR_WATCHDOG_H___ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sim_avr.h" + +typedef struct avr_watchdog_t { + avr_io_t io; + + avr_regbit_t wdrf; // watchdog reset flag (in MCU Status Register) + + avr_regbit_t wdce; // watchdog change enable + avr_regbit_t wde; // watchdog enabled + avr_regbit_t wdp[4]; // watchdog Timer Prescaler + + avr_int_vector_t watchdog; // watchdog interrupt + + avr_cycle_count_t cycle_count; + + struct { + uint8_t wdrf; // saved watchdog reset flag + avr_run_t avr_run; // restored during reset + } reset_context; +} avr_watchdog_t; + +/* takes no parameter */ +#define AVR_IOCTL_WATCHDOG_RESET AVR_IOCTL_DEF('w','d','t','r') + +void avr_watchdog_init(avr_t * avr, avr_watchdog_t * p); + + +/* + * This helps declare a watchdog block into a core. + * No guarantee it will work with all, but it works + * with the one we have right now + */ +#define AVR_WATCHDOG_DECLARE(_WDSR, _vec) \ + .watchdog = {\ + .wdrf = AVR_IO_REGBIT(MCUSR, WDRF),\ + .wdce = AVR_IO_REGBIT(_WDSR, WDCE),\ + .wde = AVR_IO_REGBIT(_WDSR, WDE),\ + .wdp = { AVR_IO_REGBIT(_WDSR, WDP0),AVR_IO_REGBIT(_WDSR, WDP1),\ + AVR_IO_REGBIT(_WDSR, WDP2),AVR_IO_REGBIT(_WDSR, WDP3) },\ + .watchdog = {\ + .enable = AVR_IO_REGBIT(_WDSR, WDIE),\ + .raised = AVR_IO_REGBIT(_WDSR, WDIF),\ + .vector = _vec,\ + },\ + } + +/* no WDP3, WDIE, WDIF in atmega128 */ +/* MCUSR is called MCUCSR in atmega128 */ +#define AVR_WATCHDOG_DECLARE_128(_WDSR, _vec) \ + .watchdog = {\ + .wdrf = AVR_IO_REGBIT(MCUCSR, WDRF),\ + .wdce = AVR_IO_REGBIT(_WDSR, WDCE),\ + .wde = AVR_IO_REGBIT(_WDSR, WDE),\ + .wdp = { AVR_IO_REGBIT(_WDSR, WDP0),AVR_IO_REGBIT(_WDSR, WDP1),\ + AVR_IO_REGBIT(_WDSR, WDP2) },\ + .watchdog = {\ + .enable = AVR_IO_REGBIT(_WDSR, 6),\ + .raised = AVR_IO_REGBIT(_WDSR, 7),\ + .vector = _vec,\ + },\ + } + +#ifdef __cplusplus +}; +#endif + +#endif /* __AVR_WATCHDOG_H___ */ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/fifo_declare.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/fifo_declare.h new file mode 100644 index 0000000..8a3b2fb --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/fifo_declare.h @@ -0,0 +1,189 @@ +/* + fido_declare.h + Copyright (C) 2003-2012 Michel Pollet <buserror@gmail.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* + * FIFO helpers, aka circular buffers + * + * these macros define accessories for FIFOs of any name, type and + * any (power of two) size + */ + +#ifndef __FIFO_DECLARE__ +#define __FIFO_DECLARE__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + doing a : + DECLARE_FIFO(uint8_t, myfifo, 128); + + will declare : + enum : myfifo_overflow_f + type : myfifo_t + functions: + // write a byte into the fifo, return 1 if there was room, 0 if there wasn't + int myfifo_write(myfifo_t *c, uint8_t b); + // reads a byte from the fifo, return 0 if empty. Use myfifo_isempty() to check beforehand + uint8_t myfifo_read(myfifo_t *c); + int myfifo_isfull(myfifo_t *c); + int myfifo_isempty(myfifo_t *c); + // returns number of items to read now + uint16_t myfifo_get_read_size(myfifo_t *c); + // read item at offset o from read cursor, no cursor advance + uint8_t myfifo_read_at(myfifo_t *c, uint16_t o); + // write b at offset o compared to current write cursor, no cursor advance + void myfifo_write_at(myfifo_t *c, uint16_t o, uint8_t b); + + In your .c you need to 'implement' the fifo: + DEFINE_FIFO(uint8_t, myfifo) + + To use the fifo, you must declare at least one : + myfifo_t fifo = FIFO_NULL; + + while (!myfifo_isfull(&fifo)) + myfifo_write(&fifo, 0xaa); + .... + while (!myfifo_isempty(&fifo)) + b = myfifo_read(&fifo); + */ + +#include <stdint.h> + +#if __AVR__ +#define FIFO_CURSOR_TYPE uint8_t +#define FIFO_BOOL_TYPE char +#define FIFO_INLINE +#define FIFO_SYNC +#endif + +#ifndef FIFO_CURSOR_TYPE +#define FIFO_CURSOR_TYPE uint16_t +#endif +#ifndef FIFO_BOOL_TYPE +#define FIFO_BOOL_TYPE int +#endif +#ifndef FIFO_INLINE +#define FIFO_INLINE inline +#endif + +/* We should not need volatile */ +#ifndef FIFO_VOLATILE +#define FIFO_VOLATILE +#endif +#ifndef FIFO_SYNC +#define FIFO_SYNC __sync_synchronize() +#endif + +#ifndef FIFO_ZERO_INIT +#define FIFO_ZERO_INIT {0} +#endif +#define FIFO_NULL { FIFO_ZERO_INIT, 0, 0, 0 } + +/* New compilers don't like unused static functions. However, + * we do like 'static inlines' for these small accessors, + * so we mark them as 'unused'. It stops it complaining */ +#ifdef __GNUC__ +#define FIFO_DECL static __attribute__ ((unused)) +#else +#define FIFO_DECL static +#endif + +#define DECLARE_FIFO(__type, __name, __size) \ +enum { __name##_overflow_f = (1 << 0) }; \ +enum { __name##_fifo_size = (__size) }; \ +typedef struct __name##_t { \ + __type buffer[__name##_fifo_size]; \ + FIFO_VOLATILE FIFO_CURSOR_TYPE read; \ + FIFO_VOLATILE FIFO_CURSOR_TYPE write; \ + FIFO_VOLATILE uint8_t flags; \ +} __name##_t + +#define DEFINE_FIFO(__type, __name) \ +FIFO_DECL FIFO_INLINE FIFO_BOOL_TYPE __name##_write(__name##_t * c, __type b)\ +{\ + FIFO_CURSOR_TYPE now = c->write;\ + FIFO_CURSOR_TYPE next = (now + 1) & (__name##_fifo_size-1);\ + if (c->read != next) { \ + c->buffer[now] = b;\ + FIFO_SYNC; \ + c->write = next;\ + return 1;\ + }\ + return 0;\ +}\ +FIFO_DECL FIFO_INLINE FIFO_BOOL_TYPE __name##_isfull(__name##_t *c)\ +{\ + FIFO_CURSOR_TYPE next = (c->write + 1) & (__name##_fifo_size-1);\ + return c->read == next;\ +}\ +FIFO_DECL FIFO_INLINE FIFO_BOOL_TYPE __name##_isempty(__name##_t * c)\ +{\ + return c->read == c->write;\ +}\ +FIFO_DECL FIFO_INLINE __type __name##_read(__name##_t * c)\ +{\ + __type res = FIFO_ZERO_INIT; \ + FIFO_CURSOR_TYPE read = c->read;\ + if (read == c->write)\ + return res;\ + res = c->buffer[read];\ + FIFO_SYNC; \ + c->read = (read + 1) & (__name##_fifo_size-1);\ + return res;\ +}\ +FIFO_DECL FIFO_INLINE FIFO_CURSOR_TYPE __name##_get_read_size(__name##_t *c)\ +{\ + return ((c->write + __name##_fifo_size) - c->read) & (__name##_fifo_size-1);\ +}\ +FIFO_DECL FIFO_INLINE FIFO_CURSOR_TYPE __name##_get_write_size(__name##_t *c)\ +{\ + return (__name##_fifo_size-1) - __name##_get_read_size(c);\ +}\ +FIFO_DECL FIFO_INLINE void __name##_read_offset(__name##_t *c, FIFO_CURSOR_TYPE o)\ +{\ + FIFO_SYNC; \ + c->read = (c->read + o) & (__name##_fifo_size-1);\ +}\ +FIFO_DECL FIFO_INLINE __type __name##_read_at(__name##_t *c, FIFO_CURSOR_TYPE o)\ +{\ + return c->buffer[(c->read + o) & (__name##_fifo_size-1)];\ +}\ +FIFO_DECL FIFO_INLINE void __name##_write_at(__name##_t *c, FIFO_CURSOR_TYPE o, __type b)\ +{\ + c->buffer[(c->write + o) & (__name##_fifo_size-1)] = b;\ +}\ +FIFO_DECL FIFO_INLINE void __name##_write_offset(__name##_t *c, FIFO_CURSOR_TYPE o)\ +{\ + FIFO_SYNC; \ + c->write = (c->write + o) & (__name##_fifo_size-1);\ +}\ +FIFO_DECL FIFO_INLINE void __name##_reset(__name##_t *c)\ +{\ + FIFO_SYNC; \ + c->read = c->write = c->flags = 0;\ +}\ +struct __name##_t + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/run_avr.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/run_avr.c new file mode 100644 index 0000000..dfa6fce --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/run_avr.c @@ -0,0 +1,287 @@ +/* + run_avr.c + + Copyright 2008, 2010 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <libgen.h> +#include <string.h> +#include <signal.h> +#include "sim_avr.h" +#include "sim_elf.h" +#include "sim_core.h" +#include "sim_gdb.h" +#include "sim_hex.h" +#include "sim_vcd_file.h" + +#include "sim_core_decl.h" + +static void +display_usage( + const char * app) +{ + printf("Usage: %s [...] <firmware>\n", app); + printf( + " [--help|-h|-?] Display this usage message and exit\n" + " [--list-cores] List all supported AVR cores and exit\n" + " [-v] Raise verbosity level\n" + " (can be passed more than once)\n" + " [--freq|-f <freq>] Sets the frequency for an .hex firmware\n" + " [--mcu|-m <device>] Sets the MCU type for an .hex firmware\n" + " [--gdb|-g [<port>]] Listen for gdb connection on <port> " + "(default 1234)\n" +#ifdef CONFIG_SIMAVR_TRACE + " [--trace, -t] Run full scale decoder trace\n" +#else + " [--trace, -t] Run full scale decoder trace (Off)\n" +#endif //CONFIG_SIMAVR_TRACE + " [-ti <vector>] Add traces for IRQ vector <vector>\n" + " [--input|-i <file>] A VCD file to use as input signals\n" + " [--output|-o <file>] A VCD file to save the traced signals\n" + " [--add-trace|-at <name=kind@addr/mask>]\n" + " Add signal to be included in VCD output\n" + " [-ff <.hex file>] Load next .hex file as flash\n" + " [-ee <.hex file>] Load next .hex file as eeprom\n" + " <firmware> A .hex or an ELF file. ELF files are\n" + " preferred, and can include " + "debugging syms\n"); + exit(1); +} + +static void +list_cores() +{ + printf( "Supported AVR cores:\n"); + for (int i = 0; avr_kind[i]; i++) { + printf(" "); + for (int ti = 0; ti < 4 && avr_kind[i]->names[ti]; ti++) + printf("%s ", avr_kind[i]->names[ti]); + printf("\n"); + } + exit(1); +} + +static avr_t * avr = NULL; + +static void +sig_int( + int sign) +{ + printf("signal caught, simavr terminating\n"); + if (avr) + avr_terminate(avr); + exit(0); +} + +int +main( + int argc, + char *argv[]) +{ +#ifdef CONFIG_SIMAVR_TRACE + int trace = 0; +#endif //CONFIG_SIMAVR_TRACE + elf_firmware_t f = {{0}}; + uint32_t f_cpu = 0; + int gdb = 0; + int log = 1; + int port = 1234; + char name[24] = ""; + uint32_t loadBase = AVR_SEGMENT_OFFSET_FLASH; + int trace_vectors[8] = {0}; + int trace_vectors_count = 0; + const char *vcd_input = NULL; + + if (argc == 1) + display_usage(basename(argv[0])); + + for (int pi = 1; pi < argc; pi++) { + if (!strcmp(argv[pi], "--list-cores")) { + list_cores(); + } else if (!strcmp(argv[pi], "-h") || !strcmp(argv[pi], "--help")) { + display_usage(basename(argv[0])); + } else if (!strcmp(argv[pi], "-m") || !strcmp(argv[pi], "--mcu")) { + if (pi < argc-1) { + snprintf(name, sizeof(name), "%s", argv[++pi]); + strcpy(f.mmcu, name); + } else { + display_usage(basename(argv[0])); + } + } else if (!strcmp(argv[pi], "-f") || !strcmp(argv[pi], "--freq")) { + if (pi < argc-1) { + f_cpu = atoi(argv[++pi]); + f.frequency = f_cpu; + } else { + display_usage(basename(argv[0])); + } + } else if (!strcmp(argv[pi], "-i") || !strcmp(argv[pi], "--input")) { + if (pi < argc-1) + vcd_input = argv[++pi]; + else + display_usage(basename(argv[0])); + } else if (!strcmp(argv[pi], "-o") || + !strcmp(argv[pi], "--output")) { + if (pi + 1 >= argc) { + fprintf(stderr, "%s: missing mandatory argument for %s.\n", argv[0], argv[pi]); + exit(1); + } + snprintf(f.tracename, sizeof(f.tracename), "%s", argv[++pi]); + } else if (!strcmp(argv[pi], "-t") || + !strcmp(argv[pi], "--trace")) { +#ifdef CONFIG_SIMAVR_TRACE + trace++; +#else + fprintf(stderr, + "%s: tracing option '%s' requires " + "compilation option CONFIG_SIMAVR_TRACE.\n", + argv[0], argv[pi]); +#endif //CONFIG_SIMAVR_TRACE + } else if (!strcmp(argv[pi], "-at") || + !strcmp(argv[pi], "--add-trace")) { + if (pi + 1 >= argc) { + fprintf(stderr, "%s: missing mandatory argument for %s.\n", argv[0], argv[pi]); + exit(1); + } + ++pi; + struct { + char kind[64]; + uint8_t mask; + uint16_t addr; + char name[64]; + } trace; + const int n_args = sscanf( + argv[pi], + "%63[^=]=%63[^@]@0x%hx/0x%hhx", + &trace.name[0], + &trace.kind[0], + &trace.addr, + &trace.mask + ); + if (n_args != 4) { + --pi; + fprintf(stderr, "%s: format for %s is name=kind@addr/mask.\n", argv[0], argv[pi]); + exit(1); + } + + /****/ if (!strcmp(trace.kind, "portpin")) { + f.trace[f.tracecount].kind = AVR_MMCU_TAG_VCD_PORTPIN; + } else if (!strcmp(trace.kind, "irq")) { + f.trace[f.tracecount].kind = AVR_MMCU_TAG_VCD_IRQ; + } else if (!strcmp(trace.kind, "trace")) { + f.trace[f.tracecount].kind = AVR_MMCU_TAG_VCD_TRACE; + } else { + fprintf( + stderr, + "%s: unknown trace kind '%s', not one of 'portpin', 'irq', or 'trace'.\n", + argv[0], + trace.kind + ); + exit(1); + } + f.trace[f.tracecount].mask = trace.mask; + f.trace[f.tracecount].addr = trace.addr; + strncpy(f.trace[f.tracecount].name, trace.name, sizeof(f.trace[f.tracecount].name)); + + printf( + "Adding %s trace on address 0x%04x, mask 0x%02x ('%s')\n", + f.trace[f.tracecount].kind == AVR_MMCU_TAG_VCD_PORTPIN ? "portpin" + : f.trace[f.tracecount].kind == AVR_MMCU_TAG_VCD_IRQ ? "irq" + : f.trace[f.tracecount].kind == AVR_MMCU_TAG_VCD_TRACE ? "trace" + : "unknown", + f.trace[f.tracecount].addr, + f.trace[f.tracecount].mask, + f.trace[f.tracecount].name + ); + + ++f.tracecount; + } else if (!strcmp(argv[pi], "-ti")) { + if (pi < argc-1) + trace_vectors[trace_vectors_count++] = atoi(argv[++pi]); + } else if (!strcmp(argv[pi], "-g") || + !strcmp(argv[pi], "--gdb")) { + gdb++; + if (pi < (argc-2) && argv[pi+1][0] != '-' ) + port = atoi(argv[++pi]); + } else if (!strcmp(argv[pi], "-v")) { + log++; + } else if (!strcmp(argv[pi], "-ee")) { + loadBase = AVR_SEGMENT_OFFSET_EEPROM; + } else if (!strcmp(argv[pi], "-ff")) { + loadBase = AVR_SEGMENT_OFFSET_FLASH; + } else if (argv[pi][0] != '-') { + sim_setup_firmware(argv[pi], loadBase, &f, argv[0]); + } + } + + // Frequency and MCU type were set early so they can be checked when + // loading a hex file. Set them again because they can also be set + // in an ELF firmware file. + + if (strlen(name)) + strcpy(f.mmcu, name); + if (f_cpu) + f.frequency = f_cpu; + + avr = avr_make_mcu_by_name(f.mmcu); + if (!avr) { + fprintf(stderr, "%s: AVR '%s' not known\n", argv[0], f.mmcu); + exit(1); + } + avr_init(avr); + avr->log = (log > LOG_TRACE ? LOG_TRACE : log); +#ifdef CONFIG_SIMAVR_TRACE + avr->trace = trace; +#endif //CONFIG_SIMAVR_TRACE + + avr_load_firmware(avr, &f); + if (f.flashbase) { + printf("Attempted to load a bootloader at %04x\n", f.flashbase); + avr->pc = f.flashbase; + } + for (int ti = 0; ti < trace_vectors_count; ti++) { + for (int vi = 0; vi < avr->interrupts.vector_count; vi++) + if (avr->interrupts.vector[vi]->vector == trace_vectors[ti]) + avr->interrupts.vector[vi]->trace = 1; + } + if (vcd_input) { + static avr_vcd_t input; + if (avr_vcd_init_input(avr, vcd_input, &input)) { + fprintf(stderr, "%s: Warning: VCD input file %s failed\n", argv[0], vcd_input); + } + } + + // even if not setup at startup, activate gdb if crashing + avr->gdb_port = port; + if (gdb) { + avr->state = cpu_Stopped; + avr_gdb_init(avr); + } + + signal(SIGINT, sig_int); + signal(SIGTERM, sig_int); + + for (;;) { + int state = avr_run(avr); + if (state == cpu_Done || state == cpu_Crashed) + break; + } + + avr_terminate(avr); +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr.c new file mode 100644 index 0000000..24cb244 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr.c @@ -0,0 +1,453 @@ +/* + sim_avr.c + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <sys/time.h> +#include "sim_avr.h" +#include "sim_core.h" +#include "sim_time.h" +#include "sim_gdb.h" +#include "avr_uart.h" +#include "sim_vcd_file.h" +#include "avr/avr_mcu_section.h" + +#define AVR_KIND_DECL +#include "sim_core_decl.h" + +static void +std_logger( + avr_t * avr, + const int level, + const char * format, + va_list ap); +static avr_logger_p _avr_global_logger = std_logger; + +void +avr_global_logger( + struct avr_t* avr, + const int level, + const char * format, + ... ) +{ + va_list args; + va_start(args, format); + if (_avr_global_logger) + _avr_global_logger(avr, level, format, args); + va_end(args); +} + +void +avr_global_logger_set( + avr_logger_p logger) +{ + _avr_global_logger = logger ? logger : std_logger; +} + +avr_logger_p +avr_global_logger_get(void) +{ + return _avr_global_logger; +} + +uint64_t +avr_get_time_stamp( + avr_t * avr ) +{ + uint64_t stamp; +#ifndef CLOCK_MONOTONIC_RAW + /* CLOCK_MONOTONIC_RAW isn't portable, here is the POSIX alternative. + * Only downside is that it will drift if the system clock changes */ + struct timeval tv; + gettimeofday(&tv, NULL); + stamp = (((uint64_t)tv.tv_sec) * 1E9) + (tv.tv_usec * 1000); +#else + struct timespec tp; + clock_gettime(CLOCK_MONOTONIC_RAW, &tp); + stamp = (tp.tv_sec * 1E9) + tp.tv_nsec; +#endif + if (!avr->time_base) + avr->time_base = stamp; + return stamp - avr->time_base; +} + +int +avr_init( + avr_t * avr) +{ + avr->flash = malloc(avr->flashend + 4); + memset(avr->flash, 0xff, avr->flashend + 1); + *((uint16_t*)&avr->flash[avr->flashend + 1]) = AVR_OVERFLOW_OPCODE; + avr->codeend = avr->flashend; + avr->data = malloc(avr->ramend + 1); + memset(avr->data, 0, avr->ramend + 1); +#ifdef CONFIG_SIMAVR_TRACE + avr->trace_data = calloc(1, sizeof(struct avr_trace_data_t)); +#endif + + AVR_LOG(avr, LOG_TRACE, "%s init\n", avr->mmcu); + + // cpu is in limbo before init is finished. + avr->state = cpu_Limbo; + avr->frequency = 1000000; // can be overridden via avr_mcu_section + avr_cmd_init(avr); + avr_interrupt_init(avr); + if (avr->custom.init) + avr->custom.init(avr, avr->custom.data); + if (avr->init) + avr->init(avr); + // set default (non gdb) fast callbacks + avr->run = avr_callback_run_raw; + avr->sleep = avr_callback_sleep_raw; + // number of address bytes to push/pull on/off the stack + avr->address_size = avr->eind ? 3 : 2; + avr->log = 1; + avr_reset(avr); + avr_regbit_set(avr, avr->reset_flags.porf); // by default set to power-on reset + return 0; +} + +void +avr_terminate( + avr_t * avr) +{ + if (avr->custom.deinit) + avr->custom.deinit(avr, avr->custom.data); + if (avr->gdb) { + avr_deinit_gdb(avr); + avr->gdb = NULL; + } + if (avr->vcd) { + avr_vcd_close(avr->vcd); + avr->vcd = NULL; + } + avr_deallocate_ios(avr); + + if (avr->flash) free(avr->flash); + if (avr->data) free(avr->data); + if (avr->io_console_buffer.buf) { + avr->io_console_buffer.len = 0; + avr->io_console_buffer.size = 0; + free(avr->io_console_buffer.buf); + avr->io_console_buffer.buf = NULL; + } + avr->flash = avr->data = NULL; +} + +void +avr_reset( + avr_t * avr) +{ + AVR_LOG(avr, LOG_TRACE, "%s reset\n", avr->mmcu); + + avr->state = cpu_Running; + for(int i = 0x20; i <= avr->ioend; i++) + avr->data[i] = 0; + _avr_sp_set(avr, avr->ramend); + avr->pc = avr->reset_pc; // Likely to be zero + for (int i = 0; i < 8; i++) + avr->sreg[i] = 0; + avr_interrupt_reset(avr); + avr_cycle_timer_reset(avr); + if (avr->reset) + avr->reset(avr); + avr_io_t * port = avr->io_port; + while (port) { + if (port->reset) + port->reset(port); + port = port->next; + } + avr->cycle = 0; // Prevent crash +} + +void +avr_sadly_crashed( + avr_t *avr, + uint8_t signal) +{ + AVR_LOG(avr, LOG_ERROR, "%s\n", __FUNCTION__); + avr->state = cpu_Stopped; + if (avr->gdb_port) { + // enable gdb server, and wait + if (!avr->gdb) + avr_gdb_init(avr); + } + if (!avr->gdb) + avr->state = cpu_Crashed; +} + +void +avr_set_command_register( + avr_t * avr, + avr_io_addr_t addr) +{ + avr_cmd_set_register(avr, addr); +} + +static void +_avr_io_console_write( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + if (v == '\r' && avr->io_console_buffer.buf) { + avr->io_console_buffer.buf[avr->io_console_buffer.len] = 0; + AVR_LOG(avr, LOG_OUTPUT, "O:" "%s" "" "\n", + avr->io_console_buffer.buf); + avr->io_console_buffer.len = 0; + return; + } + if (avr->io_console_buffer.len + 1 >= avr->io_console_buffer.size) { + avr->io_console_buffer.size += 128; + avr->io_console_buffer.buf = (char*)realloc( + avr->io_console_buffer.buf, + avr->io_console_buffer.size); + } + if (v >= ' ') + avr->io_console_buffer.buf[avr->io_console_buffer.len++] = v; +} + +void +avr_set_console_register( + avr_t * avr, + avr_io_addr_t addr) +{ + if (addr) + avr_register_io_write(avr, addr, _avr_io_console_write, NULL); +} + +void +avr_loadcode( + avr_t * avr, + uint8_t * code, + uint32_t size, + avr_flashaddr_t address) +{ + if ((address + size) > avr->flashend+1) { + AVR_LOG(avr, LOG_ERROR, "avr_loadcode(): Attempted to load code of size %d but flash size is only %d.\n", + size, avr->flashend + 1); + abort(); + } + memcpy(avr->flash + address, code, size); +} + +/** + * Accumulates sleep requests (and returns a sleep time of 0) until + * a minimum count of requested sleep microseconds are reached + * (low amounts cannot be handled accurately). + */ +uint32_t +avr_pending_sleep_usec( + avr_t * avr, + avr_cycle_count_t howLong) +{ + avr->sleep_usec += avr_cycles_to_usec(avr, howLong); + uint32_t usec = avr->sleep_usec; + if (usec > 200) { + avr->sleep_usec = 0; + return usec; + } + return 0; +} + +void +avr_callback_sleep_gdb( + avr_t * avr, + avr_cycle_count_t howLong) +{ + uint32_t usec = avr_pending_sleep_usec(avr, howLong); + while (avr_gdb_processor(avr, usec)) + ; +} + +void +avr_callback_run_gdb( + avr_t * avr) +{ + avr_gdb_processor(avr, avr->state == cpu_Stopped ? 50000 : 0); + + if (avr->state == cpu_Stopped) + return ; + + // if we are stepping one instruction, we "run" for one.. + int step = avr->state == cpu_Step; + if (step) + avr->state = cpu_Running; + + avr_flashaddr_t new_pc = avr->pc; + + if (avr->state == cpu_Running) { + new_pc = avr_run_one(avr); +#if CONFIG_SIMAVR_TRACE + avr_dump_state(avr); +#endif + } + + // run the cycle timers, get the suggested sleep time + // until the next timer is due + avr_cycle_count_t sleep = avr_cycle_timer_process(avr); + + avr->pc = new_pc; + + if (avr->state == cpu_Sleeping) { + if (!avr->sreg[S_I]) { + if (avr->log) + AVR_LOG(avr, LOG_TRACE, "simavr: sleeping with interrupts off, quitting gracefully\n"); + avr->state = cpu_Done; + return; + } + /* + * try to sleep for as long as we can (?) + */ + avr->sleep(avr, sleep); + avr->cycle += 1 + sleep; + } + // Interrupt servicing might change the PC too, during 'sleep' + if (avr->state == cpu_Running || avr->state == cpu_Sleeping) + avr_service_interrupts(avr); + + // if we were stepping, use this state to inform remote gdb + if (step) + avr->state = cpu_StepDone; +} + +/* +To avoid simulated time and wall clock time to diverge over time +this function tries to keep them in sync (roughly) by sleeping +for the time required to match the expected sleep deadline +in wall clock time. +*/ +void +avr_callback_sleep_raw( + avr_t *avr, + avr_cycle_count_t how_long) +{ + /* figure out how long we should wait to match the sleep deadline */ + uint64_t deadline_ns = avr_cycles_to_nsec(avr, avr->cycle + how_long); + uint64_t runtime_ns = avr_get_time_stamp(avr); + if (runtime_ns >= deadline_ns) + return; + uint64_t sleep_us = (deadline_ns - runtime_ns) / 1000; + usleep(sleep_us); + return; +} + +void +avr_callback_run_raw( + avr_t * avr) +{ + avr_flashaddr_t new_pc = avr->pc; + + if (avr->state == cpu_Running) { + new_pc = avr_run_one(avr); +#if CONFIG_SIMAVR_TRACE + avr_dump_state(avr); +#endif + } + + // run the cycle timers, get the suggested sleep time + // until the next timer is due + avr_cycle_count_t sleep = avr_cycle_timer_process(avr); + + avr->pc = new_pc; + + if (avr->state == cpu_Sleeping) { + if (!avr->sreg[S_I]) { + if (avr->log) + AVR_LOG(avr, LOG_TRACE, "simavr: sleeping with interrupts off, quitting gracefully\n"); + avr->state = cpu_Done; + return; + } + /* + * try to sleep for as long as we can (?) + */ + avr->sleep(avr, sleep); + avr->cycle += 1 + sleep; + } + // Interrupt servicing might change the PC too, during 'sleep' + if (avr->state == cpu_Running || avr->state == cpu_Sleeping) { + /* Note: checking interrupt_state here is completely superfluous, however + as interrupt_state tells us all we really need to know, here + a simple check here may be cheaper than a call not needed. */ + if (avr->interrupt_state) + avr_service_interrupts(avr); + } +} + + +int +avr_run( + avr_t * avr) +{ + avr->run(avr); + return avr->state; +} + +avr_t * +avr_core_allocate( + const avr_t * core, + uint32_t coreLen) +{ + uint8_t * b = malloc(coreLen); + memcpy(b, core, coreLen); + return (avr_t *)b; +} + +avr_t * +avr_make_mcu_by_name( + const char *name) +{ + avr_kind_t * maker = NULL; + for (int i = 0; avr_kind[i] && !maker; i++) { + for (int j = 0; avr_kind[i]->names[j]; j++) + if (!strcmp(avr_kind[i]->names[j], name)) { + maker = avr_kind[i]; + break; + } + } + if (!maker) { + AVR_LOG(((avr_t*)0), LOG_ERROR, "%s: AVR '%s' not known\n", __FUNCTION__, name); + return NULL; + } + + avr_t * avr = maker->make(); + AVR_LOG(avr, LOG_TRACE, "Starting %s - flashend %04x ramend %04x e2end %04x\n", + avr->mmcu, avr->flashend, avr->ramend, avr->e2end); + return avr; +} + +static void +std_logger( + avr_t * avr, + const int level, + const char * format, + va_list ap) +{ + if (!avr || avr->log >= level) { + vfprintf((level < LOG_ERROR) ? stdout : stderr, format, ap); + } +} + diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr.h new file mode 100644 index 0000000..e9a97cd --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr.h @@ -0,0 +1,517 @@ +/* + sim_avr.h + + Copyright 2008-2012 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __SIM_AVR_H__ +#define __SIM_AVR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +#if __has_attribute(fallthrough) + #define FALLTHROUGH __attribute__((fallthrough)); +#else + #define FALLTHROUGH +#endif + +#include "sim_irq.h" +#include "sim_interrupts.h" +#include "sim_cmds.h" +#include "sim_cycle_timers.h" + +typedef uint32_t avr_flashaddr_t; + +struct avr_t; +typedef uint8_t (*avr_io_read_t)( + struct avr_t * avr, + avr_io_addr_t addr, + void * param); +typedef void (*avr_io_write_t)( + struct avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param); + +enum { + // SREG bit indexes + S_C = 0,S_Z,S_N,S_V,S_S,S_H,S_T,S_I, + + // 16 bits register pairs + R_XL = 0x1a, R_XH,R_YL,R_YH,R_ZL,R_ZH, + // stack pointer + R_SPL = 32+0x3d, R_SPH, + // real SREG + R_SREG = 32+0x3f, + + // maximum number of IO registers, on normal AVRs + MAX_IOs = 280, // Bigger AVRs need more than 256-32 (mega1280) +}; + +#define AVR_DATA_TO_IO(v) ((v) - 32) +#define AVR_IO_TO_DATA(v) ((v) + 32) + +/** + * Logging macros and associated log levels. + * The current log level is kept in avr->log. + */ +enum { + LOG_NONE = 0, + LOG_OUTPUT, + LOG_ERROR, + LOG_WARNING, + LOG_TRACE, + LOG_DEBUG, +}; + + +#ifndef AVR_LOG +#define AVR_LOG(avr, level, ...) \ + do { \ + avr_global_logger(avr, level, __VA_ARGS__); \ + } while(0) +#endif +#define AVR_TRACE(avr, ... ) \ + AVR_LOG(avr, LOG_TRACE, __VA_ARGS__) + +/* + * Core states. + */ +enum { + cpu_Limbo = 0, // before initialization is finished + cpu_Stopped, // all is stopped, timers included + + cpu_Running, // we're free running + + cpu_Sleeping, // we're now sleeping until an interrupt + + cpu_Step, // run ONE instruction, then... + cpu_StepDone, // tell gdb it's all OK, and give it registers + cpu_Done, // avr software stopped gracefully + cpu_Crashed, // avr software crashed (watchdog fired) +}; + +// this is only ever used if CONFIG_SIMAVR_TRACE is defined +struct avr_trace_data_t { + struct avr_symbol_t ** codeline; + + /* DEBUG ONLY + * this keeps track of "jumps" ie, call,jmp,ret,reti and so on + * allows dumping of a meaningful data even if the stack is + * munched and so on + */ + #define OLD_PC_SIZE 32 + struct { + uint32_t pc; + uint16_t sp; + } old[OLD_PC_SIZE]; // catches reset.. + int old_pci; + +#if AVR_STACK_WATCH + #define STACK_FRAME_SIZE 32 + // this records the call/ret pairs, to try to catch + // code that munches the stack -under- their own frame + struct { + uint32_t pc; + uint16_t sp; + } stack_frame[STACK_FRAME_SIZE]; + int stack_frame_index; +#endif + + // DEBUG ONLY + // keeps track of which registers gets touched by instructions + // reset before each new instructions. Allows meaningful traces + uint32_t touched[256 / 32]; // debug +}; + +typedef void (*avr_run_t)( + struct avr_t * avr); + +#define AVR_FUSE_LOW 0 +#define AVR_FUSE_HIGH 1 +#define AVR_FUSE_EXT 2 + +#define REG_NAME_COUNT (256 + 32) // Size of reg_names table. + +/* + * Main AVR instance. Some of these fields are set by the AVR "Core" definition files + * the rest is runtime data (as little as possible) + */ +typedef struct avr_t { + const char * mmcu; // name of the AVR + // these are filled by sim_core_declare from constants in /usr/lib/avr/include/avr/io*.h + uint16_t ioend; + uint16_t ramend; + uint32_t flashend; + uint32_t e2end; + uint8_t vector_size; + uint8_t signature[3]; + uint8_t fuse[6]; + uint8_t lockbits; + avr_io_addr_t rampz; // optional, only for ELPM/SPM on >64Kb cores + avr_io_addr_t eind; // optional, only for EIJMP/EICALL on >64Kb cores + uint8_t address_size; // 2, or 3 for cores >128KB in flash + struct { + avr_regbit_t porf; + avr_regbit_t extrf; + avr_regbit_t borf; + avr_regbit_t wdrf; + } reset_flags; + + // filled by the ELF data, this allow tracking of invalid jumps + uint32_t codeend; + + int state; // stopped, running, sleeping + uint32_t frequency; // frequency we are running at + // mostly used by the ADC for now + uint32_t vcc,avcc,aref; // (optional) voltages in millivolts + + // cycles gets incremented when sleeping and when running; it corresponds + // not only to "cycles that runs" but also "cycles that might have run" + // like, sleeping. + avr_cycle_count_t cycle; // current cycle + + // these next two allow the core to freely run between cycle timers and also allows + // for a maximum run cycle limit... run_cycle_count is set during cycle timer processing. + avr_cycle_count_t run_cycle_count; // cycles to run before next timer + avr_cycle_count_t run_cycle_limit; // maximum run cycle interval limit + + /** + * Sleep requests are accumulated in sleep_usec until the minimum sleep value + * is reached, at which point sleep_usec is cleared and the sleep request + * is passed on to the operating system. + */ + uint32_t sleep_usec; + uint64_t time_base; // for avr_get_time_stamp() + + // called at init time + void (*init)(struct avr_t * avr); + // called at reset time + void (*reset)(struct avr_t * avr); + + struct { + // called at init time (for special purposes like using a + // memory mapped file as flash see: simduino) + void (*init)(struct avr_t * avr, void * data); + // called at termination time ( to clean special initializations) + void (*deinit)(struct avr_t * avr, void * data); + // value passed to init() and deinit() + void *data; + } custom; + + /*! + * Default AVR core run function. + * Two modes are available, a "raw" run that goes as fast as + * it can, and a "gdb" mode that also watchouts for gdb events + * and is a little bit slower. + */ + avr_run_t run; + + /*! + * Sleep default behaviour. + * In "raw" mode, it calls usleep, in gdb mode, it waits + * for howLong for gdb command on it's sockets. + */ + void (*sleep)(struct avr_t * avr, avr_cycle_count_t howLong); + + /*! + * Every IRQs will be stored in this pool. It is not + * mandatory (yet) but will allow listing IRQs and their connections + */ + avr_irq_pool_t irq_pool; + + // Mirror of the SREG register, to facilitate the access to bits + // in the opcode decoder. + // This array is re-synthesized back/forth when SREG changes + uint8_t sreg[8]; + + /* Interrupt state: + 00: idle (no wait, no pending interrupts) or disabled + <0: wait till zero + >0: interrupt pending */ + int8_t interrupt_state; // interrupt state + + /* + * ** current PC ** + * Note that the PC is representing /bytes/ while the AVR value is + * assumed to be "words". This is in line with what GDB does... + * this is why you will see >>1 and <<1 in the decoder to handle jumps. + * It CAN be a little confusing, so concentrate, young grasshopper. + */ + avr_flashaddr_t pc; + /* + * Reset PC, this is the value used to jump to at reset time, this + * allow support for bootloaders + */ + avr_flashaddr_t reset_pc; + + /* + * callback when specific IO registers are read/written. + * There is one drawback here, there is in way of knowing what is the + * "beginning of useful sram" on a core, so there is no way to deduce + * what is the maximum IO register for a core, and thus, we can't + * allocate this table dynamically. + * If you wanted to emulate the BIG AVRs, and XMegas, this would need + * work. + */ + struct { + struct avr_irq_t * irq; // optional, used only if asked for with avr_iomem_getirq() + struct { + void * param; + avr_io_read_t c; + } r; + struct { + void * param; + avr_io_write_t c; + } w; + } io[MAX_IOs]; + + /* + * This block allows sharing of the IO write/read on addresses between + * multiple callbacks. In 99% of case it's not needed, however on the tiny* + * (tiny85 at last) some registers have bits that are used by different + * IO modules. + * If this case is detected, a special "dispatch" callback is installed that + * will handle this particular case, without impacting the performance of the + * other, normal cases... + */ + int io_shared_io_count; + struct { + int used; + struct { + void * param; + void * c; + } io[4]; + } io_shared_io[4]; + + // flash memory (initialized to 0xff, and code loaded into it) + uint8_t * flash; + // this is the general purpose registers, IO registers, and SRAM + uint8_t * data; + + // queue of io modules + struct avr_io_t * io_port; + + // Builtin and user-defined commands + avr_cmd_table_t commands; + // cycle timers tracking & delivery + avr_cycle_timer_pool_t cycle_timers; + // interrupt vectors and delivery fifo + avr_int_table_t interrupts; + + // DEBUG ONLY -- value ignored if CONFIG_SIMAVR_TRACE = 0 + uint8_t trace : 1, + log : 4; // log level, default to 1 + + // Only used if CONFIG_SIMAVR_TRACE is defined + struct avr_trace_data_t *trace_data; + + // VALUE CHANGE DUMP file (waveforms) + // this is the VCD file that gets allocated if the + // firmware that is loaded explicitly asks for a trace + // to be generated, and allocates it's own symbols + // using AVR_MMCU_TAG_VCD_TRACE (see avr_mcu_section.h) + struct avr_vcd_t * vcd; + + // gdb hooking structure. Only present when gdb server is active + struct avr_gdb_t * gdb; + + // if non-zero, the gdb server will be started when the core + // crashed even if not activated at startup + // if zero, the simulator will just exit() in case of a crash + int gdb_port; + + // buffer for console debugging output from register + struct { + char * buf; + uint32_t size; + uint32_t len; + } io_console_buffer; +} avr_t; + + +// this is a static constructor for each of the AVR devices +typedef struct avr_kind_t { + const char * names[4]; // name aliases + avr_t * (*make)(void); +} avr_kind_t; + +// a symbol loaded from the .elf file +typedef struct avr_symbol_t { + uint32_t addr; + uint32_t size; + const char symbol[0]; +} avr_symbol_t; + +// locate the maker for mcu "name" and allocates a new avr instance +avr_t * +avr_make_mcu_by_name( + const char *name); +// initializes a new AVR instance. Will call the IO registers init(), and then reset() +int +avr_init( + avr_t * avr); +// Used by the cores, allocated a mutable avr_t from the const global +avr_t * +avr_core_allocate( + const avr_t * core, + uint32_t coreLen); + +// resets the AVR, and the IO modules +void +avr_reset( + avr_t * avr); +// run one cycle of the AVR, sleep if necessary +int +avr_run( + avr_t * avr); +// finish any pending operations +void +avr_terminate( + avr_t * avr); + +// set an IO register to receive commands from the AVR firmware +// it's optional, and uses the ELF tags +void +avr_set_command_register( + avr_t * avr, + avr_io_addr_t addr); + +// specify the "console register" -- output sent to this register +// is printed on the simulator console, without using a UART +void +avr_set_console_register( + avr_t * avr, + avr_io_addr_t addr); + +// load code in the "flash" +void +avr_loadcode( + avr_t * avr, + uint8_t * code, + uint32_t size, + avr_flashaddr_t address); + +/* + * These are accessors for avr->data but allows watchpoints to be set for gdb + * IO modules use that to set values to registers, and the AVR core decoder uses + * that to register "public" read by instructions. + */ +void +avr_core_watch_write( + avr_t *avr, + uint16_t addr, + uint8_t v); +uint8_t +avr_core_watch_read( + avr_t *avr, + uint16_t addr); + +// called when the core has detected a crash somehow. +// this might activate gdb server +void +avr_sadly_crashed( + avr_t *avr, + uint8_t signal); + +/* + * Logs a message using the current logger + */ +void +avr_global_logger( + struct avr_t* avr, + const int level, + const char * format, + ... ); + +#ifndef AVR_CORE +#include <stdarg.h> +/* + * Type for custom logging functions + */ +typedef void (*avr_logger_p)(struct avr_t* avr, const int level, const char * format, va_list ap); + +/* Sets a global logging function in place of the default */ +void +avr_global_logger_set( + avr_logger_p logger); +/* Gets the current global logger function */ +avr_logger_p +avr_global_logger_get(void); +#endif + +/* + * These are callbacks for the two 'main' behaviour in simavr + */ +void avr_callback_sleep_gdb(avr_t * avr, avr_cycle_count_t howLong); +void avr_callback_run_gdb(avr_t * avr); +void avr_callback_sleep_raw(avr_t * avr, avr_cycle_count_t howLong); +void avr_callback_run_raw(avr_t * avr); + +/** + * Accumulates sleep requests (and returns a sleep time of 0) until + * a minimum count of requested sleep microseconds are reached + * (low amounts cannot be handled accurately). + * This function is an utility function for the sleep callbacks + */ +uint32_t +avr_pending_sleep_usec( + avr_t * avr, + avr_cycle_count_t howLong); +/* Return the number of 'real time' spent since sim started, in uS */ +uint64_t +avr_get_time_stamp( + avr_t * avr ); + +#ifdef __cplusplus +}; +#endif + +#include "sim_io.h" +#include "sim_regbit.h" + +#ifdef __GNUC__ + +# ifndef likely +# define likely(x) __builtin_expect(!!(x), 1) +# endif + +# ifndef unlikely +# define unlikely(x) __builtin_expect(!!(x), 0) +# endif + +#else /* ! __GNUC__ */ + +# ifndef likely +# define likely(x) x +# endif + +# ifndef unlikely +# define unlikely(x) x +# endif + +#endif /* __GNUC__ */ + +#endif /*__SIM_AVR_H__*/ + diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr_types.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr_types.h new file mode 100644 index 0000000..b15bafc --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr_types.h @@ -0,0 +1,57 @@ +/* + sim_avr_types.h + + Copyright 2008-2012 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef __SIM_AVR_TYPES_H___ +#define __SIM_AVR_TYPES_H___ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include <inttypes.h> + +typedef uint64_t avr_cycle_count_t; +typedef uint16_t avr_io_addr_t; + +/* + * this 'structure' is a packed representation of an IO register 'bit' + * (or consecutive bits). This allows a way to set/get/clear them. + * gcc is happy passing these as register value, so you don't need to + * use a pointer when passing them along to functions. + * + * 9 bits ought to be enough, as it's the maximum I've seen (atmega2560) + */ +typedef struct avr_regbit_t { + uint32_t reg : 9, bit : 3, mask : 8; +} avr_regbit_t; + +// printf() conversion specifier for avr_cycle_count_t +#define PRI_avr_cycle_count PRIu64 + +struct avr_t; + +#ifdef __cplusplus +}; +#endif + +#endif /* __SIM_AVR_TYPES_H___ */ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cmds.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cmds.c new file mode 100644 index 0000000..587f259 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cmds.c @@ -0,0 +1,193 @@ +/* + sim_cmds.c + + Copyright 2014 Florian Albrechtskirchinger <falbrechtskirchinger@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <stdlib.h> +#include <string.h> +#include "sim_avr.h" +#include "sim_cmds.h" +#include "sim_vcd_file.h" +#include "avr_uart.h" +#include "avr/avr_mcu_section.h" + +#define LOG_PREFIX "CMDS: " + +static void +_avr_cmd_io_write( + avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + avr_cmd_table_t * commands = &avr->commands; + avr_cmd_t * command = commands->pending; + + AVR_LOG(avr, LOG_TRACE, LOG_PREFIX "%s: 0x%02x\n", __FUNCTION__, v); + + if (!command) { + if (v > MAX_AVR_COMMANDS) { + AVR_LOG(avr, LOG_ERROR, LOG_PREFIX + "%s: code 0x%02x outside permissible range (>0x%02x)\n", + __FUNCTION__, v, MAX_AVR_COMMANDS - 1); + return; + } + command = &commands->table[v]; + } + if (!command->handler) { + AVR_LOG(avr, LOG_ERROR, LOG_PREFIX + "%s: code 0x%02x has no handler (wrong MMCU config)\n", + __FUNCTION__, v); + return; + } + + if (command) { + if (command->handler(avr, v, command->param)) + commands->pending = command; + else + commands->pending = NULL; + } else + AVR_LOG(avr, LOG_TRACE, LOG_PREFIX "%s: unknown command 0x%02x\n", + __FUNCTION__, v); +} + +void +avr_cmd_set_register( + avr_t * avr, + avr_io_addr_t addr) +{ + if (addr) + avr_register_io_write(avr, addr, &_avr_cmd_io_write, NULL); +} + +void +avr_cmd_register( + avr_t * avr, + uint8_t code, + avr_cmd_handler_t handler, + void * param) +{ + avr_cmd_table_t * commands = &avr->commands; + avr_cmd_t * command; + + if (!handler) + return; + + if (code > MAX_AVR_COMMANDS) { + AVR_LOG(avr, LOG_ERROR, LOG_PREFIX + "%s: code 0x%02x outside permissible range (>0x%02x)\n", + __FUNCTION__, code, MAX_AVR_COMMANDS - 1); + return; + } + + command = &commands->table[code]; + if (command->handler) { + AVR_LOG(avr, LOG_ERROR, LOG_PREFIX + "%s: code 0x%02x is already registered\n", + __FUNCTION__, code); + return; + } + + command->handler = handler; + command->param = param; +} + +void +avr_cmd_unregister( + avr_t * avr, + uint8_t code) +{ + avr_cmd_table_t * commands = &avr->commands; + avr_cmd_t * command; + + if (code > MAX_AVR_COMMANDS) { + AVR_LOG(avr, LOG_ERROR, LOG_PREFIX + "%s: code 0x%02x outside permissible range (>0x%02x)\n", + __FUNCTION__, code, MAX_AVR_COMMANDS - 1); + return; + } + + command = &commands->table[code]; + if (command->handler) { + if(command->param) + free(command->param); + + command->handler = NULL; + command->param = NULL; + } else + AVR_LOG(avr, LOG_ERROR, LOG_PREFIX + "%s: no command registered for code 0x%02x\n", + __FUNCTION__, code); +} + +static int +_simavr_cmd_vcd_start_trace( + avr_t * avr, + uint8_t v, + void * param) +{ + if (avr->vcd) + avr_vcd_start(avr->vcd); + + return 0; +} + +static int +_simavr_cmd_vcd_stop_trace( + avr_t * avr, + uint8_t v, + void * param) +{ + if (avr->vcd) + avr_vcd_stop(avr->vcd); + + return 0; +} + +static int +_simavr_cmd_uart_loopback( + avr_t * avr, + uint8_t v, + void * param) +{ + avr_irq_t * src = avr_io_getirq(avr, AVR_IOCTL_UART_GETIRQ('0'), UART_IRQ_OUTPUT); + avr_irq_t * dst = avr_io_getirq(avr, AVR_IOCTL_UART_GETIRQ('0'), UART_IRQ_INPUT); + + if(src && dst) { + AVR_LOG(avr, LOG_TRACE, LOG_PREFIX + "%s: activating uart local echo; IRQ src %p dst %p\n", + __FUNCTION__, src, dst); + avr_connect_irq(src, dst); + } + + return 0; +} + +void +avr_cmd_init( + avr_t * avr) +{ + memset(&avr->commands, 0, sizeof(avr->commands)); + + // Register builtin commands + avr_cmd_register(avr, SIMAVR_CMD_VCD_START_TRACE, &_simavr_cmd_vcd_start_trace, NULL); + avr_cmd_register(avr, SIMAVR_CMD_VCD_STOP_TRACE, &_simavr_cmd_vcd_stop_trace, NULL); + avr_cmd_register(avr, SIMAVR_CMD_UART_LOOPBACK, &_simavr_cmd_uart_loopback, NULL); +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cmds.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cmds.h new file mode 100644 index 0000000..aac75fc --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cmds.h @@ -0,0 +1,82 @@ +/* + sim_cmds.h + + Copyright 2014 Florian Albrechtskirchinger <falbrechtskirchinger@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "sim_avr_types.h" + +#define MAX_AVR_COMMANDS 32 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int (*avr_cmd_handler_t)( + struct avr_t * avr, + uint8_t v, + void * param); + +typedef struct avr_cmd_t { + avr_cmd_handler_t handler; + void * param; +} avr_cmd_t; + +typedef struct avr_cmd_table_t { + avr_cmd_t table[MAX_AVR_COMMANDS]; + avr_cmd_t * pending; // Holds a reference to a pending multi-byte command +} avr_cmd_table_t; + +// Called by avr_set_command_register() +void +avr_cmd_set_register( + struct avr_t * avr, + avr_io_addr_t addr); + +/* + * Register a command distinguished by 'code'. + * + * When 'code' is written to the configured IO address, 'handler' is executed + * with the value written, as well as 'param'. + * 'handler' can return non-zero, to indicate, that this is a multi-byte command. + * Subsequent writes are then dispatched to the same handler, until 0 is returned. + */ +void +avr_cmd_register( + struct avr_t * avr, + uint8_t code, + avr_cmd_handler_t handler, + void * param); + +void +avr_cmd_unregister( + struct avr_t * avr, + uint8_t code); + +// Private functions + +// Called from avr_init() to initialize the avr_cmd_table_t and register builtin commands. +void +avr_cmd_init( + struct avr_t * avr); + +#ifdef __cplusplus +} +#endif diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_core.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_core.c new file mode 100644 index 0000000..ab8015c --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_core.c @@ -0,0 +1,1457 @@ +/* + sim_core.c + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include "sim_avr.h" +#include "sim_core.h" +#include "sim_gdb.h" +#include "avr_flash.h" +#include "avr_watchdog.h" + +// SREG bit names +const char * _sreg_bit_name = "cznvshti"; + +/* + * Handle "touching" registers, marking them changed. + * This is used only for debugging purposes to be able to + * print the effects of each instructions on registers + */ +#if CONFIG_SIMAVR_TRACE + +#define T(w) w + +#define REG_TOUCH(a, r) (a)->trace_data->touched[(r) >> 5] |= (1 << ((r) & 0x1f)) +#define REG_ISTOUCHED(a, r) ((a)->trace_data->touched[(r) >> 5] & (1 << ((r) & 0x1f))) + +/* + * This allows a "special case" to skip instruction tracing when in these + * symbols since printf() is useful to have, but generates a lot of cycles. + */ +int dont_trace(const char * name) +{ + return ( + !strcmp(name, "uart_putchar") || + !strcmp(name, "fputc") || + !strcmp(name, "printf") || + !strcmp(name, "vfprintf") || + !strcmp(name, "__ultoa_invert") || + !strcmp(name, "__prologue_saves__") || + !strcmp(name, "__epilogue_restores__")); +} + +int donttrace = 0; + +#define STATE(_f, args...) { \ + if (avr->trace) {\ + if (avr->trace_data->codeline && avr->trace_data->codeline[avr->pc>>1]) {\ + const char * symn = avr->trace_data->codeline[avr->pc>>1]->symbol; \ + int dont = 0 && dont_trace(symn);\ + if (dont!=donttrace) { \ + donttrace = dont;\ + DUMP_REG();\ + }\ + if (donttrace==0)\ + printf("%04x: %-25s " _f, avr->pc, symn, ## args);\ + } else \ + printf("%s: %04x: " _f, __FUNCTION__, avr->pc, ## args);\ + }\ + } +#define SREG() if (avr->trace && donttrace == 0) {\ + printf("%04x: \t\t\t\t\t\t\t\t\tSREG = ", avr->pc); \ + for (int _sbi = 0; _sbi < 8; _sbi++)\ + printf("%c", avr->sreg[_sbi] ? toupper(_sreg_bit_name[_sbi]) : '.');\ + printf("\n");\ +} + +void crash(avr_t* avr) +{ + DUMP_REG(); + printf("*** CYCLE %" PRI_avr_cycle_count "PC %04x\n", avr->cycle, avr->pc); + + for (int i = OLD_PC_SIZE-1; i > 0; i--) { + int pci = (avr->trace_data->old_pci + i) & 0xf; + printf(FONT_RED "*** %04x: %-25s RESET -%d; sp %04x\n" FONT_DEFAULT, + avr->trace_data->old[pci].pc, avr->trace_data->codeline ? avr->trace_data->codeline[avr->trace_data->old[pci].pc>>1]->symbol : "unknown", OLD_PC_SIZE-i, avr->trace_data->old[pci].sp); + } + + printf("Stack Ptr %04x/%04x = %d \n", _avr_sp_get(avr), avr->ramend, avr->ramend - _avr_sp_get(avr)); + DUMP_STACK(); + + avr_sadly_crashed(avr, 0); +} +#else +#define T(w) +#define REG_TOUCH(a, r) +#define STATE(_f, args...) +#define SREG() + +void crash(avr_t* avr) +{ + avr_sadly_crashed(avr, 0); + +} +#endif + +static inline uint16_t +_avr_flash_read16le( + avr_t * avr, + avr_flashaddr_t addr) +{ + return(avr->flash[addr] | (avr->flash[addr + 1] << 8)); +} + +static inline void _call_register_irqs(avr_t * avr, uint16_t addr) +{ + if (addr > 31 && addr < 31 + MAX_IOs) { + avr_io_addr_t io = AVR_DATA_TO_IO(addr); + + if (avr->io[io].irq) { + uint8_t v = avr->data[addr]; + avr_raise_irq(avr->io[io].irq + AVR_IOMEM_IRQ_ALL, v); + for (int i = 0; i < 8; i++) + avr_raise_irq(avr->io[io].irq + i, (v >> i) & 1); + } + } +} + +void avr_core_watch_write(avr_t *avr, uint16_t addr, uint8_t v) +{ + if (addr > avr->ramend) { + AVR_LOG(avr, LOG_WARNING, + "CORE: *** Wrapping write address " + "PC=%04x SP=%04x O=%04x v=%02x Address %04x %% %04x --> %04x\n", + avr->pc, _avr_sp_get(avr), _avr_flash_read16le(avr, avr->pc), v, addr, (avr->ramend + 1), addr % (avr->ramend + 1)); + addr = addr % (avr->ramend + 1); + } + if (addr < 32) { + AVR_LOG(avr, LOG_ERROR, FONT_RED + "CORE: *** Invalid write address PC=%04x SP=%04x O=%04x Address %04x=%02x low registers\n" + FONT_DEFAULT, + avr->pc, _avr_sp_get(avr), _avr_flash_read16le(avr, avr->pc), addr, v); + crash(avr); + } +#if AVR_STACK_WATCH + /* + * this checks that the current "function" is not doctoring the stack frame that is located + * higher on the stack than it should be. It's a sign of code that has overrun it's stack + * frame and is munching on it's own return address. + */ + if (avr->trace_data->stack_frame_index > 1 && addr > avr->trace_data->stack_frame[avr->trace_data->stack_frame_index-2].sp) { + printf( FONT_RED "%04x : munching stack " + "SP %04x, A=%04x <= %02x\n" FONT_DEFAULT, + avr->pc, _avr_sp_get(avr), addr, v); + } +#endif + + if (avr->gdb) { + avr_gdb_handle_watchpoints(avr, addr, AVR_GDB_WATCH_WRITE); + } + + avr->data[addr] = v; + _call_register_irqs(avr, addr); +} + +uint8_t avr_core_watch_read(avr_t *avr, uint16_t addr) +{ + if (addr > avr->ramend) { + AVR_LOG(avr, LOG_WARNING, + "CORE: *** Wrapping read address " + "PC=%04x SP=%04x O=%04x Address %04x %% %04x --> %04x\n" + FONT_DEFAULT, + avr->pc, _avr_sp_get(avr), _avr_flash_read16le(avr, avr->pc), + addr, (avr->ramend + 1), addr % (avr->ramend + 1)); + addr = addr % (avr->ramend + 1); + } + + if (avr->gdb) { + avr_gdb_handle_watchpoints(avr, addr, AVR_GDB_WATCH_READ); + } + +// _call_register_irqs(avr, addr); + return avr->data[addr]; +} + +/* + * Set a register (r < 256) + * if it's an IO register (> 31) also (try to) call any callback that was + * registered to track changes to that register. + */ +static inline void _avr_set_r(avr_t * avr, uint16_t r, uint8_t v) +{ + REG_TOUCH(avr, r); + + if (r == R_SREG) { + avr->data[R_SREG] = v; + // unsplit the SREG + SET_SREG_FROM(avr, v); + SREG(); + } + if (r > 31) { + avr_io_addr_t io = AVR_DATA_TO_IO(r); + if (avr->io[io].w.c) { + avr->io[io].w.c(avr, r, v, avr->io[io].w.param); + } else { + avr->data[r] = v; + if (avr->io[io].irq) { + avr_raise_irq(avr->io[io].irq + AVR_IOMEM_IRQ_ALL, v); + for (int i = 0; i < 8; i++) + avr_raise_irq(avr->io[io].irq + i, (v >> i) & 1); + } + } + } else + avr->data[r] = v; +} + +static inline void +_avr_set_r16le( + avr_t * avr, + uint16_t r, + uint16_t v) +{ + _avr_set_r(avr, r, v); + _avr_set_r(avr, r + 1, v >> 8); +} + +static inline void +_avr_set_r16le_hl( + avr_t * avr, + uint16_t r, + uint16_t v) +{ + _avr_set_r(avr, r + 1, v >> 8); + _avr_set_r(avr, r , v); +} + +/* + * Stack pointer access + */ +inline uint16_t _avr_sp_get(avr_t * avr) +{ + return avr->data[R_SPL] | (avr->data[R_SPH] << 8); +} + +inline void _avr_sp_set(avr_t * avr, uint16_t sp) +{ + _avr_set_r16le(avr, R_SPL, sp); +} + +/* + * Set any address to a value; split between registers and SRAM + */ +static inline void _avr_set_ram(avr_t * avr, uint16_t addr, uint8_t v) +{ + if (addr <= avr->ioend) + _avr_set_r(avr, addr, v); + else + avr_core_watch_write(avr, addr, v); +} + +/* + * Get a value from SRAM. + */ +static inline uint8_t _avr_get_ram(avr_t * avr, uint16_t addr) +{ + if (addr == R_SREG) { + /* + * SREG is special it's reconstructed when read + * while the core itself uses the "shortcut" array + */ + READ_SREG_INTO(avr, avr->data[R_SREG]); + + } else if (addr > 31 && addr < 31 + MAX_IOs) { + avr_io_addr_t io = AVR_DATA_TO_IO(addr); + + if (avr->io[io].r.c) + avr->data[addr] = avr->io[io].r.c(avr, addr, avr->io[io].r.param); +#if 0 + if (avr->io[io].irq) { + uint8_t v = avr->data[addr]; + avr_raise_irq(avr->io[io].irq + AVR_IOMEM_IRQ_ALL, v); + for (int i = 0; i < 8; i++) + avr_raise_irq(avr->io[io].irq + i, (v >> i) & 1); + } +#endif + } + return avr_core_watch_read(avr, addr); +} + +/* + * Stack push accessors. + */ +static inline void _avr_push8(avr_t * avr, uint16_t v) +{ + uint16_t sp = _avr_sp_get(avr); + _avr_set_ram(avr, sp, v); + _avr_sp_set(avr, sp-1); +} + +static inline uint8_t _avr_pop8(avr_t * avr) +{ + uint16_t sp = _avr_sp_get(avr) + 1; + uint8_t res = _avr_get_ram(avr, sp); + _avr_sp_set(avr, sp); + return res; +} + +int _avr_push_addr(avr_t * avr, avr_flashaddr_t addr) +{ + uint16_t sp = _avr_sp_get(avr); + addr >>= 1; + for (int i = 0; i < avr->address_size; i++, addr >>= 8, sp--) { + _avr_set_ram(avr, sp, addr); + } + _avr_sp_set(avr, sp); + return avr->address_size; +} + +avr_flashaddr_t _avr_pop_addr(avr_t * avr) +{ + uint16_t sp = _avr_sp_get(avr) + 1; + avr_flashaddr_t res = 0; + for (int i = 0; i < avr->address_size; i++, sp++) { + res = (res << 8) | _avr_get_ram(avr, sp); + } + res <<= 1; + _avr_sp_set(avr, sp -1); + return res; +} + +/* + * "Pretty" register names + */ +const char * reg_names[REG_NAME_COUNT] = { + [R_XH] = "XH", [R_XL] = "XL", + [R_YH] = "YH", [R_YL] = "YL", + [R_ZH] = "ZH", [R_ZL] = "ZL", + [R_SPH] = "SPH", [R_SPL] = "SPL", + [R_SREG] = "SREG", +}; + + +const char * avr_regname(unsigned int reg) +{ + if (!reg_names[reg]) { + char tt[16]; + if (reg < 32) + sprintf(tt, "r%d", reg); + else + sprintf(tt, "io:%02x", reg); + reg_names[reg] = strdup(tt); + } + return reg_names[reg]; +} + +/* + * Called when an invalid opcode is decoded + */ +static void _avr_invalid_opcode(avr_t * avr) +{ +#if CONFIG_SIMAVR_TRACE + printf( FONT_RED "*** %04x: %-25s Invalid Opcode SP=%04x O=%04x \n" FONT_DEFAULT, + avr->pc, avr->trace_data->codeline[avr->pc>>1]->symbol, _avr_sp_get(avr), _avr_flash_read16le(avr, avr->pc)); +#else + AVR_LOG(avr, LOG_ERROR, FONT_RED "CORE: *** %04x: Invalid Opcode SP=%04x O=%04x \n" FONT_DEFAULT, + avr->pc, _avr_sp_get(avr), _avr_flash_read16le(avr, avr->pc)); +#endif +} + +#if CONFIG_SIMAVR_TRACE +/* + * Dump changed registers when tracing + */ +void avr_dump_state(avr_t * avr) +{ + if (!avr->trace || donttrace) + return; + + int doit = 0; + + for (int r = 0; r < 3 && !doit; r++) + if (avr->trace_data->touched[r]) + doit = 1; + if (!doit) + return; + printf(" ->> "); + const int r16[] = { R_SPL, R_XL, R_YL, R_ZL }; + for (int i = 0; i < 4; i++) + if (REG_ISTOUCHED(avr, r16[i]) || REG_ISTOUCHED(avr, r16[i]+1)) { + REG_TOUCH(avr, r16[i]); + REG_TOUCH(avr, r16[i]+1); + } + + for (int i = 0; i < 3*32; i++) + if (REG_ISTOUCHED(avr, i)) { + printf("%s=%02x ", avr_regname(i), avr->data[i]); + } + printf("\n"); +} +#endif + +#define get_d5(o) \ + const uint8_t d = (o >> 4) & 0x1f; + +#define get_vd5(o) \ + get_d5(o) \ + const uint8_t vd = avr->data[d]; + +#define get_r5(o) \ + const uint8_t r = ((o >> 5) & 0x10) | (o & 0xf); + +#define get_d5_a6(o) \ + get_d5(o); \ + const uint8_t A = ((((o >> 9) & 3) << 4) | ((o) & 0xf)) + 32; + +#define get_vd5_s3(o) \ + get_vd5(o); \ + const uint8_t s = o & 7; + +#define get_vd5_s3_mask(o) \ + get_vd5_s3(o); \ + const uint8_t mask = 1 << s; + +#define get_vd5_vr5(o) \ + get_r5(o); \ + get_d5(o); \ + const uint8_t vd = avr->data[d], vr = avr->data[r]; + +#define get_d5_vr5(o) \ + get_d5(o); \ + get_r5(o); \ + const uint8_t vr = avr->data[r]; + +#define get_h4_k8(o) \ + const uint8_t h = 16 + ((o >> 4) & 0xf); \ + const uint8_t k = ((o & 0x0f00) >> 4) | (o & 0xf); + +#define get_vh4_k8(o) \ + get_h4_k8(o) \ + const uint8_t vh = avr->data[h]; + +#define get_d5_q6(o) \ + get_d5(o) \ + const uint8_t q = ((o & 0x2000) >> 8) | ((o & 0x0c00) >> 7) | (o & 0x7); + +#define get_io5(o) \ + const uint8_t io = ((o >> 3) & 0x1f) + 32; + +#define get_io5_b3(o) \ + get_io5(o); \ + const uint8_t b = o & 0x7; + +#define get_io5_b3mask(o) \ + get_io5(o); \ + const uint8_t mask = 1 << (o & 0x7); + +// const int16_t o = ((int16_t)(op << 4)) >> 3; // CLANG BUG! +#define get_o12(op) \ + const int16_t o = ((int16_t)((op << 4) & 0xffff)) >> 3; + +#define get_vp2_k6(o) \ + const uint8_t p = 24 + ((o >> 3) & 0x6); \ + const uint8_t k = ((o & 0x00c0) >> 2) | (o & 0xf); \ + const uint16_t vp = avr->data[p] | (avr->data[p + 1] << 8); + +#define get_sreg_bit(o) \ + const uint8_t b = (o >> 4) & 7; + +/* + * Add a "jump" address to the jump trace buffer + */ +#if CONFIG_SIMAVR_TRACE +#define TRACE_JUMP()\ + avr->trace_data->old[avr->trace_data->old_pci].pc = avr->pc;\ + avr->trace_data->old[avr->trace_data->old_pci].sp = _avr_sp_get(avr);\ + avr->trace_data->old_pci = (avr->trace_data->old_pci + 1) & (OLD_PC_SIZE-1);\ + +#if AVR_STACK_WATCH +#define STACK_FRAME_PUSH()\ + avr->trace_data->stack_frame[avr->trace_data->stack_frame_index].pc = avr->pc;\ + avr->trace_data->stack_frame[avr->trace_data->stack_frame_index].sp = _avr_sp_get(avr);\ + avr->trace_data->stack_frame_index++; +#define STACK_FRAME_POP()\ + if (avr->trace_data->stack_frame_index > 0) \ + avr->trace_data->stack_frame_index--; +#else +#define STACK_FRAME_PUSH() +#define STACK_FRAME_POP() +#endif +#else /* CONFIG_SIMAVR_TRACE */ + +#define TRACE_JUMP() +#define STACK_FRAME_PUSH() +#define STACK_FRAME_POP() + +#endif + +/****************************************************************************\ + * + * Helper functions for calculating the status register bit values. + * See the Atmel data sheet for the instruction set for more info. + * +\****************************************************************************/ + +static void +_avr_flags_zns (struct avr_t * avr, uint8_t res) +{ + avr->sreg[S_Z] = res == 0; + avr->sreg[S_N] = (res >> 7) & 1; + avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V]; +} + +static void +_avr_flags_zns16 (struct avr_t * avr, uint16_t res) +{ + avr->sreg[S_Z] = res == 0; + avr->sreg[S_N] = (res >> 15) & 1; + avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V]; +} + +static void +_avr_flags_add_zns (struct avr_t * avr, uint8_t res, uint8_t rd, uint8_t rr) +{ + /* carry & half carry */ + uint8_t add_carry = (rd & rr) | (rr & ~res) | (~res & rd); + avr->sreg[S_H] = (add_carry >> 3) & 1; + avr->sreg[S_C] = (add_carry >> 7) & 1; + + /* overflow */ + avr->sreg[S_V] = (((rd & rr & ~res) | (~rd & ~rr & res)) >> 7) & 1; + + /* zns */ + _avr_flags_zns(avr, res); +} + + +static void +_avr_flags_sub_zns (struct avr_t * avr, uint8_t res, uint8_t rd, uint8_t rr) +{ + /* carry & half carry */ + uint8_t sub_carry = (~rd & rr) | (rr & res) | (res & ~rd); + avr->sreg[S_H] = (sub_carry >> 3) & 1; + avr->sreg[S_C] = (sub_carry >> 7) & 1; + + /* overflow */ + avr->sreg[S_V] = (((rd & ~rr & ~res) | (~rd & rr & res)) >> 7) & 1; + + /* zns */ + _avr_flags_zns(avr, res); +} + +static void +_avr_flags_Rzns (struct avr_t * avr, uint8_t res) +{ + if (res) + avr->sreg[S_Z] = 0; + avr->sreg[S_N] = (res >> 7) & 1; + avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V]; +} + +static void +_avr_flags_sub_Rzns (struct avr_t * avr, uint8_t res, uint8_t rd, uint8_t rr) +{ + /* carry & half carry */ + uint8_t sub_carry = (~rd & rr) | (rr & res) | (res & ~rd); + avr->sreg[S_H] = (sub_carry >> 3) & 1; + avr->sreg[S_C] = (sub_carry >> 7) & 1; + + /* overflow */ + avr->sreg[S_V] = (((rd & ~rr & ~res) | (~rd & rr & res)) >> 7) & 1; + + _avr_flags_Rzns(avr, res); +} + +static void +_avr_flags_zcvs (struct avr_t * avr, uint8_t res, uint8_t vr) +{ + avr->sreg[S_Z] = res == 0; + avr->sreg[S_C] = vr & 1; + avr->sreg[S_V] = avr->sreg[S_N] ^ avr->sreg[S_C]; + avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V]; +} + +static void +_avr_flags_zcnvs (struct avr_t * avr, uint8_t res, uint8_t vr) +{ + avr->sreg[S_Z] = res == 0; + avr->sreg[S_C] = vr & 1; + avr->sreg[S_N] = res >> 7; + avr->sreg[S_V] = avr->sreg[S_N] ^ avr->sreg[S_C]; + avr->sreg[S_S] = avr->sreg[S_N] ^ avr->sreg[S_V]; +} + +static void +_avr_flags_znv0s (struct avr_t * avr, uint8_t res) +{ + avr->sreg[S_V] = 0; + _avr_flags_zns(avr, res); +} + +static inline int _avr_is_instruction_32_bits(avr_t * avr, avr_flashaddr_t pc) +{ + uint16_t o = _avr_flash_read16le(avr, pc) & 0xfe0f; + return o == 0x9200 || // STS ! Store Direct to Data Space + o == 0x9000 || // LDS Load Direct from Data Space + o == 0x940c || // JMP Long Jump + o == 0x940d || // JMP Long Jump + o == 0x940e || // CALL Long Call to sub + o == 0x940f; // CALL Long Call to sub +} + +/* + * Main opcode decoder + * + * The decoder was written by following the datasheet in no particular order. + * As I went along, I noticed "bit patterns" that could be used to factor opcodes + * However, a lot of these only became apparent later on, so SOME instructions + * (skip of bit set etc) are compact, and some could use some refactoring (the ALU + * ones scream to be factored). + * I assume that the decoder could easily be 2/3 of it's current size. + * + * + It lacks the "extended" XMega jumps. + * + It also doesn't check whether the core it's + * emulating is supposed to have the fancy instructions, like multiply and such. + * + * The number of cycles taken by instruction has been added, but might not be + * entirely accurate. + */ +avr_flashaddr_t avr_run_one(avr_t * avr) +{ +run_one_again: +#if CONFIG_SIMAVR_TRACE + /* + * this traces spurious reset or bad jumps + */ + if ((avr->pc == 0 && avr->cycle > 0) || avr->pc >= avr->codeend || _avr_sp_get(avr) > avr->ramend) { +// avr->trace = 1; + STATE("RESET\n"); + crash(avr); + } + avr->trace_data->touched[0] = avr->trace_data->touched[1] = avr->trace_data->touched[2] = 0; +#endif + + /* Ensure we don't crash simavr due to a bad instruction reading past + * the end of the flash. + */ + if (unlikely(avr->pc >= avr->flashend)) { + STATE("CRASH\n"); + crash(avr); + return 0; + } + + uint32_t opcode = _avr_flash_read16le(avr, avr->pc); + avr_flashaddr_t new_pc = avr->pc + 2; // future "default" pc + int cycle = 1; + + switch (opcode & 0xf000) { + case 0x0000: { + switch (opcode) { + case 0x0000: { // NOP + STATE("nop\n"); + } break; + default: { + switch (opcode & 0xfc00) { + case 0x0400: { // CPC -- Compare with carry -- 0000 01rd dddd rrrr + get_vd5_vr5(opcode); + uint8_t res = vd - vr - avr->sreg[S_C]; + STATE("cpc %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res); + _avr_flags_sub_Rzns(avr, res, vd, vr); + SREG(); + } break; + case 0x0c00: { // ADD -- Add without carry -- 0000 11rd dddd rrrr + get_vd5_vr5(opcode); + uint8_t res = vd + vr; + if (r == d) { + STATE("lsl %s[%02x] = %02x\n", avr_regname(d), vd, res & 0xff); + } else { + STATE("add %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res); + } + _avr_set_r(avr, d, res); + _avr_flags_add_zns(avr, res, vd, vr); + SREG(); + } break; + case 0x0800: { // SBC -- Subtract with carry -- 0000 10rd dddd rrrr + get_vd5_vr5(opcode); + uint8_t res = vd - vr - avr->sreg[S_C]; + STATE("sbc %s[%02x], %s[%02x] = %02x\n", avr_regname(d), avr->data[d], avr_regname(r), avr->data[r], res); + _avr_set_r(avr, d, res); + _avr_flags_sub_Rzns(avr, res, vd, vr); + SREG(); + } break; + default: + switch (opcode & 0xff00) { + case 0x0100: { // MOVW -- Copy Register Word -- 0000 0001 dddd rrrr + uint8_t d = ((opcode >> 4) & 0xf) << 1; + uint8_t r = ((opcode) & 0xf) << 1; + STATE("movw %s:%s, %s:%s[%02x%02x]\n", avr_regname(d), avr_regname(d+1), avr_regname(r), avr_regname(r+1), avr->data[r+1], avr->data[r]); + uint16_t vr = avr->data[r] | (avr->data[r + 1] << 8); + _avr_set_r16le(avr, d, vr); + } break; + case 0x0200: { // MULS -- Multiply Signed -- 0000 0010 dddd rrrr + int8_t r = 16 + (opcode & 0xf); + int8_t d = 16 + ((opcode >> 4) & 0xf); + int16_t res = ((int8_t)avr->data[r]) * ((int8_t)avr->data[d]); + STATE("muls %s[%d], %s[%02x] = %d\n", avr_regname(d), ((int8_t)avr->data[d]), avr_regname(r), ((int8_t)avr->data[r]), res); + _avr_set_r16le(avr, 0, res); + avr->sreg[S_C] = (res >> 15) & 1; + avr->sreg[S_Z] = res == 0; + cycle++; + SREG(); + } break; + case 0x0300: { // MUL -- Multiply -- 0000 0011 fddd frrr + int8_t r = 16 + (opcode & 0x7); + int8_t d = 16 + ((opcode >> 4) & 0x7); + int16_t res = 0; + uint8_t c = 0; + T(const char * name = "";) + switch (opcode & 0x88) { + case 0x00: // MULSU -- Multiply Signed Unsigned -- 0000 0011 0ddd 0rrr + res = ((uint8_t)avr->data[r]) * ((int8_t)avr->data[d]); + c = (res >> 15) & 1; + T(name = "mulsu";) + break; + case 0x08: // FMUL -- Fractional Multiply Unsigned -- 0000 0011 0ddd 1rrr + res = ((uint8_t)avr->data[r]) * ((uint8_t)avr->data[d]); + c = (res >> 15) & 1; + res <<= 1; + T(name = "fmul";) + break; + case 0x80: // FMULS -- Multiply Signed -- 0000 0011 1ddd 0rrr + res = ((int8_t)avr->data[r]) * ((int8_t)avr->data[d]); + c = (res >> 15) & 1; + res <<= 1; + T(name = "fmuls";) + break; + case 0x88: // FMULSU -- Multiply Signed Unsigned -- 0000 0011 1ddd 1rrr + res = ((uint8_t)avr->data[r]) * ((int8_t)avr->data[d]); + c = (res >> 15) & 1; + res <<= 1; + T(name = "fmulsu";) + break; + } + cycle++; + STATE("%s %s[%d], %s[%02x] = %d\n", name, avr_regname(d), ((int8_t)avr->data[d]), avr_regname(r), ((int8_t)avr->data[r]), res); + _avr_set_r16le(avr, 0, res); + avr->sreg[S_C] = c; + avr->sreg[S_Z] = res == 0; + SREG(); + } break; + default: _avr_invalid_opcode(avr); + } + } + } + } + } break; + + case 0x1000: { + switch (opcode & 0xfc00) { + case 0x1800: { // SUB -- Subtract without carry -- 0001 10rd dddd rrrr + get_vd5_vr5(opcode); + uint8_t res = vd - vr; + STATE("sub %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res); + _avr_set_r(avr, d, res); + _avr_flags_sub_zns(avr, res, vd, vr); + SREG(); + } break; + case 0x1000: { // CPSE -- Compare, skip if equal -- 0001 00rd dddd rrrr + get_vd5_vr5(opcode); + uint16_t res = vd == vr; + STATE("cpse %s[%02x], %s[%02x]\t; Will%s skip\n", avr_regname(d), avr->data[d], avr_regname(r), avr->data[r], res ? "":" not"); + if (res) { + if (_avr_is_instruction_32_bits(avr, new_pc)) { + new_pc += 4; cycle += 2; + } else { + new_pc += 2; cycle++; + } + } + } break; + case 0x1400: { // CP -- Compare -- 0001 01rd dddd rrrr + get_vd5_vr5(opcode); + uint8_t res = vd - vr; + STATE("cp %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res); + _avr_flags_sub_zns(avr, res, vd, vr); + SREG(); + } break; + case 0x1c00: { // ADD -- Add with carry -- 0001 11rd dddd rrrr + get_vd5_vr5(opcode); + uint8_t res = vd + vr + avr->sreg[S_C]; + if (r == d) { + STATE("rol %s[%02x] = %02x\n", avr_regname(d), avr->data[d], res); + } else { + STATE("addc %s[%02x], %s[%02x] = %02x\n", avr_regname(d), avr->data[d], avr_regname(r), avr->data[r], res); + } + _avr_set_r(avr, d, res); + _avr_flags_add_zns(avr, res, vd, vr); + SREG(); + } break; + default: _avr_invalid_opcode(avr); + } + } break; + + case 0x2000: { + switch (opcode & 0xfc00) { + case 0x2000: { // AND -- Logical AND -- 0010 00rd dddd rrrr + get_vd5_vr5(opcode); + uint8_t res = vd & vr; + if (r == d) { + STATE("tst %s[%02x]\n", avr_regname(d), avr->data[d]); + } else { + STATE("and %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res); + } + _avr_set_r(avr, d, res); + _avr_flags_znv0s(avr, res); + SREG(); + } break; + case 0x2400: { // EOR -- Logical Exclusive OR -- 0010 01rd dddd rrrr + get_vd5_vr5(opcode); + uint8_t res = vd ^ vr; + if (r==d) { + STATE("clr %s[%02x]\n", avr_regname(d), avr->data[d]); + } else { + STATE("eor %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res); + } + _avr_set_r(avr, d, res); + _avr_flags_znv0s(avr, res); + SREG(); + } break; + case 0x2800: { // OR -- Logical OR -- 0010 10rd dddd rrrr + get_vd5_vr5(opcode); + uint8_t res = vd | vr; + STATE("or %s[%02x], %s[%02x] = %02x\n", avr_regname(d), vd, avr_regname(r), vr, res); + _avr_set_r(avr, d, res); + _avr_flags_znv0s(avr, res); + SREG(); + } break; + case 0x2c00: { // MOV -- 0010 11rd dddd rrrr + get_d5_vr5(opcode); + uint8_t res = vr; + STATE("mov %s, %s[%02x] = %02x\n", avr_regname(d), avr_regname(r), vr, res); + _avr_set_r(avr, d, res); + } break; + default: _avr_invalid_opcode(avr); + } + } break; + + case 0x3000: { // CPI -- Compare Immediate -- 0011 kkkk hhhh kkkk + get_vh4_k8(opcode); + uint8_t res = vh - k; + STATE("cpi %s[%02x], 0x%02x\n", avr_regname(h), vh, k); + _avr_flags_sub_zns(avr, res, vh, k); + SREG(); + } break; + + case 0x4000: { // SBCI -- Subtract Immediate With Carry -- 0100 kkkk hhhh kkkk + get_vh4_k8(opcode); + uint8_t res = vh - k - avr->sreg[S_C]; + STATE("sbci %s[%02x], 0x%02x = %02x\n", avr_regname(h), vh, k, res); + _avr_set_r(avr, h, res); + _avr_flags_sub_Rzns(avr, res, vh, k); + SREG(); + } break; + + case 0x5000: { // SUBI -- Subtract Immediate -- 0101 kkkk hhhh kkkk + get_vh4_k8(opcode); + uint8_t res = vh - k; + STATE("subi %s[%02x], 0x%02x = %02x\n", avr_regname(h), vh, k, res); + _avr_set_r(avr, h, res); + _avr_flags_sub_zns(avr, res, vh, k); + SREG(); + } break; + + case 0x6000: { // ORI aka SBR -- Logical OR with Immediate -- 0110 kkkk hhhh kkkk + get_vh4_k8(opcode); + uint8_t res = vh | k; + STATE("ori %s[%02x], 0x%02x\n", avr_regname(h), vh, k); + _avr_set_r(avr, h, res); + _avr_flags_znv0s(avr, res); + SREG(); + } break; + + case 0x7000: { // ANDI -- Logical AND with Immediate -- 0111 kkkk hhhh kkkk + get_vh4_k8(opcode); + uint8_t res = vh & k; + STATE("andi %s[%02x], 0x%02x\n", avr_regname(h), vh, k); + _avr_set_r(avr, h, res); + _avr_flags_znv0s(avr, res); + SREG(); + } break; + + case 0xa000: + case 0x8000: { + /* + * Load (LDD/STD) store instructions + * + * 10q0 qqsd dddd yqqq + * s = 0 = load, 1 = store + * y = 16 bits register index, 1 = Y, 0 = X + * q = 6 bit displacement + */ + switch (opcode & 0xd008) { + case 0xa000: + case 0x8000: { // LD (LDD) -- Load Indirect using Z -- 10q0 qqsd dddd yqqq + uint16_t v = avr->data[R_ZL] | (avr->data[R_ZH] << 8); + get_d5_q6(opcode); + if (opcode & 0x0200) { + STATE("st (Z+%d[%04x]), %s[%02x]\n", q, v+q, avr_regname(d), avr->data[d]); + _avr_set_ram(avr, v+q, avr->data[d]); + } else { + STATE("ld %s, (Z+%d[%04x])=[%02x]\n", avr_regname(d), q, v+q, avr->data[v+q]); + _avr_set_r(avr, d, _avr_get_ram(avr, v+q)); + } + cycle += 1; // 2 cycles, 3 for tinyavr + } break; + case 0xa008: + case 0x8008: { // LD (LDD) -- Load Indirect using Y -- 10q0 qqsd dddd yqqq + uint16_t v = avr->data[R_YL] | (avr->data[R_YH] << 8); + get_d5_q6(opcode); + if (opcode & 0x0200) { + STATE("st (Y+%d[%04x]), %s[%02x]\n", q, v+q, avr_regname(d), avr->data[d]); + _avr_set_ram(avr, v+q, avr->data[d]); + } else { + STATE("ld %s, (Y+%d[%04x])=[%02x]\n", avr_regname(d), q, v+q, avr->data[d+q]); + _avr_set_r(avr, d, _avr_get_ram(avr, v+q)); + } + cycle += 1; // 2 cycles, 3 for tinyavr + } break; + default: _avr_invalid_opcode(avr); + } + } break; + + case 0x9000: { + /* this is an annoying special case, but at least these lines handle all the SREG set/clear opcodes */ + if ((opcode & 0xff0f) == 0x9408) { + get_sreg_bit(opcode); + STATE("%s%c\n", opcode & 0x0080 ? "cl" : "se", _sreg_bit_name[b]); + avr_sreg_set(avr, b, (opcode & 0x0080) == 0); + SREG(); + } else switch (opcode) { + case 0x9588: { // SLEEP -- 1001 0101 1000 1000 + STATE("sleep\n"); + /* Don't sleep if there are interrupts about to be serviced. + * Without this check, it was possible to incorrectly enter a state + * in which the cpu was sleeping and interrupts were disabled. For more + * details, see the commit message. */ + if (!avr_has_pending_interrupts(avr) || !avr->sreg[S_I]) + avr->state = cpu_Sleeping; + } break; + case 0x9598: { // BREAK -- 1001 0101 1001 1000 + STATE("break\n"); + if (avr->gdb) { + // if gdb is on, break here. + avr->state = cpu_Stopped; + avr_gdb_handle_break(avr); + } + } break; + case 0x95a8: { // WDR -- Watchdog Reset -- 1001 0101 1010 1000 + STATE("wdr\n"); + avr_ioctl(avr, AVR_IOCTL_WATCHDOG_RESET, 0); + } break; + case 0x95e8: { // SPM -- Store Program Memory -- 1001 0101 1110 1000 + STATE("spm\n"); + avr_ioctl(avr, AVR_IOCTL_FLASH_SPM, 0); + } break; + case 0x9409: // IJMP -- Indirect jump -- 1001 0100 0000 1001 + case 0x9419: // EIJMP -- Indirect jump -- 1001 0100 0001 1001 bit 4 is "indirect" + case 0x9509: // ICALL -- Indirect Call to Subroutine -- 1001 0101 0000 1001 + case 0x9519: { // EICALL -- Indirect Call to Subroutine -- 1001 0101 0001 1001 bit 8 is "push pc" + int e = opcode & 0x10; + int p = opcode & 0x100; + if (e && !avr->eind) + _avr_invalid_opcode(avr); + uint32_t z = avr->data[R_ZL] | (avr->data[R_ZH] << 8); + if (e) + z |= avr->data[avr->eind] << 16; + STATE("%si%s Z[%04x]\n", e?"e":"", p?"call":"jmp", z << 1); + if (p) + cycle += _avr_push_addr(avr, new_pc) - 1; + new_pc = z << 1; + cycle++; + TRACE_JUMP(); + } break; + case 0x9518: // RETI -- Return from Interrupt -- 1001 0101 0001 1000 + avr_sreg_set(avr, S_I, 1); + avr_interrupt_reti(avr); + FALLTHROUGH + case 0x9508: { // RET -- Return -- 1001 0101 0000 1000 + new_pc = _avr_pop_addr(avr); + cycle += 1 + avr->address_size; + STATE("ret%s\n", opcode & 0x10 ? "i" : ""); + TRACE_JUMP(); + STACK_FRAME_POP(); + } break; + case 0x95c8: { // LPM -- Load Program Memory R0 <- (Z) -- 1001 0101 1100 1000 + uint16_t z = avr->data[R_ZL] | (avr->data[R_ZH] << 8); + STATE("lpm %s, (Z[%04x])\n", avr_regname(0), z); + cycle += 2; // 3 cycles + _avr_set_r(avr, 0, avr->flash[z]); + } break; + case 0x95d8: { // ELPM -- Load Program Memory R0 <- (Z) -- 1001 0101 1101 1000 + if (!avr->rampz) + _avr_invalid_opcode(avr); + uint32_t z = avr->data[R_ZL] | (avr->data[R_ZH] << 8) | (avr->data[avr->rampz] << 16); + STATE("elpm %s, (Z[%02x:%04x])\n", avr_regname(0), z >> 16, z & 0xffff); + _avr_set_r(avr, 0, avr->flash[z]); + cycle += 2; // 3 cycles + } break; + default: { + switch (opcode & 0xfe0f) { + case 0x9000: { // LDS -- Load Direct from Data Space, 32 bits -- 1001 0000 0000 0000 + get_d5(opcode); + uint16_t x = _avr_flash_read16le(avr, new_pc); + new_pc += 2; + STATE("lds %s[%02x], 0x%04x\n", avr_regname(d), avr->data[d], x); + _avr_set_r(avr, d, _avr_get_ram(avr, x)); + cycle++; // 2 cycles + } break; + case 0x9005: + case 0x9004: { // LPM -- Load Program Memory -- 1001 000d dddd 01oo + get_d5(opcode); + uint16_t z = avr->data[R_ZL] | (avr->data[R_ZH] << 8); + int op = opcode & 1; + STATE("lpm %s, (Z[%04x]%s)\n", avr_regname(d), z, op ? "+" : ""); + _avr_set_r(avr, d, avr->flash[z]); + if (op) { + z++; + _avr_set_r16le_hl(avr, R_ZL, z); + } + cycle += 2; // 3 cycles + } break; + case 0x9006: + case 0x9007: { // ELPM -- Extended Load Program Memory -- 1001 000d dddd 01oo + if (!avr->rampz) + _avr_invalid_opcode(avr); + uint32_t z = avr->data[R_ZL] | (avr->data[R_ZH] << 8) | (avr->data[avr->rampz] << 16); + get_d5(opcode); + int op = opcode & 1; + STATE("elpm %s, (Z[%02x:%04x]%s)\n", avr_regname(d), z >> 16, z & 0xffff, op ? "+" : ""); + _avr_set_r(avr, d, avr->flash[z]); + if (op) { + z++; + _avr_set_r(avr, avr->rampz, z >> 16); + _avr_set_r16le_hl(avr, R_ZL, z); + } + cycle += 2; // 3 cycles + } break; + /* + * Load store instructions + * + * 1001 00sr rrrr iioo + * s = 0 = load, 1 = store + * ii = 16 bits register index, 11 = X, 10 = Y, 00 = Z + * oo = 1) post increment, 2) pre-decrement + */ + case 0x900c: + case 0x900d: + case 0x900e: { // LD -- Load Indirect from Data using X -- 1001 000d dddd 11oo + int op = opcode & 3; + get_d5(opcode); + uint16_t x = (avr->data[R_XH] << 8) | avr->data[R_XL]; + STATE("ld %s, %sX[%04x]%s\n", avr_regname(d), op == 2 ? "--" : "", x, op == 1 ? "++" : ""); + cycle++; // 2 cycles (1 for tinyavr, except with inc/dec 2) + if (op == 2) x--; + uint8_t vd = _avr_get_ram(avr, x); + if (op == 1) x++; + _avr_set_r16le_hl(avr, R_XL, x); + _avr_set_r(avr, d, vd); + } break; + case 0x920c: + case 0x920d: + case 0x920e: { // ST -- Store Indirect Data Space X -- 1001 001d dddd 11oo + int op = opcode & 3; + get_vd5(opcode); + uint16_t x = (avr->data[R_XH] << 8) | avr->data[R_XL]; + STATE("st %sX[%04x]%s, %s[%02x] \n", op == 2 ? "--" : "", x, op == 1 ? "++" : "", avr_regname(d), vd); + cycle++; // 2 cycles, except tinyavr + if (op == 2) x--; + _avr_set_ram(avr, x, vd); + if (op == 1) x++; + _avr_set_r16le_hl(avr, R_XL, x); + } break; + case 0x9009: + case 0x900a: { // LD -- Load Indirect from Data using Y -- 1001 000d dddd 10oo + int op = opcode & 3; + get_d5(opcode); + uint16_t y = (avr->data[R_YH] << 8) | avr->data[R_YL]; + STATE("ld %s, %sY[%04x]%s\n", avr_regname(d), op == 2 ? "--" : "", y, op == 1 ? "++" : ""); + cycle++; // 2 cycles, except tinyavr + if (op == 2) y--; + uint8_t vd = _avr_get_ram(avr, y); + if (op == 1) y++; + _avr_set_r16le_hl(avr, R_YL, y); + _avr_set_r(avr, d, vd); + } break; + case 0x9209: + case 0x920a: { // ST -- Store Indirect Data Space Y -- 1001 001d dddd 10oo + int op = opcode & 3; + get_vd5(opcode); + uint16_t y = (avr->data[R_YH] << 8) | avr->data[R_YL]; + STATE("st %sY[%04x]%s, %s[%02x]\n", op == 2 ? "--" : "", y, op == 1 ? "++" : "", avr_regname(d), vd); + cycle++; + if (op == 2) y--; + _avr_set_ram(avr, y, vd); + if (op == 1) y++; + _avr_set_r16le_hl(avr, R_YL, y); + } break; + case 0x9200: { // STS -- Store Direct to Data Space, 32 bits -- 1001 0010 0000 0000 + get_vd5(opcode); + uint16_t x = _avr_flash_read16le(avr, new_pc); + new_pc += 2; + STATE("sts 0x%04x, %s[%02x]\n", x, avr_regname(d), vd); + cycle++; + _avr_set_ram(avr, x, vd); + } break; + case 0x9001: + case 0x9002: { // LD -- Load Indirect from Data using Z -- 1001 000d dddd 00oo + int op = opcode & 3; + get_d5(opcode); + uint16_t z = (avr->data[R_ZH] << 8) | avr->data[R_ZL]; + STATE("ld %s, %sZ[%04x]%s\n", avr_regname(d), op == 2 ? "--" : "", z, op == 1 ? "++" : ""); + cycle++;; // 2 cycles, except tinyavr + if (op == 2) z--; + uint8_t vd = _avr_get_ram(avr, z); + if (op == 1) z++; + _avr_set_r16le_hl(avr, R_ZL, z); + _avr_set_r(avr, d, vd); + } break; + case 0x9201: + case 0x9202: { // ST -- Store Indirect Data Space Z -- 1001 001d dddd 00oo + int op = opcode & 3; + get_vd5(opcode); + uint16_t z = (avr->data[R_ZH] << 8) | avr->data[R_ZL]; + STATE("st %sZ[%04x]%s, %s[%02x] \n", op == 2 ? "--" : "", z, op == 1 ? "++" : "", avr_regname(d), vd); + cycle++; // 2 cycles, except tinyavr + if (op == 2) z--; + _avr_set_ram(avr, z, vd); + if (op == 1) z++; + _avr_set_r16le_hl(avr, R_ZL, z); + } break; + case 0x900f: { // POP -- 1001 000d dddd 1111 + get_d5(opcode); + _avr_set_r(avr, d, _avr_pop8(avr)); + T(uint16_t sp = _avr_sp_get(avr);) + STATE("pop %s (@%04x)[%02x]\n", avr_regname(d), sp, avr->data[sp]); + cycle++; + } break; + case 0x920f: { // PUSH -- 1001 001d dddd 1111 + get_vd5(opcode); + _avr_push8(avr, vd); + T(uint16_t sp = _avr_sp_get(avr);) + STATE("push %s[%02x] (@%04x)\n", avr_regname(d), vd, sp); + cycle++; + } break; + case 0x9400: { // COM -- One's Complement -- 1001 010d dddd 0000 + get_vd5(opcode); + uint8_t res = 0xff - vd; + STATE("com %s[%02x] = %02x\n", avr_regname(d), vd, res); + _avr_set_r(avr, d, res); + _avr_flags_znv0s(avr, res); + avr->sreg[S_C] = 1; + SREG(); + } break; + case 0x9401: { // NEG -- Two's Complement -- 1001 010d dddd 0001 + get_vd5(opcode); + uint8_t res = 0x00 - vd; + STATE("neg %s[%02x] = %02x\n", avr_regname(d), vd, res); + _avr_set_r(avr, d, res); + avr->sreg[S_H] = ((res >> 3) | (vd >> 3)) & 1; + avr->sreg[S_V] = res == 0x80; + avr->sreg[S_C] = res != 0; + _avr_flags_zns(avr, res); + SREG(); + } break; + case 0x9402: { // SWAP -- Swap Nibbles -- 1001 010d dddd 0010 + get_vd5(opcode); + uint8_t res = (vd >> 4) | (vd << 4) ; + STATE("swap %s[%02x] = %02x\n", avr_regname(d), vd, res); + _avr_set_r(avr, d, res); + } break; + case 0x9403: { // INC -- Increment -- 1001 010d dddd 0011 + get_vd5(opcode); + uint8_t res = vd + 1; + STATE("inc %s[%02x] = %02x\n", avr_regname(d), vd, res); + _avr_set_r(avr, d, res); + avr->sreg[S_V] = res == 0x80; + _avr_flags_zns(avr, res); + SREG(); + } break; + case 0x9405: { // ASR -- Arithmetic Shift Right -- 1001 010d dddd 0101 + get_vd5(opcode); + uint8_t res = (vd >> 1) | (vd & 0x80); + STATE("asr %s[%02x]\n", avr_regname(d), vd); + _avr_set_r(avr, d, res); + _avr_flags_zcnvs(avr, res, vd); + SREG(); + } break; + case 0x9406: { // LSR -- Logical Shift Right -- 1001 010d dddd 0110 + get_vd5(opcode); + uint8_t res = vd >> 1; + STATE("lsr %s[%02x]\n", avr_regname(d), vd); + _avr_set_r(avr, d, res); + avr->sreg[S_N] = 0; + _avr_flags_zcvs(avr, res, vd); + SREG(); + } break; + case 0x9407: { // ROR -- Rotate Right -- 1001 010d dddd 0111 + get_vd5(opcode); + uint8_t res = (avr->sreg[S_C] ? 0x80 : 0) | vd >> 1; + STATE("ror %s[%02x]\n", avr_regname(d), vd); + _avr_set_r(avr, d, res); + _avr_flags_zcnvs(avr, res, vd); + SREG(); + } break; + case 0x940a: { // DEC -- Decrement -- 1001 010d dddd 1010 + get_vd5(opcode); + uint8_t res = vd - 1; + STATE("dec %s[%02x] = %02x\n", avr_regname(d), vd, res); + _avr_set_r(avr, d, res); + avr->sreg[S_V] = res == 0x7f; + _avr_flags_zns(avr, res); + SREG(); + } break; + case 0x940c: + case 0x940d: { // JMP -- Long Call to sub, 32 bits -- 1001 010a aaaa 110a + avr_flashaddr_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1); + uint16_t x = _avr_flash_read16le(avr, new_pc); + a = (a << 16) | x; + STATE("jmp 0x%06x\n", a); + new_pc = a << 1; + cycle += 2; + TRACE_JUMP(); + } break; + case 0x940e: + case 0x940f: { // CALL -- Long Call to sub, 32 bits -- 1001 010a aaaa 111a + avr_flashaddr_t a = ((opcode & 0x01f0) >> 3) | (opcode & 1); + uint16_t x = _avr_flash_read16le(avr, new_pc); + a = (a << 16) | x; + STATE("call 0x%06x\n", a); + new_pc += 2; + cycle += 1 + _avr_push_addr(avr, new_pc); + new_pc = a << 1; + TRACE_JUMP(); + STACK_FRAME_PUSH(); + } break; + + default: { + switch (opcode & 0xff00) { + case 0x9600: { // ADIW -- Add Immediate to Word -- 1001 0110 KKpp KKKK + get_vp2_k6(opcode); + uint16_t res = vp + k; + STATE("adiw %s:%s[%04x], 0x%02x\n", avr_regname(p), avr_regname(p + 1), vp, k); + _avr_set_r16le_hl(avr, p, res); + avr->sreg[S_V] = ((~vp & res) >> 15) & 1; + avr->sreg[S_C] = ((~res & vp) >> 15) & 1; + _avr_flags_zns16(avr, res); + SREG(); + cycle++; + } break; + case 0x9700: { // SBIW -- Subtract Immediate from Word -- 1001 0111 KKpp KKKK + get_vp2_k6(opcode); + uint16_t res = vp - k; + STATE("sbiw %s:%s[%04x], 0x%02x\n", avr_regname(p), avr_regname(p + 1), vp, k); + _avr_set_r16le_hl(avr, p, res); + avr->sreg[S_V] = ((vp & ~res) >> 15) & 1; + avr->sreg[S_C] = ((res & ~vp) >> 15) & 1; + _avr_flags_zns16(avr, res); + SREG(); + cycle++; + } break; + case 0x9800: { // CBI -- Clear Bit in I/O Register -- 1001 1000 AAAA Abbb + get_io5_b3mask(opcode); + uint8_t res = _avr_get_ram(avr, io) & ~mask; + STATE("cbi %s[%04x], 0x%02x = %02x\n", avr_regname(io), avr->data[io], mask, res); + _avr_set_ram(avr, io, res); + cycle++; + } break; + case 0x9900: { // SBIC -- Skip if Bit in I/O Register is Cleared -- 1001 1001 AAAA Abbb + get_io5_b3mask(opcode); + uint8_t res = _avr_get_ram(avr, io) & mask; + STATE("sbic %s[%04x], 0x%02x\t; Will%s branch\n", avr_regname(io), avr->data[io], mask, !res?"":" not"); + if (!res) { + if (_avr_is_instruction_32_bits(avr, new_pc)) { + new_pc += 4; cycle += 2; + } else { + new_pc += 2; cycle++; + } + } + } break; + case 0x9a00: { // SBI -- Set Bit in I/O Register -- 1001 1010 AAAA Abbb + get_io5_b3mask(opcode); + uint8_t res = _avr_get_ram(avr, io) | mask; + STATE("sbi %s[%04x], 0x%02x = %02x\n", avr_regname(io), avr->data[io], mask, res); + _avr_set_ram(avr, io, res); + cycle++; + } break; + case 0x9b00: { // SBIS -- Skip if Bit in I/O Register is Set -- 1001 1011 AAAA Abbb + get_io5_b3mask(opcode); + uint8_t res = _avr_get_ram(avr, io) & mask; + STATE("sbis %s[%04x], 0x%02x\t; Will%s branch\n", avr_regname(io), avr->data[io], mask, res?"":" not"); + if (res) { + if (_avr_is_instruction_32_bits(avr, new_pc)) { + new_pc += 4; cycle += 2; + } else { + new_pc += 2; cycle++; + } + } + } break; + default: + switch (opcode & 0xfc00) { + case 0x9c00: { // MUL -- Multiply Unsigned -- 1001 11rd dddd rrrr + get_vd5_vr5(opcode); + uint16_t res = vd * vr; + STATE("mul %s[%02x], %s[%02x] = %04x\n", avr_regname(d), vd, avr_regname(r), vr, res); + cycle++; + _avr_set_r16le(avr, 0, res); + avr->sreg[S_Z] = res == 0; + avr->sreg[S_C] = (res >> 15) & 1; + SREG(); + } break; + default: _avr_invalid_opcode(avr); + } + } + } break; + } + } break; + } + } break; + + case 0xb000: { + switch (opcode & 0xf800) { + case 0xb800: { // OUT A,Rr -- 1011 1AAd dddd AAAA + get_d5_a6(opcode); + STATE("out %s, %s[%02x]\n", avr_regname(A), avr_regname(d), avr->data[d]); + _avr_set_ram(avr, A, avr->data[d]); + } break; + case 0xb000: { // IN Rd,A -- 1011 0AAd dddd AAAA + get_d5_a6(opcode); + STATE("in %s, %s[%02x]\n", avr_regname(d), avr_regname(A), avr->data[A]); + _avr_set_r(avr, d, _avr_get_ram(avr, A)); + } break; + default: _avr_invalid_opcode(avr); + } + } break; + + case 0xc000: { // RJMP -- 1100 kkkk kkkk kkkk + get_o12(opcode); + STATE("rjmp .%d [%04x]\n", o >> 1, new_pc + o); + new_pc = (new_pc + o) % (avr->flashend+1); + cycle++; + TRACE_JUMP(); + } break; + + case 0xd000: { // RCALL -- 1101 kkkk kkkk kkkk + get_o12(opcode); + STATE("rcall .%d [%04x]\n", o >> 1, new_pc + o); + cycle += _avr_push_addr(avr, new_pc); + new_pc = (new_pc + o) % (avr->flashend+1); + // 'rcall .1' is used as a cheap "push 16 bits of room on the stack" + if (o != 0) { + TRACE_JUMP(); + STACK_FRAME_PUSH(); + } + } break; + + case 0xe000: { // LDI Rd, K aka SER (LDI r, 0xff) -- 1110 kkkk dddd kkkk + get_h4_k8(opcode); + STATE("ldi %s, 0x%02x\n", avr_regname(h), k); + _avr_set_r(avr, h, k); + } break; + + case 0xf000: { + switch (opcode & 0xfe00) { + case 0xf100: { /* simavr special opcodes */ + if (opcode == 0xf1f1) { // AVR_OVERFLOW_OPCODE + printf("FLASH overflow, soft reset\n"); + new_pc = 0; + TRACE_JUMP(); + } + } break; + case 0xf000: + case 0xf200: + case 0xf400: + case 0xf600: { // BRXC/BRXS -- All the SREG branches -- 1111 0Boo oooo osss + int16_t o = ((int16_t)(opcode << 6)) >> 9; // offset + uint8_t s = opcode & 7; + int set = (opcode & 0x0400) == 0; // this bit means BRXC otherwise BRXS + int branch = (avr->sreg[s] && set) || (!avr->sreg[s] && !set); + const char *names[2][8] = { + { "brcc", "brne", "brpl", "brvc", NULL, "brhc", "brtc", "brid"}, + { "brcs", "breq", "brmi", "brvs", NULL, "brhs", "brts", "brie"}, + }; + if (names[set][s]) { + STATE("%s .%d [%04x]\t; Will%s branch\n", names[set][s], o, new_pc + (o << 1), branch ? "":" not"); + } else { + STATE("%s%c .%d [%04x]\t; Will%s branch\n", set ? "brbs" : "brbc", _sreg_bit_name[s], o, new_pc + (o << 1), branch ? "":" not"); + } + if (branch) { + cycle++; // 2 cycles if taken, 1 otherwise + new_pc = new_pc + (o << 1); + } + } break; + case 0xf800: + case 0xf900: { // BLD -- Bit Store from T into a Bit in Register -- 1111 100d dddd 0bbb + get_vd5_s3_mask(opcode); + uint8_t v = (vd & ~mask) | (avr->sreg[S_T] ? mask : 0); + STATE("bld %s[%02x], 0x%02x = %02x\n", avr_regname(d), vd, mask, v); + _avr_set_r(avr, d, v); + } break; + case 0xfa00: + case 0xfb00:{ // BST -- Bit Store into T from bit in Register -- 1111 101d dddd 0bbb + get_vd5_s3(opcode) + STATE("bst %s[%02x], 0x%02x\n", avr_regname(d), vd, 1 << s); + avr->sreg[S_T] = (vd >> s) & 1; + SREG(); + } break; + case 0xfc00: + case 0xfe00: { // SBRS/SBRC -- Skip if Bit in Register is Set/Clear -- 1111 11sd dddd 0bbb + get_vd5_s3_mask(opcode) + int set = (opcode & 0x0200) != 0; + int branch = ((vd & mask) && set) || (!(vd & mask) && !set); + STATE("%s %s[%02x], 0x%02x\t; Will%s branch\n", set ? "sbrs" : "sbrc", avr_regname(d), vd, mask, branch ? "":" not"); + if (branch) { + if (_avr_is_instruction_32_bits(avr, new_pc)) { + new_pc += 4; cycle += 2; + } else { + new_pc += 2; cycle++; + } + } + } break; + default: _avr_invalid_opcode(avr); + } + } break; + + default: _avr_invalid_opcode(avr); + + } + avr->cycle += cycle; + + if ((avr->state == cpu_Running) && + (avr->run_cycle_count > cycle) && + (avr->interrupt_state == 0)) + { + avr->run_cycle_count -= cycle; + avr->pc = new_pc; + goto run_one_again; + } + + return new_pc; +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_core.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_core.h new file mode 100644 index 0000000..874651e --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_core.h @@ -0,0 +1,142 @@ +/* + sim_core.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __SIM_CORE_H__ +#define __SIM_CORE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef NO_COLOR + #define FONT_GREEN + #define FONT_RED + #define FONT_DEFAULT +#else + #define FONT_GREEN "\e[32m" + #define FONT_RED "\e[31m" + #define FONT_DEFAULT "\e[0m" +#endif + +/* + * Instruction decoder, run ONE instruction + */ +avr_flashaddr_t avr_run_one(avr_t * avr); + +/* + * These are for internal access to the stack (for interrupts) + */ +uint16_t _avr_sp_get(avr_t * avr); +void _avr_sp_set(avr_t * avr, uint16_t sp); +int _avr_push_addr(avr_t * avr, avr_flashaddr_t addr); + +#if CONFIG_SIMAVR_TRACE + +/* + * Get a "pretty" register name + */ +const char * avr_regname(unsigned int reg); + +/* + * DEBUG bits follow + * These will disappear when gdb arrives + */ +void avr_dump_state(avr_t * avr); + +#define DUMP_REG() { \ + for (int i = 0; i < 32; i++) printf("%s=%02x%c", avr_regname(i), avr->data[i],i==15?'\n':' ');\ + printf("\n");\ + uint16_t y = avr->data[R_YL] | (avr->data[R_YH]<<8);\ + for (int i = 0; i < 20; i++) printf("Y+%02d=%02x ", i, avr->data[y+i]);\ + printf("\n");\ + } + + +#if AVR_STACK_WATCH +#define DUMP_STACK() \ + for (int i = avr->trace_data->stack_frame_index; i; i--) {\ + int pci = i-1;\ + printf(FONT_RED "*** %04x: %-25s sp %04x\n" FONT_DEFAULT,\ + avr->trace_data->stack_frame[pci].pc, \ + avr->trace_data->codeline ? avr->trace_data->codeline[avr->trace_data->stack_frame[pci].pc>>1]->symbol : "unknown", \ + avr->trace_data->stack_frame[pci].sp);\ + } +#else +#define DUMP_STACK() +#endif + +#else /* CONFIG_SIMAVR_TRACE */ + +#define DUMP_STACK() +#define DUMP_REG(); + +#endif + +/** + * Reconstructs the SREG value from avr->sreg into dst. + */ +#define READ_SREG_INTO(avr, dst) { \ + dst = 0; \ + for (int i = 0; i < 8; i++) \ + if (avr->sreg[i] > 1) { \ + printf("** Invalid SREG!!\n"); \ + } else if (avr->sreg[i]) \ + dst |= (1 << i); \ + } + +static inline void avr_sreg_set(avr_t * avr, uint8_t flag, uint8_t ival) +{ + /* + * clear interrupt_state if disabling interrupts. + * set wait if enabling interrupts. + * no change if interrupt flag does not change. + */ + + if (flag == S_I) { + if (ival) { + if (!avr->sreg[S_I]) + avr->interrupt_state = -1; + } else + avr->interrupt_state = 0; + } + + avr->sreg[flag] = ival; +} + +/** + * Splits the SREG value from src into the avr->sreg array. + */ +#define SET_SREG_FROM(avr, src) { \ + for (int i = 0; i < 8; i++) \ + avr_sreg_set(avr, i, (src & (1 << i)) != 0); \ + } + +/* + * Opcode is sitting at the end of the flash to catch PC overflows. + * Apparently it's used by some code to simulate soft reset? + */ +#define AVR_OVERFLOW_OPCODE 0xf1f1 + +#ifdef __cplusplus +}; +#endif + +#endif /*__SIM_CORE_H__*/ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cycle_timers.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cycle_timers.c new file mode 100644 index 0000000..93cf265 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cycle_timers.c @@ -0,0 +1,249 @@ +/* + sim_cycle_timers.c + + Copyright 2008-2012 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "sim_avr.h" +#include "sim_time.h" +#include "sim_cycle_timers.h" + +#define QUEUE(__q, __e) { \ + (__e)->next = (__q); \ + (__q) = __e; \ + } +#define DETACH(__q, __l, __e) { \ + if (__l) \ + (__l)->next = (__e)->next; \ + else \ + (__q) = (__e)->next; \ + } +#define INSERT(__q, __l, __e) { \ + if (__l) { \ + (__e)->next = (__l)->next; \ + (__l)->next = (__e); \ + } else { \ + (__e)->next = (__q); \ + (__q) = (__e); \ + } \ + } + +#define DEFAULT_SLEEP_CYCLES 1000 + +void +avr_cycle_timer_reset( + struct avr_t * avr) +{ + avr_cycle_timer_pool_t * pool = &avr->cycle_timers; + memset(pool, 0, sizeof(*pool)); + // queue all slots into the free queue + for (int i = 0; i < MAX_CYCLE_TIMERS; i++) { + avr_cycle_timer_slot_p t = &pool->timer_slots[i]; + QUEUE(pool->timer_free, t); + } + avr->run_cycle_count = 1; + avr->run_cycle_limit = 1; +} + +static avr_cycle_count_t +avr_cycle_timer_return_sleep_run_cycles_limited( + avr_t *avr, + avr_cycle_count_t sleep_cycle_count) +{ + // run_cycle_count is bound to run_cycle_limit but NOT less than 1 cycle... + // this is not an error!.. unless you like deadlock. + avr_cycle_count_t run_cycle_count = ((avr->run_cycle_limit >= sleep_cycle_count) ? + sleep_cycle_count : avr->run_cycle_limit); + avr->run_cycle_count = run_cycle_count ? run_cycle_count : 1; + + // sleep cycles are returned unbounded thus preserving original behavior. + return(sleep_cycle_count); +} + +static void +avr_cycle_timer_reset_sleep_run_cycles_limited( + avr_t *avr) +{ + avr_cycle_timer_pool_t * pool = &avr->cycle_timers; + avr_cycle_count_t sleep_cycle_count = DEFAULT_SLEEP_CYCLES; + + if(pool->timer) { + if(pool->timer->when > avr->cycle) { + sleep_cycle_count = pool->timer->when - avr->cycle; + } else { + sleep_cycle_count = 0; + } + } + + avr_cycle_timer_return_sleep_run_cycles_limited(avr, sleep_cycle_count); +} + +// no sanity checks checking here, on purpose +static void +avr_cycle_timer_insert( + avr_t * avr, + avr_cycle_count_t when, + avr_cycle_timer_t timer, + void * param) +{ + avr_cycle_timer_pool_t * pool = &avr->cycle_timers; + + when += avr->cycle; + + avr_cycle_timer_slot_p t = pool->timer_free; + + if (!t) { + AVR_LOG(avr, LOG_ERROR, "CYCLE: %s: ran out of timers (%d)!\n", __func__, MAX_CYCLE_TIMERS); + return; + } + // detach head + pool->timer_free = t->next; + t->next = NULL; + t->timer = timer; + t->param = param; + t->when = when; + + // find its place in the list + avr_cycle_timer_slot_p loop = pool->timer, last = NULL; + while (loop) { + if (loop->when > when) + break; + last = loop; + loop = loop->next; + } + INSERT(pool->timer, last, t); +} + +void +avr_cycle_timer_register( + avr_t * avr, + avr_cycle_count_t when, + avr_cycle_timer_t timer, + void * param) +{ + avr_cycle_timer_pool_t * pool = &avr->cycle_timers; + + // remove it if it was already scheduled + avr_cycle_timer_cancel(avr, timer, param); + + if (!pool->timer_free) { + AVR_LOG(avr, LOG_ERROR, "CYCLE: %s: pool is full (%d)!\n", __func__, MAX_CYCLE_TIMERS); + return; + } + avr_cycle_timer_insert(avr, when, timer, param); + avr_cycle_timer_reset_sleep_run_cycles_limited(avr); +} + +void +avr_cycle_timer_register_usec( + avr_t * avr, + uint32_t when, + avr_cycle_timer_t timer, + void * param) +{ + avr_cycle_timer_register(avr, avr_usec_to_cycles(avr, when), timer, param); +} + +void +avr_cycle_timer_cancel( + avr_t * avr, + avr_cycle_timer_t timer, + void * param) +{ + avr_cycle_timer_pool_t * pool = &avr->cycle_timers; + + // find its place in the list + avr_cycle_timer_slot_p t = pool->timer, last = NULL; + while (t) { + if (t->timer == timer && t->param == param) { + DETACH(pool->timer, last, t); + QUEUE(pool->timer_free, t); + break; + } + last = t; + t = t->next; + } + avr_cycle_timer_reset_sleep_run_cycles_limited(avr); +} + +/* + * Check to see if a timer is present, if so, return the number (+1) of + * cycles left for it to fire, and if not present, return zero + */ +avr_cycle_count_t +avr_cycle_timer_status( + avr_t * avr, + avr_cycle_timer_t timer, + void * param) +{ + avr_cycle_timer_pool_t * pool = &avr->cycle_timers; + + // find its place in the list + avr_cycle_timer_slot_p t = pool->timer; + while (t) { + if (t->timer == timer && t->param == param) { + return 1 + (t->when - avr->cycle); + } + t = t->next; + } + return 0; +} + +/* + * run through all the timers, call the ones that needs it, + * clear the ones that wants it, and calculate the next + * potential cycle we could sleep for... + */ +avr_cycle_count_t +avr_cycle_timer_process( + avr_t * avr) +{ + avr_cycle_timer_pool_t * pool = &avr->cycle_timers; + + if (pool->timer) do { + avr_cycle_timer_slot_p t = pool->timer; + avr_cycle_count_t when = t->when; + + if (when > avr->cycle) + return avr_cycle_timer_return_sleep_run_cycles_limited(avr, when - avr->cycle); + + // detach from active timers + pool->timer = t->next; + t->next = NULL; + do { + avr_cycle_count_t w = t->timer(avr, when, t->param); + // make sure the return value is either zero, or greater + // than the last one to prevent infinite loop here + when = w > when ? w : 0; + } while (when && when <= avr->cycle); + + if (when) // reschedule then + avr_cycle_timer_insert(avr, when - avr->cycle, t->timer, t->param); + + // requeue this one into the free ones + QUEUE(pool->timer_free, t); + } while (pool->timer); + + // original behavior was to return 1000 cycles when no timers were present... + // run_cycles are bound to at least one cycle but no more than requested limit... + // value passed here is returned unbounded, thus preserving original behavior. + return avr_cycle_timer_return_sleep_run_cycles_limited(avr, DEFAULT_SLEEP_CYCLES); +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cycle_timers.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cycle_timers.h new file mode 100644 index 0000000..a4dfdf7 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cycle_timers.h @@ -0,0 +1,121 @@ +/* + sim_cycle_timers.h + + Copyright 2008-2012 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * cycle timers are callbacks that will be called when "when" cycle is reached + * these timers are one shots, then get cleared if the timer function returns zero, + * they get reset if the callback function returns a new cycle number + * + * the implementation maintains a list of 'pending' timers, sorted by when they + * should run, it allows very quick comparison with the next timer to run, and + * quick removal of then from the pile once dispatched. + */ +#ifndef __SIM_CYCLE_TIMERS_H___ +#define __SIM_CYCLE_TIMERS_H___ + +#include "sim_avr_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_CYCLE_TIMERS 64 + +typedef avr_cycle_count_t (*avr_cycle_timer_t)( + struct avr_t * avr, + avr_cycle_count_t when, + void * param); + +/* + * Each timer instance contains the absolute cycle number they + * are hoping to run at, a function pointer to call and a parameter + * + * it will NEVER be the exact cycle specified, as each instruction is + * not divisible and might take 2 or more cycles anyway. + * + * However if there was a LOT of cycle lag, the timer migth be called + * repeteadly until it 'caches up'. + */ +typedef struct avr_cycle_timer_slot_t { + struct avr_cycle_timer_slot_t *next; + avr_cycle_count_t when; + avr_cycle_timer_t timer; + void * param; +} avr_cycle_timer_slot_t, *avr_cycle_timer_slot_p; + +/* + * Timer pool contains a pool of timer slots available, they all + * start queued into the 'free' qeueue, are migrated to the + * 'active' queue when needed and are re-queued to the free one + * when done + */ +typedef struct avr_cycle_timer_pool_t { + avr_cycle_timer_slot_t timer_slots[MAX_CYCLE_TIMERS]; + avr_cycle_timer_slot_p timer_free; + avr_cycle_timer_slot_p timer; +} avr_cycle_timer_pool_t, *avr_cycle_timer_pool_p; + + +// register for calling 'timer' in 'when' cycles +void +avr_cycle_timer_register( + struct avr_t * avr, + avr_cycle_count_t when, + avr_cycle_timer_t timer, + void * param); +// register a timer to call in 'when' usec +void +avr_cycle_timer_register_usec( + struct avr_t * avr, + uint32_t when, + avr_cycle_timer_t timer, + void * param); +// cancel a previously set timer +void +avr_cycle_timer_cancel( + struct avr_t * avr, + avr_cycle_timer_t timer, + void * param); +/* + * Check to see if a timer is present, if so, return the number (+1) of + * cycles left for it to fire, and if not present, return zero + */ +avr_cycle_count_t +avr_cycle_timer_status( + struct avr_t * avr, + avr_cycle_timer_t timer, + void * param); + +// +// Private, called from the core +// +avr_cycle_count_t +avr_cycle_timer_process( + struct avr_t * avr); +void +avr_cycle_timer_reset( + struct avr_t * avr); + +#ifdef __cplusplus +}; +#endif + +#endif /* __SIM_CYCLE_TIMERS_H___ */ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_elf.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_elf.c new file mode 100644 index 0000000..df69b81 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_elf.c @@ -0,0 +1,499 @@ +/* + sim_elf.c + + Loads a .elf file, extract the code, the data, the eeprom and + the "mcu" specification section, also load usable code symbols + to be able to print meaningful trace information. + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <libelf.h> +#include <gelf.h> + +#include "sim_elf.h" +#include "sim_vcd_file.h" +#include "avr_eeprom.h" +#include "avr_ioport.h" + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +void +avr_load_firmware( + avr_t * avr, + elf_firmware_t * firmware) +{ + if (firmware->frequency) + avr->frequency = firmware->frequency; + if (firmware->vcc) + avr->vcc = firmware->vcc; + if (firmware->avcc) + avr->avcc = firmware->avcc; + if (firmware->aref) + avr->aref = firmware->aref; +#if CONFIG_SIMAVR_TRACE && ELF_SYMBOLS + int scount = firmware->flashsize >> 1; + avr->trace_data->codeline = malloc(scount * sizeof(avr_symbol_t*)); + memset(avr->trace_data->codeline, 0, scount * sizeof(avr_symbol_t*)); + + for (int i = 0; i < firmware->symbolcount; i++) + if (firmware->symbol[i]->addr < firmware->flashsize) // code address + avr->trace_data->codeline[firmware->symbol[i]->addr >> 1] = + firmware->symbol[i]; + // "spread" the pointers for known symbols forward + avr_symbol_t * last = NULL; + for (int i = 0; i < scount; i++) { + if (!avr->trace_data->codeline[i]) + avr->trace_data->codeline[i] = last; + else + last = avr->trace_data->codeline[i]; + } +#endif + + avr_loadcode(avr, firmware->flash, + firmware->flashsize, firmware->flashbase); + avr->codeend = firmware->flashsize + + firmware->flashbase - firmware->datasize; + + if (firmware->eeprom && firmware->eesize) { + avr_eeprom_desc_t d = { + .ee = firmware->eeprom, + .offset = 0, + .size = firmware->eesize + }; + avr_ioctl(avr, AVR_IOCTL_EEPROM_SET, &d); + } + if (firmware->fuse) + memcpy(avr->fuse, firmware->fuse, firmware->fusesize); + if (firmware->lockbits) + avr->lockbits = firmware->lockbits[0]; + // load the default pull up/down values for ports + for (int i = 0; i < 8 && firmware->external_state[i].port; i++) { + avr_ioport_external_t e = { + .name = firmware->external_state[i].port, + .mask = firmware->external_state[i].mask, + .value = firmware->external_state[i].value, + }; + avr_ioctl(avr, AVR_IOCTL_IOPORT_SET_EXTERNAL(e.name), &e); + } + avr_set_command_register(avr, firmware->command_register_addr); + avr_set_console_register(avr, firmware->console_register_addr); + + // rest is initialization of the VCD file + if (firmware->tracecount == 0) + return; + avr->vcd = malloc(sizeof(*avr->vcd)); + memset(avr->vcd, 0, sizeof(*avr->vcd)); + avr_vcd_init(avr, + firmware->tracename[0] ? firmware->tracename: "gtkwave_trace.vcd", + avr->vcd, + firmware->traceperiod >= 1000 ? firmware->traceperiod : 1000); + + AVR_LOG(avr, LOG_TRACE, "Creating VCD trace file '%s'\n", + avr->vcd->filename); + + for (int ti = 0; ti < firmware->tracecount; ti++) { + if (firmware->trace[ti].kind == AVR_MMCU_TAG_VCD_PORTPIN) { + avr_irq_t * irq = avr_io_getirq(avr, + AVR_IOCTL_IOPORT_GETIRQ(firmware->trace[ti].mask), + firmware->trace[ti].addr); + if (irq) { + char name[16]; + sprintf(name, "%c%d", firmware->trace[ti].mask, + firmware->trace[ti].addr); + avr_vcd_add_signal(avr->vcd, irq, 1, + firmware->trace[ti].name[0] ? + firmware->trace[ti].name : name); + } + } else if (firmware->trace[ti].kind == AVR_MMCU_TAG_VCD_IRQ) { + avr_irq_t * bit = avr_get_interrupt_irq(avr, firmware->trace[ti].mask); + if (bit && firmware->trace[ti].addr < AVR_INT_IRQ_COUNT) + avr_vcd_add_signal(avr->vcd, + &bit[firmware->trace[ti].addr], + firmware->trace[ti].mask == 0xff ? 8 : 1, + firmware->trace[ti].name); + } else if (firmware->trace[ti].mask == 0xff || + firmware->trace[ti].mask == 0) { + // easy one + avr_irq_t * all = avr_iomem_getirq(avr, + firmware->trace[ti].addr, + firmware->trace[ti].name, + AVR_IOMEM_IRQ_ALL); + if (!all) { + AVR_LOG(avr, LOG_ERROR, + "ELF: %s: unable to attach trace to address %04x\n", + __FUNCTION__, firmware->trace[ti].addr); + } else { + avr_vcd_add_signal(avr->vcd, all, 8, + firmware->trace[ti].name); + } + } else { + int count = __builtin_popcount(firmware->trace[ti].mask); + // for (int bi = 0; bi < 8; bi++) + // if (firmware->trace[ti].mask & (1 << bi)) + // count++; + for (int bi = 0; bi < 8; bi++) + if (firmware->trace[ti].mask & (1 << bi)) { + avr_irq_t * bit = avr_iomem_getirq(avr, + firmware->trace[ti].addr, + firmware->trace[ti].name, + bi); + if (!bit) { + AVR_LOG(avr, LOG_ERROR, + "ELF: %s: unable to attach trace to address %04x\n", + __FUNCTION__, firmware->trace[ti].addr); + break; + } + + if (count == 1) { + avr_vcd_add_signal(avr->vcd, + bit, 1, firmware->trace[ti].name); + break; + } + char comp[128]; + sprintf(comp, "%s.%d", firmware->trace[ti].name, bi); + avr_vcd_add_signal(avr->vcd, bit, 1, comp); + } + } + } + // if the firmware has specified a command register, do NOT start the trace here + // the firmware probably knows best when to start/stop it + if (!firmware->command_register_addr) + avr_vcd_start(avr->vcd); +} + +static void +elf_parse_mmcu_section( + elf_firmware_t * firmware, + uint8_t * src, + uint32_t size) +{ +// hdump(".mmcu", src, size); + while (size) { + uint8_t tag = *src++; + uint8_t ts = *src++; + int next = size > 2 + ts ? 2 + ts : size; + // printf("elf_parse_mmcu_section %2d, size %2d / remains %3d\n", + // tag, ts, size); + switch (tag) { + case AVR_MMCU_TAG_FREQUENCY: + firmware->frequency = + src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); + break; + case AVR_MMCU_TAG_NAME: + strcpy(firmware->mmcu, (char*)src); + break; + case AVR_MMCU_TAG_VCC: + firmware->vcc = + src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); + break; + case AVR_MMCU_TAG_AVCC: + firmware->avcc = + src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); + break; + case AVR_MMCU_TAG_AREF: + firmware->aref = + src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); + break; + case AVR_MMCU_TAG_PORT_EXTERNAL_PULL: { + for (int i = 0; i < 8; i++) + if (!firmware->external_state[i].port) { + firmware->external_state[i].port = src[2]; + firmware->external_state[i].mask = src[1]; + firmware->external_state[i].value = src[0]; +#if 0 + AVR_LOG(NULL, LOG_DEBUG, + "AVR_MMCU_TAG_PORT_EXTERNAL_PULL[%d] %c:%02x:%02x\n", + i, firmware->external_state[i].port, + firmware->external_state[i].mask, + firmware->external_state[i].value); +#endif + break; + } + } break; + case AVR_MMCU_TAG_VCD_PORTPIN: + case AVR_MMCU_TAG_VCD_IRQ: + case AVR_MMCU_TAG_VCD_TRACE: { + uint8_t mask = src[0]; + uint16_t addr = src[1] | (src[2] << 8); + char * name = (char*)src + 3; + +#if 0 + AVR_LOG(NULL, LOG_DEBUG, + "VCD_TRACE %d %04x:%02x - %s\n", tag, + addr, mask, name); +#endif + firmware->trace[firmware->tracecount].kind = tag; + firmware->trace[firmware->tracecount].mask = mask; + firmware->trace[firmware->tracecount].addr = addr; + strncpy(firmware->trace[firmware->tracecount].name, name, + sizeof(firmware->trace[firmware->tracecount].name)); + firmware->tracecount++; + } break; + case AVR_MMCU_TAG_VCD_FILENAME: { + strcpy(firmware->tracename, (char*)src); + } break; + case AVR_MMCU_TAG_VCD_PERIOD: { + firmware->traceperiod = + src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); + } break; + case AVR_MMCU_TAG_SIMAVR_COMMAND: { + firmware->command_register_addr = src[0] | (src[1] << 8); + } break; + case AVR_MMCU_TAG_SIMAVR_CONSOLE: { + firmware->console_register_addr = src[0] | (src[1] << 8); + } break; + } + size -= next; + src += next - 2; // already incremented + } +} + +static int +elf_copy_segment(int fd, Elf32_Phdr *php, uint8_t **dest) +{ + int rv; + + if (*dest == NULL) + *dest = malloc(php->p_filesz); + if (!*dest) + return -1; + + lseek(fd, php->p_offset, SEEK_SET); + rv = read(fd, *dest, php->p_filesz); + if (rv != php->p_filesz) { + AVR_LOG(NULL, LOG_ERROR, + "Got %d when reading %d bytes for %x at offset %d " + "from ELF file\n", + rv, php->p_filesz, php->p_vaddr, php->p_offset); + return -1; + } + AVR_LOG(NULL, LOG_DEBUG, "Loaded %d bytes at %x\n", + php->p_filesz, php->p_vaddr); + return 0; +} + +static int +elf_handle_segment(int fd, Elf32_Phdr *php, uint8_t **dest, const char *name) +{ + if (*dest) { + AVR_LOG(NULL, LOG_ERROR, + "Unexpected extra %s data: %d bytes at %x.\n", + name, php->p_filesz, php->p_vaddr); + return -1; + } else { + elf_copy_segment(fd, php, dest); + return 0; + } +} + +/* The structure *firmware must be pre-initialised to zero, then optionally + * tracing and VCD information may be added. + */ + +int +elf_read_firmware( + const char * file, + elf_firmware_t * firmware) +{ + Elf32_Ehdr elf_header; /* ELF header */ + Elf *elf = NULL; /* Our Elf pointer for libelf */ + Elf32_Phdr *php; /* Program header. */ + Elf_Scn *scn = NULL; /* Section Descriptor */ + size_t ph_count; /* Program Header entry count. */ + int fd, i; /* File Descriptor */ + + if ((fd = open(file, O_RDONLY | O_BINARY)) == -1 || + (read(fd, &elf_header, sizeof(elf_header))) < sizeof(elf_header)) { + AVR_LOG(NULL, LOG_ERROR, "could not read %s\n", file); + perror(file); + close(fd); + return -1; + } + +#if ELF_SYMBOLS + firmware->symbolcount = 0; + firmware->symbol = NULL; +#endif + + /* this is actually mandatory !! otherwise elf_begin() fails */ + if (elf_version(EV_CURRENT) == EV_NONE) { + /* library out of date - recover from error */ + return -1; + } + // Iterate through section headers again this time well stop when we find symbols + elf = elf_begin(fd, ELF_C_READ, NULL); + //printf("Loading elf %s : %p\n", file, elf); + + if (!elf) + return -1; + if (elf_kind(elf) != ELF_K_ELF) { + AVR_LOG(NULL, LOG_ERROR, "Unexpected ELF file type\n"); + return -1; + } + + /* Scan the Program Header Table. */ + + if (elf_getphdrnum(elf, &ph_count) != 0 || ph_count == 0 || + (php = elf32_getphdr(elf)) == NULL) { + AVR_LOG(NULL, LOG_ERROR, "No ELF Program Headers\n"); + return -1; + } + + for (i = 0; i < (int)ph_count; ++i, ++php) { +#if 0 + printf("Header %d type %d addr %x/%x size %d/%d flags %x\n", + i, php->p_type, php->p_vaddr, php->p_paddr, + php->p_filesz, php->p_memsz, php->p_flags); +#endif + if (php->p_type != PT_LOAD || php->p_filesz == 0) + continue; + if (php->p_vaddr < 0x800000) { + /* Explicit flash section. Load it. */ + + if (elf_handle_segment(fd, php, &firmware->flash, "Flash")) + continue; + firmware->flashsize = php->p_filesz; + firmware->flashbase = php->p_vaddr; + } else if (php->p_vaddr < 0x810000) { + /* Data space. If there are initialised variables, treat + * them as extra initialised flash. The C startup function + * understands that and will copy them to RAM. + */ + + if (firmware->flash) { + uint8_t *where; + + firmware->flash = realloc(firmware->flash, + firmware->flashsize + php->p_filesz); + if (!firmware->flash) + return -1; + where = firmware->flash + firmware->flashsize; + elf_copy_segment(fd, php, &where); + firmware->flashsize += php->p_filesz; + } else { + /* If this ever happens, add a second pass. */ + + AVR_LOG(NULL, LOG_ERROR, + "Initialialised data but no flash (%d bytes at %x)!\n", + php->p_filesz, php->p_vaddr); + return -1; + } + } else if (php->p_vaddr < 0x820000) { + /* EEPROM. */ + + if (elf_handle_segment(fd, php, &firmware->eeprom, "EEPROM")) + continue; + firmware->eesize = php->p_filesz; + } else if (php->p_vaddr < 0x830000) { + /* Fuses. */ + + if (elf_handle_segment(fd, php, &firmware->fuse, "Fuses")) + continue; + firmware->fusesize = php->p_filesz; + } else if (php->p_vaddr < 0x840000) { + /* Lock bits. */ + + elf_handle_segment(fd, php, &firmware->lockbits, "Lock bits"); + } + } + + /* Scan the section table for .mmcu magic and symbols. */ + + while ((scn = elf_nextscn(elf, scn)) != NULL) { + GElf_Shdr shdr; /* Section Header */ + gelf_getshdr(scn, &shdr); + char * name = elf_strptr(elf, elf_header.e_shstrndx, shdr.sh_name); + // printf("Walking elf section '%s'\n", name); + + if (!strcmp(name, ".mmcu")) { + Elf_Data *s = elf_getdata(scn, NULL); + + elf_parse_mmcu_section(firmware, s->d_buf, s->d_size); + if (shdr.sh_addr < 0x860000) + AVR_LOG(NULL, LOG_WARNING, + "Warning: ELF .mmcu section at %x may be loaded.\n", + shdr.sh_addr); + // printf("%s: size %ld\n", __FUNCTION__, s->d_size); + // avr->frequency = f_cpu; + } + +#if ELF_SYMBOLS + // When we find a section header marked SHT_SYMTAB stop and get symbols + if (shdr.sh_type == SHT_SYMTAB) { + // edata points to our symbol table + Elf_Data *edata = elf_getdata(scn, NULL); + + // how many symbols are there? this number comes from the size of + // the section divided by the entry size + int symbol_count = shdr.sh_size / shdr.sh_entsize; + + // loop through to grab all symbols + for (int i = 0; i < symbol_count; i++) { + GElf_Sym sym; /* Symbol */ + // libelf grabs the symbol data using gelf_getsym() + gelf_getsym(edata, i, &sym); + + // print out the value and size + if (ELF32_ST_BIND(sym.st_info) == STB_GLOBAL || + ELF32_ST_TYPE(sym.st_info) == STT_FUNC || + ELF32_ST_TYPE(sym.st_info) == STT_OBJECT) { + const char * name = elf_strptr(elf, shdr.sh_link, sym.st_name); + + // if its a bootloader, this symbol will be the entry point we need + if (!strcmp(name, "__vectors")) + firmware->flashbase = sym.st_value; + avr_symbol_t * s = malloc(sizeof(avr_symbol_t) + strlen(name) + 1); + strcpy((char*)s->symbol, name); + s->addr = sym.st_value; + s->size = sym.st_size; + if (!(firmware->symbolcount % 8)) + firmware->symbol = realloc( + firmware->symbol, + (firmware->symbolcount + 8) * sizeof(firmware->symbol[0])); + + // insert new element, keep the array sorted + int insert = -1; + for (int si = 0; si < firmware->symbolcount && insert == -1; si++) + if (firmware->symbol[si]->addr >= s->addr) + insert = si; + if (insert == -1) + insert = firmware->symbolcount; + else + memmove(firmware->symbol + insert + 1, + firmware->symbol + insert, + (firmware->symbolcount - insert) * sizeof(firmware->symbol[0])); + firmware->symbol[insert] = s; + firmware->symbolcount++; + } + } + } +#endif // ELF_SYMBOLS + } + elf_end(elf); + close(fd); + return 0; +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_elf.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_elf.h new file mode 100644 index 0000000..37d61d7 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_elf.h @@ -0,0 +1,103 @@ +/* + sim_elf.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __SIM_ELF_H__ +#define __SIM_ELF_H__ + +#include "avr/avr_mcu_section.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ELF_SYMBOLS +#define ELF_SYMBOLS 1 +#endif + +/* these are the addresses the gnu linker uses to + * "fake" a non-Harvard addressing space for the AVR + */ +#define AVR_SEGMENT_OFFSET_FLASH 0 +#define AVR_SEGMENT_OFFSET_EEPROM 0x00810000 + +#include "sim_avr.h" + +typedef struct elf_firmware_t { + char mmcu[64]; + uint32_t frequency; + uint32_t vcc,avcc,aref; + + char tracename[128]; // trace filename + uint32_t traceperiod; + int tracecount; + struct { + uint8_t kind; + uint8_t mask; + uint16_t addr; + char name[64]; + } trace[32]; + + struct { + char port; + uint8_t mask, value; + } external_state[8]; + + // register to listen to for commands from the firmware + uint16_t command_register_addr; + uint16_t console_register_addr; + + uint32_t flashbase; // base address + uint8_t * flash; + uint32_t flashsize; + uint32_t datasize; + uint32_t bsssize; + // read the .eeprom section of the elf, too + uint8_t * eeprom; + uint32_t eesize; + uint8_t * fuse; + uint32_t fusesize; + uint8_t * lockbits; + +#if ELF_SYMBOLS + avr_symbol_t ** symbol; + uint32_t symbolcount; +#endif +} elf_firmware_t ; + +/* The structure *firmware must be pre-initialised to zero, then optionally + * with tracing and VCD information. + */ + +int +elf_read_firmware( + const char * file, + elf_firmware_t * firmware); + +void +avr_load_firmware( + avr_t * avr, + elf_firmware_t * firmware); + +#ifdef __cplusplus +}; +#endif + +#endif /*__SIM_ELF_H__*/ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_gdb.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_gdb.c new file mode 100644 index 0000000..cd2196e --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_gdb.c @@ -0,0 +1,1026 @@ +/* + sim_gdb.c + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "sim_network.h" +#include <sys/time.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <pthread.h> +#include "sim_avr.h" +#include "sim_core.h" // for SET_SREG_FROM, READ_SREG_INTO +#include "sim_hex.h" +#include "avr_eeprom.h" +#include "sim_gdb.h" + +// For debug printfs: "#define DBG(w) w" +#define DBG(w) + +#define WATCH_LIMIT (32) + +typedef struct { + uint32_t len; /**< How many points are taken (points[0] .. points[len - 1]). */ + struct { + uint32_t addr; /**< Which address is watched. */ + uint32_t size; /**< How large is the watched segment. */ + uint32_t kind; /**< Bitmask of enum avr_gdb_watch_type values. */ + } points[WATCH_LIMIT]; +} avr_gdb_watchpoints_t; + +/* How many AVR instructions to execute before looking for gdb input. */ + +#define GDB_BURST 256 + +typedef struct avr_gdb_t { + avr_t * avr; + int burst_count; // Current instruction burst size + int listen; // listen socket + int s; // current gdb connection + + avr_gdb_watchpoints_t breakpoints; + avr_gdb_watchpoints_t watchpoints; + + // These are used by gdb's "info io_registers" command. + + uint16_t ior_base; + uint8_t ior_count, mad; +} avr_gdb_t; + + +/** + * Returns the index of the watchpoint if found, -1 otherwise. + */ +static int +gdb_watch_find( + const avr_gdb_watchpoints_t * w, + uint32_t addr ) +{ + for (int i = 0; i < w->len; i++) { + if (w->points[i].addr > addr) { + return -1; + } else if (w->points[i].addr == addr) { + return i; + } + } + return -1; +} + +/** + * Contrary to gdb_watch_find, this actually checks the address against + * a watched memory _range_. + */ +static int +gdb_watch_find_range( + const avr_gdb_watchpoints_t * w, + uint32_t addr ) +{ + for (int i = 0; i < w->len; i++) { + if (w->points[i].addr > addr) { + return -1; + } else if (w->points[i].addr <= addr && + addr < w->points[i].addr + w->points[i].size) { + return i; + } + } + return -1; +} + +/** + * Returns -1 on error, 0 otherwise. + */ +static int +gdb_watch_add_or_update( + avr_gdb_watchpoints_t * w, + enum avr_gdb_watch_type kind, + uint32_t addr, + uint32_t size ) +{ + if (kind == AVR_GDB_WATCH_ACCESS) + kind |= AVR_GDB_WATCH_WRITE | AVR_GDB_WATCH_READ; + + /* If the watchpoint exists, update it. */ + int i = gdb_watch_find(w, addr); + if (i != -1) { + w->points[i].size = size; + w->points[i].kind |= kind; + return 0; + } + + /* Otherwise add it. */ + if (w->len == WATCH_LIMIT) { + return -1; + } + + /* Find the insertion point. */ + for (i = 0; i < w->len; i++) { + if (w->points[i].addr > addr) { + break; + } + } + + w->len++; + + /* Make space for new element, moving old ones from the end. */ + for (int j = w->len; j > i; j--) { + w->points[j] = w->points[j - 1]; + } + + /* Insert it. */ + w->points[i].kind = kind; + w->points[i].addr = addr; + w->points[i].size = size; + + return 0; +} + +/** + * Returns -1 on error or if the specified point does not exist, 0 otherwise. + */ +static int +gdb_watch_rm( + avr_gdb_watchpoints_t * w, + enum avr_gdb_watch_type kind, + uint32_t addr ) +{ + int i = gdb_watch_find(w, addr); + if (i == -1) { + return -1; + } + + w->points[i].kind &= ~kind; + if (w->points[i].kind) { + return 0; + } + + for (i = i + 1; i < w->len; i++) { + w->points[i - 1] = w->points[i]; + } + + w->len--; + + return 0; +} + +static void +gdb_watch_clear( + avr_gdb_watchpoints_t * w ) +{ + w->len = 0; +} + +static void +gdb_send_reply( + avr_gdb_t * g, + char * cmd ) +{ + uint8_t reply[1024]; + uint8_t * dst = reply; + uint8_t check = 0; + *dst++ = '$'; + while (*cmd) { + check += *cmd; + *dst++ = *cmd++; + } + sprintf((char*)dst, "#%02x", check); + DBG(printf("%s '%s'\n", __FUNCTION__, reply);) + send(g->s, reply, dst - reply + 3, 0); +} + +static void +gdb_send_stop_status( + avr_gdb_t * g, + uint8_t signal, + const char * reason, + uint32_t * pp ) +{ + avr_t * avr; + uint8_t sreg; + int n; + char cmd[64]; + + avr = g->avr; + READ_SREG_INTO(avr, sreg); + + n = sprintf(cmd, "T%02x20:%02x;21:%02x%02x;22:%02x%02x%02x00;", + signal, sreg, + avr->data[R_SPL], avr->data[R_SPH], + avr->pc & 0xff, (avr->pc >> 8) & 0xff, + (avr->pc >> 16) & 0xff); + if (reason) { + if (pp) + sprintf(cmd + n, "%s:%x;", reason, *pp); + else + sprintf(cmd + n, "%s:;", reason); + } + gdb_send_reply(g, cmd); +} + +static void +gdb_send_quick_status( + avr_gdb_t * g, + uint8_t signal ) +{ + gdb_send_stop_status(g, signal, NULL, NULL); +} + +static int +gdb_change_breakpoint( + avr_gdb_watchpoints_t * w, + int set, + enum avr_gdb_watch_type kind, + uint32_t addr, + uint32_t size ) +{ + DBG(printf("%s kind %d addr %08x len %d\n", set ? "Set" : "Clear", + kind, addr, size);) + + if (set) { + return gdb_watch_add_or_update(w, kind, addr, size); + } else { + return gdb_watch_rm(w, kind, addr); + } + return -1; +} + +static int +gdb_write_register( + avr_gdb_t * g, + int regi, + uint8_t * src ) +{ + switch (regi) { + case 0 ... 31: + g->avr->data[regi] = *src; + return 1; + case 32: + g->avr->data[R_SREG] = *src; + SET_SREG_FROM(g->avr, *src); + return 1; + case 33: + g->avr->data[R_SPL] = src[0]; + g->avr->data[R_SPH] = src[1]; + return 2; + case 34: + g->avr->pc = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); + return 4; + } + return 1; +} + +static int +gdb_read_register( + avr_gdb_t * g, + int regi, + char * rep ) +{ + switch (regi) { + case 0 ... 31: + sprintf(rep, "%02x", g->avr->data[regi]); + break; + case 32: { + uint8_t sreg; + READ_SREG_INTO(g->avr, sreg); + sprintf(rep, "%02x", sreg); + } + break; + case 33: + sprintf(rep, "%02x%02x", g->avr->data[R_SPL], g->avr->data[R_SPH]); + break; + case 34: + sprintf(rep, "%02x%02x%02x00", + g->avr->pc & 0xff, (g->avr->pc>>8)&0xff, (g->avr->pc>>16)&0xff); + break; + } + return strlen(rep); +} + +static int tohex(const char *in, char *out, unsigned int len) +{ + int n = 0; + + while (*in && n + 2 < len) + n += sprintf(out + n, "%02x", (uint8_t)*in++); + return n; +} + +/* Send a message to the user. Gdb must be expecting a reply, otherwise this + * is ignored. + */ + +static void message(avr_gdb_t * g, const char *m) +{ + char buff[256]; + + buff[0] = 'O'; + tohex(m, buff + 1, sizeof buff - 1); + gdb_send_reply(g, buff); +} + +static int +handle_monitor(avr_t * avr, avr_gdb_t * g, char * cmd) +{ + char *ip, *op; + unsigned int c1, c2; + char dehex[128]; + + if (*cmd++ != ',') + return 1; // Bad format + for (op = dehex; op < dehex + (sizeof dehex - 1); ++op) { + if (!*cmd) + break; + if (sscanf(cmd, "%1x%1x", &c1, &c2) != 2) + return 2; // Bad format + *op = (c1 << 4) + c2; + cmd += 2; + } + *op = '\0'; + if (*cmd) + return 3; // Too long + ip = dehex; + while (*ip) { + while (*ip == ' ' || *ip == '\t') + ++ip; + + if (strncmp(ip, "reset", 5) == 0) { + avr_reset(avr); + avr->state = cpu_Stopped; + ip += 5; + } else if (strncmp(ip, "halt", 4) == 0) { + avr->state = cpu_Stopped; + ip += 4; + } else if (strncmp(ip, "ior", 3) == 0) { + unsigned int base; + int n, m, count; + + // Format is "ior <base> <count> + // or just "ior" to reset. + + ip += 3; + m = sscanf(ip, "%x %i%n", &base, &count, &n); + if (m <= 0) { + // Reset values. + + g->ior_base = g->ior_count = 0; + n = 0; + } else if (m != 2) { + return 1; + } else { + if (count <= 0 || base + count + 32 > REG_NAME_COUNT || + base + count + 32 > avr->ioend) { + return 4; // bad value + } + g->ior_base = base; + g->ior_count = count; + } + ip += n; + DBG( + } else if (strncmp(ip, "say ", 4) == 0) { + // Put a message in the debug output. + printf("Say: %s\n", ip + 4); + ip += strlen(ip); + ) + } else { + tohex("Monitor subcommands are: ior halt reset" DBG(" say") "\n", + dehex, sizeof dehex); + gdb_send_reply(g, dehex); + return -1; + } + } + return 0; +} + +static void +handle_io_registers(avr_t * avr, avr_gdb_t * g, char * cmd) +{ + extern const char *avr_regname(unsigned int); // sim_core.c + char * params; + char * reply; + unsigned int addr, count; + char buff[1024]; + + if (g->mad) { + /* For this command, gdb employs a streaming protocol, + * with the command being repeated until the stub sends + * an empy packet as terminator. That makes no sense, + * as the requests are sized to ensure the reply will + * fit in a single packet. + */ + + reply = ""; + g->mad = 0; + } else { + params = cmd + 11; + if (sscanf(params, ":%x,%x", &addr, &count) == 2) { + int i; + + // Send names and values. + addr += 32; + if (addr + count > avr->ioend) + count = avr->ioend + 1 - addr; + reply = buff; + for (i = 0; i < count; ++i) { + const char *name; + + name = avr_regname(addr + i); + reply += sprintf(reply, "%s,%x;", + name, avr->data[addr + i]); + if (reply > buff + sizeof buff - 20) + break; + } + } else { + // Send register count. + + count = g->ior_count ? g->ior_count : + avr->ioend > REG_NAME_COUNT ? + REG_NAME_COUNT - 32 : avr->ioend - 32; + sprintf(buff, "%x", count); + } + reply = buff; + g->mad = 1; + } + gdb_send_reply(g, reply); +} + +static void +handle_v(avr_t * avr, avr_gdb_t * g, char * cmd, int length) +{ + uint32_t addr; + uint8_t *src = NULL; + int len, err = -1; + + if (strncmp(cmd, "FlashErase", 10) == 0) { + + sscanf(cmd, "%*[^:]:%x,%x", &addr, &len); + if (addr < avr->flashend) { + src = avr->flash + addr; + if (addr + len > avr->flashend) + len = avr->flashend - addr; + memset(src, 0xff, len); + DBG(printf("FlashErase: %x,%x\n", addr, len);) //Remove + } else { + err = 1; + } + } else if (strncmp(cmd, "FlashWrite", 10) == 0) { + if (sscanf(cmd, "%*[^:]:%x:%n", &addr, &len) != 1) { + err = 2; + } else { + if (len >= length) { + err = 99; + } else if (addr < avr->flashend) { + int escaped; + char *end; + uint8_t *limit; + + end = cmd + length - 1; // Ignore final '#'. + cmd += len; + src = avr->flash + addr; + limit = avr->flash + avr->flashend; + for (escaped = 0; cmd < end && src < limit; ++cmd) { + if (escaped) { + *src++ = *cmd ^ 0x20; + escaped = 0; + } else if (*cmd == '}') { + escaped = 1; + } else { + *src++ = *cmd; + } + } + DBG(printf("FlashWrite %x, %ld bytes\n", addr, + (src - avr->flash) - addr);) + addr = src - avr->flash; // Address of end. + if (addr > avr->codeend) // Checked by sim_core.c + avr->codeend = addr; + if (cmd != end) { + DBG(printf("FlashWrite %ld bytes left!\n", end - cmd)); + } + } else { + err = 1; + } + } + } else if (strncmp(cmd, "FlashDone", 9) == 0) { + DBG(printf("FlashDone\n");) //Remove + } else { + gdb_send_reply(g, ""); + return; + } + + if (err < 0) { + gdb_send_reply(g, "OK"); + } else { + char b[32]; + + sprintf(b, "E %.2d", err); + gdb_send_reply(g, b); + } +} + +static void +gdb_handle_command( + avr_gdb_t * g, + char * cmd, + int length) +{ + avr_t * avr = g->avr; + char rep[1024]; + uint8_t command = *cmd++; + switch (command) { + case 'q': + if (strncmp(cmd, "Supported", 9) == 0) { + /* If GDB asked what features we support, report back + * the features we support, which is just memory layout + * information and stop reasons for now. + */ + gdb_send_reply(g, "qXfer:memory-map:read+;swbreak+;hwbreak+"); + break; + } else if (strncmp(cmd, "Attached", 8) == 0) { + /* Respond that we are attached to an existing process.. + * ourselves! + */ + gdb_send_reply(g, "1"); + break; + // Rmoving the following 3 lines fixes #150 issue: + // } else if (strncmp(cmd, "Offsets", 7) == 0) { + // gdb_send_reply(g, "Text=0;Data=800000;Bss=800000"); + // break; + } else if (strncmp(cmd, "Xfer:memory-map:read", 20) == 0) { + snprintf(rep, sizeof(rep), + "l<memory-map>\n" + " <memory type='ram' start='0x800000' length='%#x'/>\n" + " <memory type='flash' start='0' length='%#x'>\n" + " <property name='blocksize'>0x80</property>\n" + " </memory>\n" + "</memory-map>", + g->avr->ramend + 1, g->avr->flashend + 1); + + gdb_send_reply(g, rep); + break; + } else if (strncmp(cmd, "RegisterInfo", 12) == 0) { + // Send back the information we have on this register (if any). + long n = strtol(cmd + 12, NULL, 16); + if (n < 32) { + // General purpose (8-bit) registers. + snprintf(rep, sizeof(rep), "name:r%ld;bitsize:8;offset:0;encoding:uint;format:hex;set:General Purpose Registers;gcc:%ld;dwarf:%ld;", n, n, n); + gdb_send_reply(g, rep); + break; + } else if (n == 32) { + // SREG (flags) register. + snprintf(rep, sizeof(rep), "name:sreg;bitsize:8;offset:0;encoding:uint;format:binary;set:General Purpose Registers;gcc:32;dwarf:32;"); + gdb_send_reply(g, rep); + break; + } else if (n == 33) { + // SP register (SPH and SPL combined). + snprintf(rep, sizeof(rep), "name:sp;bitsize:16;offset:0;encoding:uint;format:hex;set:General Purpose Registers;gcc:33;dwarf:33;generic:sp;"); + gdb_send_reply(g, rep); + break; + } else if (n == 34) { + // PC register + snprintf(rep, sizeof(rep), "name:pc;bitsize:32;offset:0;encoding:uint;format:hex;set:General Purpose Registers;gcc:34;dwarf:34;generic:pc;"); + gdb_send_reply(g, rep); + break; + } else { + // Register not available. + // By sending back nothing, the debugger knows it has read + // all available registers. + } + } else if (strncmp(cmd, "Rcmd", 4) == 0) { // monitor command + int err = handle_monitor(avr, g, cmd + 4); + if (err > 0) { + snprintf(rep, sizeof rep, + "E%02x", err); + gdb_send_reply(g, rep); + } else if (err == 0) { + gdb_send_reply(g, "OK"); + } + break; + } else if (strncmp(cmd, "Ravr.io_reg", 11) == 0) { + handle_io_registers(avr, g, cmd); + break; + } + gdb_send_reply(g, ""); + break; + case '?': + gdb_send_quick_status(g, 0); + break; + case 'G': { // set all general purpose registers + // get their binary form + read_hex_string(cmd, (uint8_t*)rep, strlen(cmd)); + uint8_t *src = (uint8_t*)rep; + for (int i = 0; i < 35; i++) + src += gdb_write_register(g, i, src); + gdb_send_reply(g, "OK"); + } break; + case 'g': { // read all general purpose registers + char * dst = rep; + for (int i = 0; i < 35; i++) + dst += gdb_read_register(g, i, dst); + gdb_send_reply(g, rep); + } break; + case 'p': { // read register + unsigned int regi = 0; + sscanf(cmd, "%x", ®i); + gdb_read_register(g, regi, rep); + gdb_send_reply(g, rep); + } break; + case 'P': { // write register + unsigned int regi = 0; + char * val = strchr(cmd, '='); + if (!val) + break; + *val++ = 0; + sscanf(cmd, "%x", ®i); + read_hex_string(val, (uint8_t*)rep, strlen(val)); + gdb_write_register(g, regi, (uint8_t*)rep); + gdb_send_reply(g, "OK"); + } break; + case 'm': { // read memory + avr_flashaddr_t addr; + uint32_t len; + sscanf(cmd, "%x,%x", &addr, &len); + uint8_t * src = NULL; + /* GDB seems to also use 0x1800000 for sram ?!?! */ + addr &= 0xffffff; + if (addr < avr->flashend) { + src = avr->flash + addr; + } else if (addr >= 0x800000 && (addr - 0x800000) <= avr->ramend) { + src = avr->data + addr - 0x800000; + } else if (addr == (0x800000 + avr->ramend + 1) && len == 2) { + // Allow GDB to read a value just after end of stack. + // This is necessary to make instruction stepping work when stack is empty + AVR_LOG(avr, LOG_TRACE, + "GDB: read just past end of stack %08x, %08x; returning zero\n", addr, len); + gdb_send_reply(g, "0000"); + break; + } else if (addr >= 0x810000 && (addr - 0x810000) <= avr->e2end) { + avr_eeprom_desc_t ee = {.offset = (addr - 0x810000)}; + avr_ioctl(avr, AVR_IOCTL_EEPROM_GET, &ee); + if (ee.ee) + src = ee.ee; + else { + gdb_send_reply(g, "E01"); + break; + } + } else { + AVR_LOG(avr, LOG_ERROR, + "GDB: read memory error %08x, %08x (ramend %04x)\n", + addr, len, avr->ramend+1); + gdb_send_reply(g, "E01"); + break; + } + char * dst = rep; + while (len--) { + sprintf(dst, "%02x", *src++); + dst += 2; + } + *dst = 0; + gdb_send_reply(g, rep); + } break; + case 'M': { // write memory + uint32_t addr, len; + sscanf(cmd, "%x,%x", &addr, &len); + char * start = strchr(cmd, ':'); + if (!start) { + gdb_send_reply(g, "E01"); + break; + } + if (addr < 0xffff) { + read_hex_string(start + 1, avr->flash + addr, strlen(start+1)); + gdb_send_reply(g, "OK"); + } else if (addr >= 0x800000 && (addr - 0x800000) <= avr->ramend) { + read_hex_string(start + 1, avr->data + addr - 0x800000, strlen(start+1)); + gdb_send_reply(g, "OK"); + } else if (addr >= 0x810000 && (addr - 0x810000) <= avr->e2end) { + read_hex_string(start + 1, (uint8_t*)rep, strlen(start+1)); + avr_eeprom_desc_t ee = {.offset = (addr - 0x810000), .size = len, .ee = (uint8_t*)rep }; + avr_ioctl(avr, AVR_IOCTL_EEPROM_SET, &ee); + gdb_send_reply(g, "OK"); + } else { + AVR_LOG(avr, LOG_ERROR, "GDB: write memory error %08x, %08x\n", addr, len); + gdb_send_reply(g, "E01"); + } + } break; + case 'c': { // continue + avr->state = cpu_Running; + } break; + case 's': { // step + avr->state = cpu_Step; + } break; + case 'r': { // deprecated, suggested for AVRStudio compatibility + avr_reset(avr); + avr->state = cpu_Stopped; + } break; + case 'Z': // set clear break/watchpoint + case 'z': { + uint32_t kind, addr, len; + int set = (command == 'Z'); + sscanf(cmd, "%d,%x,%x", &kind, &addr, &len); +// printf("breakpoint %d, %08x, %08x\n", kind, addr, len); + switch (kind) { + case 0: // software breakpoint + case 1: // hardware breakpoint + if (addr > avr->flashend || + gdb_change_breakpoint(&g->breakpoints, set, 1 << kind, addr, len) == -1) { + gdb_send_reply(g, "E01"); + break; + } + + gdb_send_reply(g, "OK"); + break; + case 2: // write watchpoint + case 3: // read watchpoint + case 4: // access watchpoint + /* Mask out the offset applied to SRAM addresses. */ + addr &= ~0x800000; + if (addr > avr->ramend || + gdb_change_breakpoint(&g->watchpoints, set, 1 << kind, addr, len) == -1) { + gdb_send_reply(g, "E01"); + break; + } + + gdb_send_reply(g, "OK"); + break; + default: + gdb_send_reply(g, ""); + break; + } + } break; + case 'D': // detach +#ifdef DETACHABLE + if (avr->state = cpu_Stopped) + avr->state = cpu_Running; + gdb_send_reply(g, "OK"); + close(g->s); + g->s = -1; + break; +#endif + case 'k': // kill + avr->state = cpu_Done; + gdb_send_reply(g, "OK"); + break; + case 'v': + handle_v(avr, g, cmd, length); + break; + default: + gdb_send_reply(g, ""); + break; + } +} + +static int +gdb_network_handler( + avr_gdb_t * g, + uint32_t dosleep ) +{ + fd_set read_set; + int max; + FD_ZERO(&read_set); + + g->burst_count = 0; // Reset burst count + if (g->s != -1) { + FD_SET(g->s, &read_set); + max = g->s + 1; + } else { + FD_SET(g->listen, &read_set); + max = g->listen + 1; + } + struct timeval timo = { dosleep / 1000000, dosleep % 1000000 }; + int ret = select(max, &read_set, NULL, NULL, &timo); + + if (ret == 0) + return 0; + + if (FD_ISSET(g->listen, &read_set)) { + g->s = accept(g->listen, NULL, NULL); + + if (g->s == -1) { + perror("gdb_network_handler accept"); + sleep(5); + return 1; + } + int i = 1; + setsockopt (g->s, IPPROTO_TCP, TCP_NODELAY, &i, sizeof (i)); + g->avr->state = cpu_Stopped; + DBG(printf("%s connection opened\n", __FUNCTION__);) + } + + if (g->s != -1 && FD_ISSET(g->s, &read_set)) { + uint8_t buffer[1024]; + + ssize_t r = recv(g->s, buffer, sizeof(buffer)-1, 0); + + if (r == 0) { + DBG(printf("%s connection closed\n", __FUNCTION__);) + close(g->s); + gdb_watch_clear(&g->breakpoints); + gdb_watch_clear(&g->watchpoints); + g->avr->state = cpu_Running; // resume + g->s = -1; + return 1; + } + if (r == -1) { + perror("gdb_network_handler recv"); + sleep(1); + return 1; + } + buffer[r] = 0; + + uint8_t * src = buffer; + while (*src == '+' || *src == '-') + src++; + DBG( + if (!strncmp("$vFlashWrite", (char *)src, 12)) { + printf("%s: received Flashwrite command %ld bytes\n", + __FUNCTION__, r); + } else { + printf("%s: received command %ld bytes\n'%s'\n", + __FUNCTION__, r, buffer); + }) + // hdump("gdb", buffer, r); + // control C -- lets send the guy a nice status packet + if (*src == 3) { + src++; + gdb_send_quick_status(g, 2); // SIGINT + g->avr->state = cpu_Stopped; + printf("GDB hit control-c\n"); + } else if (*src == '$') { + // strip checksum + uint8_t * end = buffer + r - 1; + while (end > src && *end != '#') + *end-- = 0; + *end = 0; + src++; + DBG( + if (strncmp("vFlashWrite", (char *)src, 11)) + printf("GDB command = '%s'\n", src);) + send(g->s, "+", 1, 0); + if (end > src) + gdb_handle_command(g, (char*)src, end - src); + } + } + return 1; +} + +/* Called on a hardware break instruction. */ +void avr_gdb_handle_break(avr_t *avr) +{ + avr_gdb_t *g = avr->gdb; + + message(g, "Simavr executed 'break' instruction.\n"); + //gdb_send_stop_status(g, 5, "swbreak", NULL); Correct but ignored! + gdb_send_quick_status(g, 5); +} + +/** + * If an applicable watchpoint exists for addr, stop the cpu and send a status report. + * type is one of AVR_GDB_WATCH_READ, AVR_GDB_WATCH_WRITE depending on the type of access. + */ +void +avr_gdb_handle_watchpoints( + avr_t * avr, + uint16_t addr, + enum avr_gdb_watch_type type ) +{ + avr_gdb_t *g = avr->gdb; + uint32_t false_addr; + + int i = gdb_watch_find_range(&g->watchpoints, addr); + if (i == -1) { + return; + } + + int kind = g->watchpoints.points[i].kind; + DBG(printf("Addr %04x found watchpoint %d size %d type %x wanted %x\n", + addr, i, g->watchpoints.points[i].size, kind, type);) + if (kind & type) { + /* Send gdb reply (see GDB user manual appendix E.3). */ + + const char * what; + + what = (kind & AVR_GDB_WATCH_ACCESS) ? "awatch" : + (kind & AVR_GDB_WATCH_WRITE) ? "watch" : "rwatch"; + false_addr = addr + 0x800000; + gdb_send_stop_status(g, 5, what, &false_addr); + avr->state = cpu_Stopped; + } +} + +int +avr_gdb_processor( + avr_t * avr, + int sleep ) +{ + if (!avr || !avr->gdb) + return 0; + avr_gdb_t * g = avr->gdb; + + if (avr->state == cpu_Running && + gdb_watch_find(&g->breakpoints, avr->pc) != -1) { + DBG(printf("avr_gdb_processor hit breakpoint at %08x\n", avr->pc);) + gdb_send_stop_status(g, 5, "hwbreak", NULL); + avr->state = cpu_Stopped; + } else if (avr->state == cpu_StepDone) { + gdb_send_quick_status(g, 0); + avr->state = cpu_Stopped; + } else { + /* Look for gdb input every GDB_BURST instructions. */ + + if (sleep == 0 && g->burst_count++ < GDB_BURST) + return 0; + } + return gdb_network_handler(g, sleep); +} + + +int +avr_gdb_init( + avr_t * avr ) +{ + if (avr->gdb) + return 0; // GDB server already is active + + avr_gdb_t * g = malloc(sizeof(avr_gdb_t)); + memset(g, 0, sizeof(avr_gdb_t)); + + avr->gdb = NULL; + + if ( network_init() ) { + AVR_LOG(avr, LOG_ERROR, "GDB: Can't initialize network"); + goto error; + } + + if ((g->listen = socket(PF_INET, SOCK_STREAM, 0)) < 0) { + AVR_LOG(avr, LOG_ERROR, "GDB: Can't create socket: %s", strerror(errno)); + goto error; + } + + int optval = 1; + setsockopt(g->listen, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); + + struct sockaddr_in address = { 0 }; + address.sin_family = AF_INET; + address.sin_port = htons (avr->gdb_port); + + if (bind(g->listen, (struct sockaddr *) &address, sizeof(address))) { + AVR_LOG(avr, LOG_ERROR, "GDB: Can not bind socket: %s", strerror(errno)); + goto error; + } + if (listen(g->listen, 1)) { + perror("listen"); + goto error; + } + printf("avr_gdb_init listening on port %d\n", avr->gdb_port); + g->avr = avr; + g->s = -1; + avr->gdb = g; + // change default run behaviour to use the slightly slower versions + avr->run = avr_callback_run_gdb; + avr->sleep = avr_callback_sleep_gdb; + + return 0; + +error: + if (g->listen >= 0) + close(g->listen); + free(g); + + return -1; +} + +void +avr_deinit_gdb( + avr_t * avr ) +{ + if (!avr->gdb) + return; + avr->run = avr_callback_run_raw; // restore normal callbacks + avr->sleep = avr_callback_sleep_raw; + if (avr->gdb->listen != -1) + close(avr->gdb->listen); + avr->gdb->listen = -1; + if (avr->gdb->s != -1) + close(avr->gdb->s); + avr->gdb->s = -1; + free(avr->gdb); + avr->gdb = NULL; + + network_release(); +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_gdb.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_gdb.h new file mode 100644 index 0000000..2936df7 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_gdb.h @@ -0,0 +1,55 @@ +/* + sim_gdb.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __SIM_GDB_H__ +#define __SIM_GDB_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Watchpoint types. + See GDB User Manual, Appendix E.2 */ +enum avr_gdb_watch_type { + AVR_GDB_BREAK_SOFT = 1 << 0, + AVR_GDB_BREAK_HARD = 1 << 1, + + AVR_GDB_WATCH_WRITE = 1 << 2, + AVR_GDB_WATCH_READ = 1 << 3, + AVR_GDB_WATCH_ACCESS = 1 << 4 +}; + +int avr_gdb_init(avr_t * avr); + +void avr_deinit_gdb(avr_t * avr); + +// call from the main AVR decoder thread +int avr_gdb_processor(avr_t * avr, int sleep); + +// Called from sim_core.c +void avr_gdb_handle_watchpoints(avr_t * g, uint16_t addr, enum avr_gdb_watch_type type); +void avr_gdb_handle_break(avr_t *); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_hex.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_hex.c new file mode 100644 index 0000000..fea67c4 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_hex.c @@ -0,0 +1,287 @@ +/* + sim_hex.c + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "sim_hex.h" +#include "sim_elf.h" + +// friendly hex dump +void hdump(const char *w, uint8_t *b, size_t l) +{ + uint32_t i; + if (l < 16) { + printf("%s: ",w); + for (i = 0; i < l; i++) printf("%02x",b[i]); + } else { + printf("%s:\n",w); + for (i = 0; i < l; i++) { + if (!(i & 0x1f)) printf(" "); + printf("%02x",b[i]); + if ((i & 0x1f) == 0x1f) { + printf(" "); + printf("\n"); + } + } + } + printf("\n"); +} + + // decode line text hex to binary +int read_hex_string(const char * src, uint8_t * buffer, int maxlen) +{ + uint8_t * dst = buffer; + int ls = 0; + uint8_t b = 0; + while (*src && maxlen) { + char c = *src++; + switch (c) { + case 'a' ... 'f': b = (b << 4) | (c - 'a' + 0xa); break; + case 'A' ... 'F': b = (b << 4) | (c - 'A' + 0xa); break; + case '0' ... '9': b = (b << 4) | (c - '0'); break; + default: + if (c > ' ') { + fprintf(stderr, "%s: huh '%c' (%s)\n", __FUNCTION__, c, src); + return -1; + } + continue; + } + if (ls & 1) { + *dst++ = b; b = 0; + maxlen--; + } + ls++; + } + + return dst - buffer; +} + +void +free_ihex_chunks( + ihex_chunk_p chunks) +{ + if (!chunks) + return; + for (int i = 0; chunks[i].size; i++) + if (chunks[i].data) + free(chunks[i].data); +} + +int +read_ihex_chunks( + const char * fname, + ihex_chunk_p * chunks ) +{ + if (!fname || !chunks) + return -1; + FILE * f = fopen(fname, "r"); + if (!f) { + perror(fname); + return -1; + } + uint32_t segment = 0; // segment address + int chunk = 0, max_chunks = 0; + *chunks = NULL; + + while (!feof(f)) { + char line[128]; + if (!fgets(line, sizeof(line)-1, f)) + continue; + if (line[0] != ':') { + fprintf(stderr, "AVR: '%s' invalid ihex format (%.4s)\n", fname, line); + break; + } + uint8_t bline[64]; + + int len = read_hex_string(line + 1, bline, sizeof(bline)); + if (len <= 0) + continue; + + uint8_t chk = 0; + { // calculate checksum + uint8_t * src = bline; + int tlen = len-1; + while (tlen--) + chk += *src++; + chk = 0x100 - chk; + } + if (chk != bline[len-1]) { + fprintf(stderr, "%s: %s, invalid checksum %02x/%02x\n", __FUNCTION__, fname, chk, bline[len-1]); + break; + } + uint32_t addr = 0; + switch (bline[3]) { + case 0: // normal data + addr = segment | (bline[1] << 8) | bline[2]; + break; + case 1: // end of file - reset segment + segment = 0; + continue; + case 2: // extended address 2 bytes + segment = ((bline[4] << 8) | bline[5]) << 4; + continue; + case 4: + segment = ((bline[4] << 8) | bline[5]) << 16; + continue; + default: + fprintf(stderr, "%s: %s, unsupported check type %02x\n", __FUNCTION__, fname, bline[3]); + continue; + } + if (chunk < max_chunks && addr != ((*chunks)[chunk].baseaddr + (*chunks)[chunk].size)) { + if ((*chunks)[chunk].size) + chunk++; + } + if (chunk >= max_chunks) { + max_chunks++; + /* Here we allocate and zero an extra chunk, to act as terminator */ + *chunks = realloc(*chunks, (1 + max_chunks) * sizeof(ihex_chunk_t)); + memset(*chunks + chunk, 0, + (1 + (max_chunks - chunk)) * sizeof(ihex_chunk_t)); + (*chunks)[chunk].baseaddr = addr; + } + (*chunks)[chunk].data = realloc((*chunks)[chunk].data, + (*chunks)[chunk].size + bline[0]); + memcpy((*chunks)[chunk].data + (*chunks)[chunk].size, + bline + 4, bline[0]); + (*chunks)[chunk].size += bline[0]; + } + fclose(f); + return max_chunks; +} + + +uint8_t * +read_ihex_file( + const char * fname, uint32_t * dsize, uint32_t * start) +{ + ihex_chunk_p chunks = NULL; + int count = read_ihex_chunks(fname, &chunks); + uint8_t * res = NULL; + + if (count > 0) { + *dsize = chunks[0].size; + *start = chunks[0].baseaddr; + res = chunks[0].data; + chunks[0].data = NULL; + } + if (count > 1) { + fprintf(stderr, "AVR: '%s' ihex contains more chunks than loaded (%d)\n", + fname, count); + } + free_ihex_chunks(chunks); + return res; +} + +/* Load a firmware file, ELF or HEX format, from filename, based at + * loadBase, returning the data in *fp ready for loading into + * the simulated MCU. Progname is the current program name for error messages. + * + * Included here as it mostly specific to HEX files. + */ + +void +sim_setup_firmware(const char * filename, uint32_t loadBase, + elf_firmware_t * fp, const char * progname) +{ + char * suffix = strrchr(filename, '.'); + + if (suffix && !strcasecmp(suffix, ".hex")) { + if (!(fp->mmcu[0] && fp->frequency > 0)) { + printf("MCU type and frequency are not set " + "when loading .hex file\n"); + } + ihex_chunk_p chunk = NULL; + int cnt = read_ihex_chunks(filename, &chunk); + if (cnt <= 0) { + fprintf(stderr, + "%s: Unable to load IHEX file %s\n", progname, filename); + exit(1); + } + printf("Loaded %d section(s) of ihex\n", cnt); + + for (int ci = 0; ci < cnt; ci++) { + if (chunk[ci].baseaddr < (1*1024*1024)) { + if (fp->flash) { + printf("Ignoring chunk %d, " + "possible flash redefinition %08x, %d\n", + ci, chunk[ci].baseaddr, chunk[ci].size); + free(chunk[ci].data); + chunk[ci].data = NULL; + continue; + } + fp->flash = chunk[ci].data; + fp->flashsize = chunk[ci].size; + fp->flashbase = chunk[ci].baseaddr; + printf("Load HEX flash %08x, %d at %08x\n", + fp->flashbase, fp->flashsize, fp->flashbase); + } else if (chunk[ci].baseaddr >= AVR_SEGMENT_OFFSET_EEPROM || + (chunk[ci].baseaddr + loadBase) >= + AVR_SEGMENT_OFFSET_EEPROM) { + // eeprom! + + if (fp->eeprom) { + + // Converting ELF with .mmcu section will do this. + + printf("Ignoring chunk %d, " + "possible eeprom redefinition %08x, %d\n", + ci, chunk[ci].baseaddr, chunk[ci].size); + free(chunk[ci].data); + chunk[ci].data = NULL; + continue; + } + fp->eeprom = chunk[ci].data; + fp->eesize = chunk[ci].size; + printf("Load HEX eeprom %08x, %d\n", + chunk[ci].baseaddr, fp->eesize); + } + } + free(chunk); + } else { + if (elf_read_firmware(filename, fp) == -1) { + fprintf(stderr, "%s: Unable to load firmware from file %s\n", + progname, filename); + exit(1); + } + } +} + +#ifdef IHEX_TEST +// gcc -std=gnu99 -Isimavr/sim simavr/sim/sim_hex.c -o sim_hex -DIHEX_TEST -Dtest_main=main +int test_main(int argc, char * argv[]) +{ + struct ihex_chunk_t chunk[4]; + + for (int fi = 1; fi < argc; fi++) { + int c = read_ihex_chunks(argv[fi], chunk, 4); + if (c == -1) { + perror(argv[fi]); + continue; + } + for (int ci = 0; ci < c; ci++) { + char n[96]; + sprintf(n, "%s[%d] = %08x", argv[fi], ci, chunk[ci].baseaddr); + hdump(n, chunk[ci].data, chunk[ci].size); + } + } +} +#endif diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_hex.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_hex.h new file mode 100644 index 0000000..e3a1d1f --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_hex.h @@ -0,0 +1,90 @@ +/* + sim_hex.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef __SIM_HEX_H___ +#define __SIM_HEX_H___ + +#include <stdint.h> +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +// Load a firmware file, ELF or HEX format, ready for use. + +struct elf_firmware_t; // Predeclaration ... + +void +sim_setup_firmware( + const char * filename, // Firmware file + uint32_t loadBase, // Base of load region + struct elf_firmware_t * fp, // Data returned here + const char * progname); // For error messages. + +// parses a hex text string 'src' of at max 'maxlen' characters, decodes it into 'buffer' +int +read_hex_string( + const char * src, + uint8_t * buffer, + int maxlen); + +// a .hex file chunk (base address + size) +typedef struct ihex_chunk_t { + uint32_t baseaddr; // offset it started at in the .hex file + uint8_t * data; // read data + uint32_t size; // read data size +} ihex_chunk_t, *ihex_chunk_p; + +/* + * Read a .hex file, detects the various different chunks in it from their starting + * addresses and allocate an array of ihex_chunk_t returned in 'chunks'. + * Returns the number of chunks found, or -1 if an error occurs. + */ +int +read_ihex_chunks( + const char * fname, + ihex_chunk_p * chunks ); +/* Frees previously allocated chunks */ +void +free_ihex_chunks( + ihex_chunk_p chunks); + +// reads IHEX file 'fname', puts it's decoded size in *'dsize' and returns +// a newly allocated buffer with the binary data (or NULL, if error) +uint8_t * +read_ihex_file( + const char * fname, + uint32_t * dsize, + uint32_t * start); + +// hex dump from pointer 'b' for 'l' bytes with string prefix 'w' +void +hdump( + const char *w, + uint8_t *b, size_t l); + +#ifdef __cplusplus +}; +#endif + +#endif /* __SIM_HEX_H___ */ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_interrupts.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_interrupts.c new file mode 100644 index 0000000..9e3ed9c --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_interrupts.c @@ -0,0 +1,296 @@ +/* + sim_interrupts.c + + Copyright 2008-2012 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include "sim_interrupts.h" +#include "sim_avr.h" +#include "sim_core.h" + +DEFINE_FIFO(avr_int_vector_p, avr_int_pending); + +void +avr_interrupt_init( + avr_t * avr ) +{ + avr_int_table_p table = &avr->interrupts; + memset(table, 0, sizeof(*table)); + + static const char *names[] = { ">avr.int.pending", ">avr.int.running" }; + avr_init_irq(&avr->irq_pool, table->irq, + 0, // base number + AVR_INT_IRQ_COUNT, names); +} + +void +avr_interrupt_reset( + avr_t * avr ) +{ + avr_int_table_p table = &avr->interrupts; + + table->running_ptr = 0; + avr_int_pending_reset(&table->pending); + avr->interrupt_state = 0; + for (int i = 0; i < table->vector_count; i++) + table->vector[i]->pending = 0; +} + +void +avr_register_vector( + avr_t *avr, + avr_int_vector_t * vector) +{ + if (!vector->vector) + return; + + avr_int_table_p table = &avr->interrupts; + + char name0[48], name1[48]; + sprintf(name0, ">avr.int.%02x.pending", vector->vector); + sprintf(name1, ">avr.int.%02x.running", vector->vector); + const char *names[2] = { name0, name1 }; + avr_init_irq(&avr->irq_pool, vector->irq, + vector->vector * 256, // base number + AVR_INT_IRQ_COUNT, names); + table->vector[table->vector_count++] = vector; + if (vector->trace) + printf("IRQ%d registered (enabled %04x:%d)\n", + vector->vector, vector->enable.reg, vector->enable.bit); + + if (!vector->enable.reg) + AVR_LOG(avr, LOG_WARNING, "IRQ%d No 'enable' bit !\n", + vector->vector); +} + +int +avr_has_pending_interrupts( + avr_t * avr) +{ + avr_int_table_p table = &avr->interrupts; + return !avr_int_pending_isempty(&table->pending); +} + +int +avr_is_interrupt_pending( + avr_t * avr, + avr_int_vector_t * vector) +{ + return vector->pending; +} + +int +avr_is_interrupt_enabled( + avr_t * avr, + avr_int_vector_t * vector) +{ + return avr_regbit_get(avr, vector->enable); +} + +int +avr_raise_interrupt( + avr_t * avr, + avr_int_vector_t * vector) +{ + if (!vector || !vector->vector) + return 0; + + if (vector->trace) + printf("IRQ%d raising (enabled %d)\n", + vector->vector, avr_regbit_get(avr, vector->enable)); + + // always mark the 'raised' flag to one, even if the interrupt is disabled + // this allow "polling" for the "raised" flag, like for non-interrupt + // driven UART and so so. These flags are often "write one to clear" + if (vector->raised.reg) + avr_regbit_set(avr, vector->raised); + + if (vector->pending) { + if (vector->trace) + printf("IRQ%d:I=%d already raised (enabled %d) (cycle %lld pc 0x%x)\n", + vector->vector, !!avr->sreg[S_I], avr_regbit_get(avr, vector->enable), + (long long int)avr->cycle, avr->pc); + + return 0; + } + + avr_raise_irq(vector->irq + AVR_INT_IRQ_PENDING, 1); + avr_raise_irq(avr->interrupts.irq + AVR_INT_IRQ_PENDING, vector->vector); + + // If the interrupt is enabled, attempt to wake the core + if (avr_regbit_get(avr, vector->enable)) { + // Mark the interrupt as pending + vector->pending = 1; + + avr_int_table_p table = &avr->interrupts; + + avr_int_pending_write(&table->pending, vector); + + if (avr->sreg[S_I] && avr->interrupt_state == 0) + avr->interrupt_state = 1; + if (avr->state == cpu_Sleeping) { + if (vector->trace) + printf("IRQ%d Waking CPU due to interrupt\n", + vector->vector); + avr->state = cpu_Running; // in case we were sleeping + } + } + // return 'raised' even if it was already pending + return 1; +} + +void +avr_clear_interrupt( + avr_t * avr, + avr_int_vector_t * vector) +{ + if (!vector) + return; + if (vector->trace) + printf("IRQ%d cleared\n", vector->vector); + vector->pending = 0; + + avr_raise_irq(vector->irq + AVR_INT_IRQ_PENDING, 0); + avr_raise_irq_float(avr->interrupts.irq + AVR_INT_IRQ_PENDING, + avr_has_pending_interrupts(avr) ? + avr_int_pending_read_at( + &avr->interrupts.pending, 0)->vector : 0, + avr_has_pending_interrupts(avr)); + + if (vector->raised.reg && !vector->raise_sticky) + avr_regbit_clear(avr, vector->raised); +} + +int +avr_clear_interrupt_if( + avr_t * avr, + avr_int_vector_t * vector, + uint8_t old) +{ + avr_raise_irq(avr->interrupts.irq + AVR_INT_IRQ_PENDING, + avr_has_pending_interrupts(avr)); + if (avr_regbit_get(avr, vector->raised)) { + avr_clear_interrupt(avr, vector); + return 1; + } + avr_regbit_setto(avr, vector->raised, old); + return 0; +} + +avr_irq_t * +avr_get_interrupt_irq( + avr_t * avr, + uint8_t v) +{ + avr_int_table_p table = &avr->interrupts; + if (v == AVR_INT_ANY) + return table->irq; + for (int i = 0; i < table->vector_count; i++) + if (table->vector[i]->vector == v) + return table->vector[i]->irq; + return NULL; +} + +/* this is called upon RETI. */ +void +avr_interrupt_reti( + struct avr_t * avr) +{ + avr_int_table_p table = &avr->interrupts; + if (table->running_ptr) { + avr_int_vector_t * vector = table->running[--table->running_ptr]; + avr_raise_irq(vector->irq + AVR_INT_IRQ_RUNNING, 0); + } + avr_raise_irq(table->irq + AVR_INT_IRQ_RUNNING, + table->running_ptr > 0 ? + table->running[table->running_ptr-1]->vector : 0); +} + +/* + * check whether interrupts are pending. If so, check if the interrupt "latency" is reached, + * and if so triggers the handlers and jump to the vector. + */ +void +avr_service_interrupts( + avr_t * avr) +{ + if (!avr->sreg[S_I] || !avr->interrupt_state) + return; + + if (avr->interrupt_state < 0) { + avr->interrupt_state++; + if (avr->interrupt_state == 0) + avr->interrupt_state = avr_has_pending_interrupts(avr); + return; + } + + avr_int_table_p table = &avr->interrupts; + + // how many are pending... + int cnt = avr_int_pending_get_read_size(&table->pending); + // locate the highest priority one + int min = 0xff; + int mini = 0; + for (int ii = 0; ii < cnt; ii++) { + avr_int_vector_t * v = avr_int_pending_read_at(&table->pending, ii); + if (v->vector < min) { + min = v->vector; + mini = ii; + } + } + avr_int_vector_t * vector = avr_int_pending_read_at(&table->pending, mini); + + // it's possible that the vector being serviced is not at the front of the fifo, because we process interrupts based + // on vector priority rather than position in the fifo. if this is the case, we need to manually swap the vector + // being serviced with the vector at the front of the fifo so that the vector at the front of the fifo can be + // serviced in a following iteration. + avr_int_vector_p fifo_front = avr_int_pending_read(&table->pending); + if (fifo_front->vector != vector->vector) { + // the read into fifo_front above has incremented pending.read, so now mini points 1 beyond the desired + // destination for the swap. + table->pending.buffer[(table->pending.read + mini - 1) % avr_int_pending_fifo_size] = fifo_front; + } + + // if that single interrupt is masked, ignore it and continue + // could also have been disabled, or cleared + if (!avr_regbit_get(avr, vector->enable) || !vector->pending) { + vector->pending = 0; + avr->interrupt_state = avr_has_pending_interrupts(avr); + } else { + if (vector->trace) + printf("IRQ%d calling\n", vector->vector); + _avr_push_addr(avr, avr->pc); + avr_sreg_set(avr, S_I, 0); + avr->pc = vector->vector * avr->vector_size; + + avr_raise_irq(vector->irq + AVR_INT_IRQ_RUNNING, 1); + avr_raise_irq(table->irq + AVR_INT_IRQ_RUNNING, vector->vector); + if (table->running_ptr == ARRAY_SIZE(table->running)) { + AVR_LOG(avr, LOG_ERROR, "%s run out of nested stack!", __func__); + } else { + table->running[table->running_ptr++] = vector; + } + avr_clear_interrupt(avr, vector); + } +} + diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_interrupts.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_interrupts.h new file mode 100644 index 0000000..bebf614 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_interrupts.h @@ -0,0 +1,134 @@ +/* + sim_interrupts.h + + Copyright 2008-2012 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __SIM_INTERRUPTS_H__ +#define __SIM_INTERRUPTS_H__ + +#include "sim_avr_types.h" +#include "sim_irq.h" +#include "fifo_declare.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + AVR_INT_IRQ_PENDING = 0, + AVR_INT_IRQ_RUNNING, + AVR_INT_IRQ_COUNT, + AVR_INT_ANY = 0xff, // for avr_get_interrupt_irq() +}; +// interrupt vector for the IO modules +typedef struct avr_int_vector_t { + uint8_t vector; // vector number, zero (reset) is reserved + avr_regbit_t enable; // IO register index for the "interrupt enable" flag for this vector + avr_regbit_t raised; // IO register index for the register where the "raised" flag is (optional) + + uint8_t mask; // Mask for PCINTs. this is needed for chips like the 2560 where PCINT do not align with IRQs + int8_t shift; // PCINT8 = E0, PCINT9-15 are on J0-J6. Shift shifts down (<0) or up (>0) for alignment with IRQ#. + + // 'pending' IRQ, and 'running' status as signaled here + avr_irq_t irq[AVR_INT_IRQ_COUNT]; + uint8_t pending : 1, // 1 while scheduled in the fifo + trace : 1, // only for debug of a vector + raise_sticky : 1; // 1 if the interrupt flag (= the raised regbit) is not cleared + // by the hardware when executing the interrupt routine (see TWINT) +} avr_int_vector_t, *avr_int_vector_p; + +// Size needs to be >= max number of vectors, and a power of two +DECLARE_FIFO(avr_int_vector_p, avr_int_pending, 64); + +// interrupt vectors, and their enable/clear registers +typedef struct avr_int_table_t { + avr_int_vector_t * vector[64]; + uint8_t vector_count; + avr_int_pending_t pending; + uint8_t running_ptr; + avr_int_vector_t *running[64]; // stack of nested interrupts + // global status for pending + running in interrupt context + avr_irq_t irq[AVR_INT_IRQ_COUNT]; +} avr_int_table_t, *avr_int_table_p; + +/* + * Interrupt Helper Functions + */ +// register an interrupt vector. It's only needed if you want to use the "r_raised" flags +void +avr_register_vector( + struct avr_t *avr, + avr_int_vector_t * vector); +// raise an interrupt (if enabled). The interrupt is latched and will be called later +// return non-zero if the interrupt was raised and is now pending +int +avr_raise_interrupt( + struct avr_t * avr, + avr_int_vector_t * vector); +// return non-zero if the AVR core has any pending interrupts +int +avr_has_pending_interrupts( + struct avr_t * avr); +// return nonzero if a specific interrupt vector is pending +int +avr_is_interrupt_pending( + struct avr_t * avr, + avr_int_vector_t * vector); +// clear the "pending" status of an interrupt +void +avr_clear_interrupt( + struct avr_t * avr, + avr_int_vector_t * vector); +// called by the core at each cycle to check whether an interrupt is pending +void +avr_service_interrupts( + struct avr_t * avr); +// called by the core when RETI opcode is ran +void +avr_interrupt_reti( + struct avr_t * avr); +// clear the interrupt (inc pending) if "raised" flag is 1 +int +avr_clear_interrupt_if( + struct avr_t * avr, + avr_int_vector_t * vector, + uint8_t old); + +// return the IRQ that is raised when the vector is enabled and called/cleared +// this allows tracing of pending interrupts +avr_irq_t * +avr_get_interrupt_irq( + struct avr_t * avr, + uint8_t v); + +// Initializes the interrupt table +void +avr_interrupt_init( + struct avr_t * avr ); + +// reset the interrupt table and the fifo +void +avr_interrupt_reset( + struct avr_t * avr ); + +#ifdef __cplusplus +}; +#endif + +#endif /* __SIM_INTERRUPTS_H__ */ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_io.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_io.c new file mode 100644 index 0000000..548f030 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_io.c @@ -0,0 +1,298 @@ +/* + sim_io.c + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <stdint.h> +#include "sim_io.h" + +int +avr_ioctl( + avr_t *avr, + uint32_t ctl, + void * io_param) +{ + avr_io_t * port = avr->io_port; + int res = -1; + while (port && res == -1) { + if (port->ioctl) + res = port->ioctl(port, ctl, io_param); + port = port->next; + } + return res; +} + +void +avr_register_io( + avr_t *avr, + avr_io_t * io) +{ + io->next = avr->io_port; + io->avr = avr; + avr->io_port = io; +} + +void +avr_register_io_read( + avr_t *avr, + avr_io_addr_t addr, + avr_io_read_t readp, + void * param) +{ + avr_io_addr_t a = AVR_DATA_TO_IO(addr); + if (avr->io[a].r.param || avr->io[a].r.c) { + if (avr->io[a].r.param != param || avr->io[a].r.c != readp) { + AVR_LOG(avr, LOG_ERROR, + "IO: %s(): Already registered, refusing to override.\n", + __func__); + AVR_LOG(avr, LOG_ERROR, + "IO: %s(%04x : %p/%p): %p/%p\n", + __func__, a, + avr->io[a].r.c, avr->io[a].r.param, readp, param); + abort(); + } + } + avr->io[a].r.param = param; + avr->io[a].r.c = readp; +} + +static void +_avr_io_mux_write( + avr_t * avr, + avr_io_addr_t addr, + uint8_t v, + void * param) +{ + int io = (intptr_t)param; + for (int i = 0; i < avr->io_shared_io[io].used; i++) { + avr_io_write_t c = avr->io_shared_io[io].io[i].c; + if (c) + c(avr, addr, v, avr->io_shared_io[io].io[i].param); + } +} + +void +avr_register_io_write( + avr_t *avr, + avr_io_addr_t addr, + avr_io_write_t writep, + void * param) +{ + avr_io_addr_t a = AVR_DATA_TO_IO(addr); + + if (a >= MAX_IOs) { + AVR_LOG(avr, LOG_ERROR, + "IO: %s(): IO address 0x%04x out of range (max 0x%04x).\n", + __func__, a, MAX_IOs); + abort(); + } + /* + * Verifying that some other piece of code is not installed to watch write + * on this address. If there is, this code installs a "dispatcher" callback + * instead to handle multiple clients, otherwise, it continues as usual + */ + if (avr->io[a].w.param || avr->io[a].w.c) { + if (avr->io[a].w.param != param || avr->io[a].w.c != writep) { + // if the muxer not already installed, allocate a new slot + if (avr->io[a].w.c != _avr_io_mux_write) { + int no = avr->io_shared_io_count++; + if (avr->io_shared_io_count > ARRAY_SIZE(avr->io_shared_io)) { + AVR_LOG(avr, LOG_ERROR, + "IO: %s(): Too many shared IO registers.\n", __func__); + abort(); + } + AVR_LOG(avr, LOG_TRACE, + "IO: %s(%04x): Installing muxer on register.\n", + __func__, addr); + avr->io_shared_io[no].used = 1; + avr->io_shared_io[no].io[0].param = avr->io[a].w.param; + avr->io_shared_io[no].io[0].c = avr->io[a].w.c; + avr->io[a].w.param = (void*)(intptr_t)no; + avr->io[a].w.c = _avr_io_mux_write; + } + int no = (intptr_t)avr->io[a].w.param; + int d = avr->io_shared_io[no].used++; + if (avr->io_shared_io[no].used > ARRAY_SIZE(avr->io_shared_io[0].io)) { + AVR_LOG(avr, LOG_ERROR, + "IO: %s(): Too many callbacks on %04x.\n", + __func__, addr); + abort(); + } + avr->io_shared_io[no].io[d].param = param; + avr->io_shared_io[no].io[d].c = writep; + return; + } + } + + avr->io[a].w.param = param; + avr->io[a].w.c = writep; +} + +avr_irq_t * +avr_io_getirq( + avr_t * avr, + uint32_t ctl, + int index) +{ + avr_io_t * port = avr->io_port; + while (port) { + if (port->irq && port->irq_ioctl_get == ctl && port->irq_count > index) + return port->irq + index; + port = port->next; + } + return NULL; +} + +avr_irq_t * +avr_iomem_getirq( + avr_t * avr, + avr_io_addr_t addr, + const char * name, + int index) +{ + if (index > 8) + return NULL; + avr_io_addr_t a = AVR_DATA_TO_IO(addr); + if (avr->io[a].irq == NULL) { + /* + * Prepare an array of names for the io IRQs. Ideally we'd love to have + * a proper name for these, but it's not possible at this time. + */ + char names[9 * 20]; + char * d = names; + const char * namep[9]; + for (int ni = 0; ni < 9; ni++) { + if (ni < 8) + sprintf(d, "=avr.io.%04x.%d", addr, ni); + else + sprintf(d, "8=avr.io.%04x.all", addr); + namep[ni] = d; + d += strlen(d) + 1; + } + avr->io[a].irq = avr_alloc_irq(&avr->irq_pool, 0, 9, namep); + // mark the pin ones as filtered, so they only are raised when changing + for (int i = 0; i < 8; i++) + avr->io[a].irq[i].flags |= IRQ_FLAG_FILTERED; + } + // if given a name, replace the default one... + if (name) { + int l = strlen(name); + char n[l + 10]; + sprintf(n, "avr.io.%s", name); + free((void*)avr->io[a].irq[index].name); + avr->io[a].irq[index].name = strdup(n); + } + return avr->io[a].irq + index; +} + +avr_irq_t * +avr_io_setirqs( + avr_io_t * io, + uint32_t ctl, + int count, + avr_irq_t * irqs ) +{ + // allocate this module's IRQ + io->irq_count = count; + + if (!irqs) { + const char ** irq_names = NULL; + + if (io->irq_names) { + irq_names = malloc(count * sizeof(char*)); + memset(irq_names, 0, count * sizeof(char*)); + char buf[64]; + for (int i = 0; i < count; i++) { + /* + * this bit takes the io module 'kind' ("port") + * the IRQ name ("=0") and the last character of the ioctl ('p','o','r','A') + * to create a full name "=porta.0" + */ + char * dst = buf; + // copy the 'flags' of the name out + const char * kind = io->irq_names[i]; + while (isdigit(*kind)) + *dst++ = *kind++; + while (!isalpha(*kind)) + *dst++ = *kind++; + // add avr name +// strcpy(dst, io->avr->mmcu); + strcpy(dst, "avr"); + dst += strlen(dst); + *dst ++ = '.'; + // add module 'kind' + strcpy(dst, io->kind); + dst += strlen(dst); + // add port name, if any + if ((ctl & 0xff) > ' ') + *dst ++ = tolower(ctl & 0xff); + *dst ++ = '.'; + // add the rest of the irq name + strcpy(dst, kind); + dst += strlen(dst); + *dst = 0; + +// printf("%s\n", buf); + irq_names[i] = strdup(buf); + } + } + irqs = avr_alloc_irq(&io->avr->irq_pool, 0, + count, irq_names); + if (irq_names) { + for (int i = 0; i < count; i++) + free((char*)irq_names[i]); + free((char*)irq_names); + } + } + + io->irq = irqs; + io->irq_ioctl_get = ctl; + return io->irq; +} + +static void +avr_deallocate_io( + avr_io_t * io) +{ + if (io->dealloc) + io->dealloc(io); + avr_free_irq(io->irq, io->irq_count); + io->irq_count = 0; + io->irq_ioctl_get = 0; + io->avr = NULL; + io->next = NULL; +} + +void +avr_deallocate_ios( + avr_t * avr) +{ + avr_io_t * port = avr->io_port; + while (port) { + avr_io_t * next = port->next; + avr_deallocate_io(port); + port = next; + } + avr->io_port = NULL; +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_io.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_io.h new file mode 100644 index 0000000..cfd2fdb --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_io.h @@ -0,0 +1,132 @@ +/* + sim_io.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __SIM_IO_H__ +#define __SIM_IO_H__ + +#include "sim_avr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * used by the ioports to implement their own features + * see avr_eeprom.* for an example, and avr_ioctl(). + */ +#define AVR_IOCTL_DEF(_a,_b,_c,_d) \ + (((_a) << 24)|((_b) << 16)|((_c) << 8)|((_d))) + +/* + * IO module base struct + * Modules uses that as their first member in their own struct + */ +typedef struct avr_io_t { + struct avr_io_t * next; + avr_t * avr; // avr we are attached to + const char * kind; // pretty name, for debug + + const char ** irq_names; // IRQ names + + uint32_t irq_ioctl_get; // used to get irqs from this module + int irq_count; // number of (optional) irqs + struct avr_irq_t * irq; // optional external IRQs + // called at reset time + void (*reset)(struct avr_io_t *io); + // called externally. allow access to io modules and so on + int (*ioctl)(struct avr_io_t *io, uint32_t ctl, void *io_param); + + // optional, a function to free up allocated system resources + void (*dealloc)(struct avr_io_t *io); +} avr_io_t; + +/* + * IO modules helper functions + */ + +// registers an IO module, so it's run(), reset() etc are called +// this is called by the AVR core init functions, you /could/ register an external +// one after instantiation, for whatever purpose... +void +avr_register_io( + avr_t *avr, + avr_io_t * io); +// Sets an IO module "official" IRQs and the ioctl used to get to them. if 'irqs' is NULL, +// 'count' will be allocated +avr_irq_t * +avr_io_setirqs( + avr_io_t * io, + uint32_t ctl, + int count, + avr_irq_t * irqs ); + +// register a callback for when IO register "addr" is read +void +avr_register_io_read( + avr_t *avr, + avr_io_addr_t addr, + avr_io_read_t read, + void * param); +// register a callback for when the IO register is written. callback has to set the memory itself +void +avr_register_io_write( + avr_t *avr, + avr_io_addr_t addr, + avr_io_write_t write, + void * param); +// call every IO modules until one responds to this +int +avr_ioctl( + avr_t *avr, + uint32_t ctl, + void * io_param); +// get the specific irq for a module, check AVR_IOCTL_IOPORT_GETIRQ for example +struct avr_irq_t * +avr_io_getirq( + avr_t * avr, + uint32_t ctl, + int index); + +// get the IRQ for an absolute IO address +// this allows any code to hook an IRQ in any io address, for example +// tracing changes of values into a register +// Note that the values do not "magically" change, they change only +// when the AVR code attempt to read and write at that address +// +// the "index" is a bit number, or ALL bits if index == 8 +#define AVR_IOMEM_IRQ_ALL 8 +avr_irq_t * +avr_iomem_getirq( + avr_t * avr, + avr_io_addr_t addr, + const char * name /* Optional, if NULL, "ioXXXX" will be used */ , + int index); + +// Terminates all IOs and remove from them from the io chain +void +avr_deallocate_ios( + avr_t *avr); + +#ifdef __cplusplus +}; +#endif + +#endif /* __SIM_IO_H__ */ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_irq.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_irq.c new file mode 100644 index 0000000..6d175cf --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_irq.c @@ -0,0 +1,294 @@ +/* + sim_irq.c + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "sim_irq.h" + +// internal structure for a hook, never seen by the notify procs +typedef struct avr_irq_hook_t { + struct avr_irq_hook_t * next; + int busy; // prevent reentrance of callbacks + + struct avr_irq_t * chain; // raise the IRQ on this too - optional if "notify" is on + avr_irq_notify_t notify; // called when IRQ is raised - optional if "chain" is on + void * param; // "notify" parameter +} avr_irq_hook_t; + +static void +_avr_irq_pool_add( + avr_irq_pool_t * pool, + avr_irq_t * irq) +{ + int insert = 0; + /* lookup a slot */ + for (; insert < pool->count && pool->irq[insert]; insert++) + ; + if (insert == pool->count) { + if ((pool->count & 0xf) == 0) { + pool->irq = (avr_irq_t**)realloc(pool->irq, + (pool->count + 16) * sizeof(avr_irq_t *)); + } + pool->count++; + } + pool->irq[insert] = irq; + irq->pool = pool; +} + +static void +_avr_irq_pool_remove( + avr_irq_pool_t * pool, + avr_irq_t * irq) +{ + for (int i = 0; i < pool->count; i++) + if (pool->irq[i] == irq) { + pool->irq[i] = 0; + return; + } +} + +void +avr_init_irq( + avr_irq_pool_t * pool, + avr_irq_t * irq, + uint32_t base, + uint32_t count, + const char ** names /* optional */) +{ + memset(irq, 0, sizeof(avr_irq_t) * count); + + for (int i = 0; i < count; i++) { + irq[i].irq = base + i; + irq[i].flags = IRQ_FLAG_INIT; + if (pool) + _avr_irq_pool_add(pool, &irq[i]); + if (names && names[i]) + irq[i].name = strdup(names[i]); + else { + printf("WARNING %s() with NULL name for irq %d.\n", __func__, irq[i].irq); + } + } +} + +avr_irq_t * +avr_alloc_irq( + avr_irq_pool_t * pool, + uint32_t base, + uint32_t count, + const char ** names /* optional */) +{ + avr_irq_t * irq = (avr_irq_t*)malloc(sizeof(avr_irq_t) * count); + avr_init_irq(pool, irq, base, count, names); + for (int i = 0; i < count; i++) + irq[i].flags |= IRQ_FLAG_ALLOC; + return irq; +} + +static avr_irq_hook_t * +_avr_alloc_irq_hook( + avr_irq_t * irq) +{ + avr_irq_hook_t *hook = malloc(sizeof(avr_irq_hook_t)); + memset(hook, 0, sizeof(avr_irq_hook_t)); + hook->next = irq->hook; + irq->hook = hook; + return hook; +} + +void +avr_free_irq( + avr_irq_t * irq, + uint32_t count) +{ + if (!irq || !count) + return; + for (int i = 0; i < count; i++) { + avr_irq_t * iq = irq + i; + if (iq->pool) + _avr_irq_pool_remove(iq->pool, iq); + if (iq->name) + free((char*)iq->name); + iq->name = NULL; + // purge hooks + avr_irq_hook_t *hook = iq->hook; + while (hook) { + avr_irq_hook_t * next = hook->next; + free(hook); + hook = next; + } + iq->hook = NULL; + } + // if that irq list was allocated by us, free it + if (irq->flags & IRQ_FLAG_ALLOC) + free(irq); +} + +void +avr_irq_register_notify( + avr_irq_t * irq, + avr_irq_notify_t notify, + void * param) +{ + if (!irq || !notify) + return; + + avr_irq_hook_t *hook = irq->hook; + while (hook) { + if (hook->notify == notify && hook->param == param) + return; // already there + hook = hook->next; + } + hook = _avr_alloc_irq_hook(irq); + hook->notify = notify; + hook->param = param; +} + +void +avr_irq_unregister_notify( + avr_irq_t * irq, + avr_irq_notify_t notify, + void * param) +{ + avr_irq_hook_t *hook, *prev; + if (!irq || !notify) + return; + + hook = irq->hook; + prev = NULL; + while (hook) { + if (hook->notify == notify && hook->param == param) { + if ( prev ) + prev->next = hook->next; + else + irq->hook = hook->next; + free(hook); + return; + } + prev = hook; + hook = hook->next; + } +} + +void +avr_raise_irq_float( + avr_irq_t * irq, + uint32_t value, + int floating) +{ + if (!irq) + return ; + uint32_t output = (irq->flags & IRQ_FLAG_NOT) ? !value : value; + // if value is the same but it's the first time, raise it anyway + if (irq->value == output && + (irq->flags & IRQ_FLAG_FILTERED) && !(irq->flags & IRQ_FLAG_INIT)) + return; + irq->flags &= ~(IRQ_FLAG_INIT | IRQ_FLAG_FLOATING); + if (floating) + irq->flags |= IRQ_FLAG_FLOATING; + avr_irq_hook_t *hook = irq->hook; + while (hook) { + avr_irq_hook_t * next = hook->next; + // prevents reentrance / endless calling loops + if (hook->busy == 0) { + hook->busy++; + if (hook->notify) + hook->notify(irq, output, hook->param); + if (hook->chain) + avr_raise_irq_float(hook->chain, output, floating); + hook->busy--; + } + hook = next; + } + // the value is set after the callbacks are called, so the callbacks + // can themselves compare for old/new values between their parameter + // they are passed (new value) and the previous irq->value + irq->value = output; +} + +void +avr_raise_irq( + avr_irq_t * irq, + uint32_t value) +{ + avr_raise_irq_float(irq, value, !!(irq->flags & IRQ_FLAG_FLOATING)); +} + +void +avr_connect_irq( + avr_irq_t * src, + avr_irq_t * dst) +{ + if (!src || !dst || src == dst) { + fprintf(stderr, "error: %s invalid irq %p/%p", __FUNCTION__, src, dst); + return; + } + avr_irq_hook_t *hook = src->hook; + while (hook) { + if (hook->chain == dst) + return; // already there + hook = hook->next; + } + hook = _avr_alloc_irq_hook(src); + hook->chain = dst; +} + +void +avr_unconnect_irq( + avr_irq_t * src, + avr_irq_t * dst) +{ + avr_irq_hook_t *hook, *prev; + + if (!src || !dst || src == dst) { + fprintf(stderr, "error: %s invalid irq %p/%p", __FUNCTION__, src, dst); + return; + } + hook = src->hook; + prev = NULL; + while (hook) { + if (hook->chain == dst) { + if ( prev ) + prev->next = hook->next; + else + src->hook = hook->next; + free(hook); + return; + } + prev = hook; + hook = hook->next; + } +} + +uint8_t +avr_irq_get_flags( + avr_irq_t * irq ) +{ + return irq->flags; +} + +void +avr_irq_set_flags( + avr_irq_t * irq, + uint8_t flags ) +{ + irq->flags = flags; +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_irq.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_irq.h new file mode 100644 index 0000000..b96fd47 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_irq.h @@ -0,0 +1,150 @@ +/* + sim_irq.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __SIM_IRQ_H__ +#define __SIM_IRQ_H__ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Internal IRQ system + * + * This subsystem allows any piece of code to "register" a hook to be called when an IRQ is + * raised. The IRQ definition is up to the module defining it, for example a IOPORT pin change + * might be an IRQ in which case any piece of code can be notified when a pin has changed state + * + * The notify hooks are chained, and duplicates are filtered out so you can't register a + * notify hook twice on one particular IRQ + * + * IRQ calling order is not defined, so don't rely on it. + * + * IRQ hook needs to be registered in reset() handlers, ie after all modules init() bits + * have been called, to prevent race condition of the initialization order. + */ +struct avr_irq_t; + +typedef void (*avr_irq_notify_t)( + struct avr_irq_t * irq, + uint32_t value, + void * param); + + +enum { + IRQ_FLAG_NOT = (1 << 0), //!< change polarity of the IRQ + IRQ_FLAG_FILTERED = (1 << 1), //!< do not "notify" if "value" is the same as previous raise + IRQ_FLAG_ALLOC = (1 << 2), //!< this irq structure was malloced via avr_alloc_irq + IRQ_FLAG_INIT = (1 << 3), //!< this irq hasn't been used yet + IRQ_FLAG_FLOATING = (1 << 4), //!< this 'pin'/signal is floating + IRQ_FLAG_USER = (1 << 5), //!< Can be used by irq users +}; + +/* + * IRQ Pool structure + */ +typedef struct avr_irq_pool_t { + int count; //!< number of irqs living in the pool + struct avr_irq_t ** irq; //!< irqs belonging in this pool +} avr_irq_pool_t; + +/*! + * Public IRQ structure + */ +typedef struct avr_irq_t { + struct avr_irq_pool_t * pool; + const char * name; + uint32_t irq; //!< any value the user needs + uint32_t value; //!< current value + uint8_t flags; //!< IRQ_* flags + struct avr_irq_hook_t * hook; //!< list of hooks to be notified +} avr_irq_t; + +//! allocates 'count' IRQs, initializes their "irq" starting from 'base' and increment +avr_irq_t * +avr_alloc_irq( + avr_irq_pool_t * pool, + uint32_t base, + uint32_t count, + const char ** names /* optional */); +void +avr_free_irq( + avr_irq_t * irq, + uint32_t count); + +//! init 'count' IRQs, initializes their "irq" starting from 'base' and increment +void +avr_init_irq( + avr_irq_pool_t * pool, + avr_irq_t * irq, + uint32_t base, + uint32_t count, + const char ** names /* optional */); +//! Returns the current IRQ flags +uint8_t +avr_irq_get_flags( + avr_irq_t * irq ); +//! Sets this irq's flags +void +avr_irq_set_flags( + avr_irq_t * irq, + uint8_t flags ); +//! 'raise' an IRQ. Ie call their 'hooks', and raise any chained IRQs, and set the new 'value' +void +avr_raise_irq( + avr_irq_t * irq, + uint32_t value); +//! Same as avr_raise_irq(), but also allow setting the float status +void +avr_raise_irq_float( + avr_irq_t * irq, + uint32_t value, + int floating); +//! this connects a "source" IRQ to a "destination" IRQ +void +avr_connect_irq( + avr_irq_t * src, + avr_irq_t * dst); +void +avr_unconnect_irq( + avr_irq_t * src, + avr_irq_t * dst); + +//! register a notification 'hook' for 'irq' -- 'param' is anything that your want passed back as argument +void +avr_irq_register_notify( + avr_irq_t * irq, + avr_irq_notify_t notify, + void * param); + +void +avr_irq_unregister_notify( + avr_irq_t * irq, + avr_irq_notify_t notify, + void * param); + +#ifdef __cplusplus +}; +#endif + +#endif /* __SIM_IRQ_H__ */ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_network.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_network.h new file mode 100644 index 0000000..da4600a --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_network.h @@ -0,0 +1,89 @@ +/* + sim_network.h + + Copyright 2012 Stephan Veigl <veigl@gmx.net> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __SIM_NETWORK_H__ +#define __SIM_NETWORK_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __MINGW32__ + +// Windows with MinGW + +#include <winsock2.h> +#include <windows.h> +#include <ws2tcpip.h> + +#define send(sockfd, buf, len, flags) \ + (ssize_t)send( (sockfd), (const char *)(buf), (len), (flags)) +#define setsockopt(sockfd, level, optname, optval, optlen) \ + setsockopt( (sockfd), (level), (optname), (void *)(optval), (optlen)) +#define recv(sockfd, buf, len, flags) \ + (ssize_t)recv( (sockfd), (char *)(buf), (len), (flags)) +#define sleep(x) Sleep((x)*1000) + +static inline int network_init(void) +{ + // Windows requires WinSock to be init before use + WSADATA wsaData; + if ( WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) ) + return -1; + + return 0; +} + +static inline void network_release(void) +{ + // close WinSock + WSACleanup(); +} + +#else + +// native Linux + +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <arpa/inet.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <poll.h> + +static inline int network_init(void) +{ + // nothing to do + return 0; +} + +static inline void network_release(void) +{ + // nothing to do +} + +#endif + +#ifdef __cplusplus +}; +#endif + +#endif /*__SIM_NETWORK_H__*/ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_regbit.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_regbit.h new file mode 100644 index 0000000..862f490 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_regbit.h @@ -0,0 +1,199 @@ +/* + sim_regbit.h + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __SIM_REGBIT_H__ +#define __SIM_REGBIT_H__ + +#include "sim_avr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ARRAY_SIZE(_aa) (sizeof(_aa) / sizeof((_aa)[0])) + + +/* + * These accessors are inlined and are used to perform the operations on + * avr_regbit_t definitions. This is the "official" way to access bits into registers + * The small footprint costs brings much better versatility for functions/bits that are + * not always defined in the same place on real AVR cores + */ +/* + * set/get/clear io register bits in one operation + */ +static inline uint8_t +avr_regbit_set( + avr_t * avr, + avr_regbit_t rb) +{ + uint16_t a = rb.reg; + uint8_t m; + + if (!a) + return 0; + m = (uint8_t)(rb.mask << rb.bit); + avr_core_watch_write(avr, a, (uint8_t)(avr->data[a] | m)); + return (uint8_t)((avr->data[a] >> rb.bit) & rb.mask); +} + +static inline uint8_t +avr_regbit_setto( + avr_t * avr, + avr_regbit_t rb, + uint8_t v) +{ + uint16_t a = rb.reg; + uint8_t m; + + if (!a) + return 0; + m = (uint8_t)(rb.mask << rb.bit); + avr_core_watch_write(avr, a, + (uint8_t)((avr->data[a] & ~(m)) | + ((v << rb.bit) & m))); + return (uint8_t)((avr->data[a] >> rb.bit) & rb.mask); +} + +/* + * Set the 'raw' bits, if 'v' is the unshifted value of the bits + */ +static inline uint8_t +avr_regbit_setto_raw( + avr_t * avr, + avr_regbit_t rb, + uint8_t v) +{ + uint16_t a = rb.reg; + uint8_t m; + + if (!a) + return 0; + m = (uint8_t)(rb.mask << rb.bit); + avr_core_watch_write(avr, a, + (uint8_t)((avr->data[a] & ~(m)) | ((v) & m))); + return (uint8_t)((avr->data[a]) & (rb.mask << rb.bit)); +} + +static inline uint8_t +avr_regbit_get( + avr_t * avr, + avr_regbit_t rb) +{ + uint16_t a = rb.reg; + if (!a) + return 0; + //uint8_t m = rb.mask << rb.bit; + return (uint8_t)((avr->data[a] >> rb.bit) & rb.mask); +} + +/* + * Using regbit from value eliminates some of the + * set to test then clear register operations. + * makes cheking register bits before setting easier. + */ +static inline uint8_t +avr_regbit_from_value( + avr_t * avr __attribute__((unused)), + avr_regbit_t rb, + uint8_t value) +{ + uint16_t a = rb.reg; + if (!a) + return 0; + return (uint8_t)((value >> rb.bit) & rb.mask); +} + +/* + * Return the bit(s) 'in position' instead of zero based + */ +static inline uint8_t +avr_regbit_get_raw( + avr_t * avr, + avr_regbit_t rb) +{ + uint16_t a = rb.reg; + if (!a) + return 0; + //uint8_t m = rb.mask << rb.bit; + return (uint8_t)((avr->data[a]) & (rb.mask << rb.bit)); +} + +static inline uint8_t +avr_regbit_clear( + avr_t * avr, + avr_regbit_t rb) +{ + uint16_t a = rb.reg; + if (!a) + return 0; + uint8_t m = (uint8_t)(rb.mask << rb.bit); + avr_core_watch_write(avr, a, (uint8_t)(avr->data[a] & ~m)); + return avr->data[a]; +} + + +/* + * This reads the bits for an array of avr_regbit_t, make up a "byte" with them. + * This allows reading bits like CS0, CS1, CS2 etc even if they are not in the same + * physical IO register. + */ +static inline uint8_t +avr_regbit_get_array( + avr_t * avr, + avr_regbit_t *rb, + int count) +{ + uint8_t res = 0; + int i; + + for (i = 0; i < count; i++, rb++) if (rb->reg) { + uint16_t a = rb->reg; + res |= (uint8_t)(((avr->data[a] >> rb->bit) & rb->mask) << i); + } + return res; +} + +/* + * Does the reverse of avr_regbit_get_array + */ +static inline void +avr_regbit_set_array_from_value( + avr_t * avr, + avr_regbit_t * rb, + uint8_t count, + uint8_t value) +{ + int i; + for (i = 0; i < count; i++, rb++) if (rb->reg) { + uint8_t rbv = (value >> (count - i)) & 1; + avr_regbit_setto(avr, *rb, rbv); + } +} + +#define AVR_IO_REGBIT(_io, _bit) { . reg = (_io), .bit = (_bit), .mask = 1 } +#define AVR_IO_REGBITS(_io, _bit, _mask) { . reg = (_io), .bit = (_bit), .mask = (_mask) } + +#ifdef __cplusplus +}; +#endif + +#endif /* __SIM_REGBIT_H__ */ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_time.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_time.h new file mode 100644 index 0000000..4b81f43 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_time.h @@ -0,0 +1,64 @@ +/* + sim_time.h + + Copyright 2008-2012 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef __SIM_TIME_H___ +#define __SIM_TIME_H___ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sim_avr.h" + +// converts a number of usec to a number of machine cycles, at current speed +static inline avr_cycle_count_t +avr_usec_to_cycles(struct avr_t * avr, uint32_t usec) +{ + return avr->frequency * (avr_cycle_count_t)usec / 1000000; +} + +// converts back a number of cycles to usecs (for usleep) +static inline uint32_t +avr_cycles_to_usec(struct avr_t * avr, avr_cycle_count_t cycles) +{ + return 1000000L * cycles / avr->frequency; +} + +// converts back a number of cycles to nsecs +static inline uint64_t +avr_cycles_to_nsec(struct avr_t * avr, avr_cycle_count_t cycles) +{ + return (uint64_t)1E6 * (uint64_t)cycles / (avr->frequency/1000); +} + +// converts a number of hz (to megahertz etc) to a number of cycle +static inline avr_cycle_count_t +avr_hz_to_cycles(avr_t * avr, uint32_t hz) +{ + return avr->frequency / hz; +} + +#ifdef __cplusplus +}; +#endif + +#endif /* __SIM_TIME_H___ */ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_utils.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_utils.c new file mode 100644 index 0000000..eeb4986 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_utils.c @@ -0,0 +1,68 @@ +/* + sim_utils.c + + Implements a Value Change Dump file outout to generate + traces & curves and display them in gtkwave. + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include <stdlib.h> + +#include "sim_utils.h" + +static argv_p +argv_realloc( + argv_p argv, + uint32_t size ) +{ + argv = realloc(argv, + sizeof(argv_t) + (size * sizeof(argv->argv[0]))); + argv->size = size; + return argv; +} + +argv_p +argv_parse( + argv_p argv, + char * line ) +{ + if (!argv) + argv = argv_realloc(argv, 8); + argv->argc = 0; + + /* strip end of lines and trailing spaces */ + char *d = line + strlen(line); + while ((d - line) > 0 && *(--d) <= ' ') + *d = 0; + /* stop spaces + tabs */ + char *s = line; + while (*s && *s <= ' ') + s++; + argv->line = s; + char * a = NULL; + do { + if (argv->argc == argv->size) + argv = argv_realloc(argv, argv->size + 8); + if ((a = strsep(&s, " \t")) != NULL) + argv->argv[argv->argc++] = a; + } while (a); + argv->argv[argv->argc] = NULL; + return argv; +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_utils.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_utils.h new file mode 100644 index 0000000..44cb2c5 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_utils.h @@ -0,0 +1,51 @@ +/* + sim_utils.h + + Implements a Value Change Dump file outout to generate + traces & curves and display them in gtkwave. + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __SIM_UTILS_H__ +#define __SIM_UTILS_H__ + +#include <stdint.h> + +typedef struct argv_t { + uint32_t size, argc; + char * line; + char * argv[]; +} argv_t, *argv_p; + +/* + * Allocate a argv_t structure, split 'line' into words (destructively) + * and fills up argc, and argv fields with pointers to the individual + * words. The line is stripped of any \r\n as well + * You can pass an already allocated argv_t for it to be reused (and + * grown to fit). + * + * You are still responsible, as the caller, to (free) the resulting + * pointer, and the 'line' text, if appropriate, no duplication is made + */ +argv_p +argv_parse( + argv_p argv, + char * line ); + +#endif /* __SIM_UTILS_H__ */ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_vcd_file.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_vcd_file.c new file mode 100644 index 0000000..16e4d25 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_vcd_file.c @@ -0,0 +1,630 @@ +/* + sim_vcd_file.c + + Implements a Value Change Dump file outout to generate + traces & curves and display them in gtkwave. + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <inttypes.h> +#include <ctype.h> +#include <time.h> +#include "sim_vcd_file.h" +#include "sim_avr.h" +#include "sim_time.h" +#include "sim_utils.h" +#include "sim_core_config.h" + +DEFINE_FIFO(avr_vcd_log_t, avr_vcd_fifo); + +#define strdupa(__s) strcpy(alloca(strlen(__s)+1), __s) + +static void +_avr_vcd_notify( + struct avr_irq_t * irq, + uint32_t value, + void * param); + +int +avr_vcd_init( + struct avr_t * avr, + const char * filename, + avr_vcd_t * vcd, + uint32_t period) +{ + memset(vcd, 0, sizeof(avr_vcd_t)); + vcd->avr = avr; + vcd->filename = strdup(filename); + vcd->period = avr_usec_to_cycles(vcd->avr, period); + return 0; +} + +/* + * Parse a VCD 'timing' line. The lines are assumed to be: + * #<absolute timestamp>[\n][<value x/z/0/1><signal alias character>| + * b[x/z/0/1]?<space><signal alias character| + * r<real value><space><signal alias character]+ + * For example: + * #1234 1' 0$ + * Or: + * #1234 + * b1101x1 ' + * 0$ + * + * This function tries to handle this transparently, and pushes the + * signal/values into the FIFO for processing by the timer when + * convenient. + * NOTE: Add 'floating' support here. Also, FIX THE TIMING. + */ +static avr_cycle_count_t +avr_vcd_input_parse_line( + avr_vcd_t * vcd, + argv_p v ) +{ + uint64_t res = 0; + int vi = 0; + + if (v->argc == 0) + return res; + + if (v->argv[0][0] == '#') { + res = atoll(v->argv[0] + 1) * vcd->vcd_to_ns; + vcd->start = vcd->period; + vcd->period = res; + vi++; + } + for (int i = vi; i < v->argc; i++) { + char * a = v->argv[i]; + uint32_t val = 0; + int floating = 0; + char name = 0; + int sigindex; + + if (*a == 'b' || *a == 'B') { // Binary string + a++; + while (*a) { + if (*a == 'x' || *a == 'z') { + val <<= 1; + floating |= (floating << 1) | 1; + } else if (*a == '0' || *a == '1') { + val = (val << 1) | (*a - '0'); + floating <<= 1; + } else { + name = *a; + break; + } + a++; + } + } else if (*a == '0' || *a == '1' || *a == 'x' || *a == 'z') { + if (*a == 'x' || *a == 'z') + floating = 1; + else + val = *a++ - '0'; + if (*a && *a > ' ') + name = *a; + } else if (*a == 'r' || *a == 'R') { + val = (uint32_t)strtod(++a, NULL); + } + + if (!name && (i < v->argc - 1)) { + const char *n = v->argv[i+1]; + if (strlen(n) == 1) { + // we've got a name, it was not attached + name = *n; + i++; // skip that one + } + } + sigindex = -1; + if (name) { + for (int si = 0; + si < vcd->signal_count && + sigindex == -1; si++) { + if (vcd->signal[si].alias == name) + sigindex = si; + } + } + if (sigindex == -1) { + printf("Signal name '%c' value %x not found\n", + name? name : '?', val); + continue; + } + avr_vcd_log_t e = { + .when = vcd->period, + .sigindex = sigindex, + .floating = !!floating, + .value = val, + }; + // printf("%10u %d\n", e.when, e.value); + avr_vcd_fifo_write(&vcd->log, e); + } + return res; +} + +/* + * Read some signals from the file and fill the FIFO with it, we read + * a completely arbitrary amount of stuff to fill the FIFO reasonably well + */ +static int +avr_vcd_input_read( + avr_vcd_t * vcd ) +{ + char line[1024]; + + while (fgets(line, sizeof(line), vcd->input)) { + // printf("%s", line); + if (!line[0]) // technically can't happen, but make sure next line works + continue; + vcd->input_line = argv_parse(vcd->input_line, line); + avr_vcd_input_parse_line(vcd, vcd->input_line); + /* stop once the fifo is full enough */ + if (avr_vcd_fifo_get_read_size(&vcd->log) >= 128) + break; + } + return avr_vcd_fifo_isempty(&vcd->log); +} + +/* + * This is called when we need to change the state of one or more IRQ, + * so look in the FIFO to know 'our' stamp time, read as much as we can + * that is still on that same timestamp. + * When when the FIFO content has too far in the future, re-schedule the + * timer for that time and shoot off. + * Also try to top up the FIFO with new read stuff when it's drained + */ +static avr_cycle_count_t +_avr_vcd_input_timer( + struct avr_t * avr, + avr_cycle_count_t when, + void * param) +{ + avr_cycle_count_t next; + avr_vcd_t * vcd = param; + +again: + // get some more if needed + if (avr_vcd_fifo_get_read_size(&vcd->log) < (vcd->signal_count * 16)) + avr_vcd_input_read(vcd); + + if (avr_vcd_fifo_isempty(&vcd->log)) { + printf("%s DONE but why are we here?\n", __func__); + return 0; + } + + avr_vcd_log_t log = avr_vcd_fifo_read_at(&vcd->log, 0); + uint64_t stamp = log.when; + while (!avr_vcd_fifo_isempty(&vcd->log)) { + log = avr_vcd_fifo_read_at(&vcd->log, 0); + if (log.when != stamp) // leave those in the FIFO + break; + // we already have it + avr_vcd_fifo_read_offset(&vcd->log, 1); + avr_vcd_signal_p signal = &vcd->signal[log.sigindex]; + avr_raise_irq_float(&signal->irq, log.value, log.floating); + } + + if (avr_vcd_fifo_isempty(&vcd->log)) { + AVR_LOG(vcd->avr, LOG_TRACE, + "%s Finished reading, ending simavr\n", + vcd->filename); + avr->state = cpu_Done; + return 0; + } + log = avr_vcd_fifo_read_at(&vcd->log, 0); + + next = (log.when * avr->frequency) / (1000*1000*1000); + if (next <= when) + goto again; + return next; +} + +int +avr_vcd_init_input( + struct avr_t * avr, + const char * filename, // filename to read + avr_vcd_t * vcd ) // vcd struct to initialize +{ + memset(vcd, 0, sizeof(avr_vcd_t)); + vcd->avr = avr; + vcd->filename = strdup(filename); + + vcd->input = fopen(vcd->filename, "r"); + if (!vcd->input) { + perror(filename); + return -1; + } + char line[1024]; + argv_p v = NULL; + + while (fgets(line, sizeof(line), vcd->input)) { + if (!line[0]) // technically can't happen, but make sure next line works + continue; + v = argv_parse(v, line); + + // we are done reading headers, got our first timestamp + if (v->line[0] == '#') { + uint64_t when; + + vcd->start = 0; + avr_vcd_input_parse_line(vcd, v); + when = (vcd->period * vcd->avr->frequency) / + (1000*1000*1000); + avr_cycle_timer_register(vcd->avr, when, + _avr_vcd_input_timer, vcd); + break; + } + // ignore multiline stuff + if (v->line[0] != '$') + continue; + + const char * end = !strcmp(v->argv[v->argc - 1], "$end") ? + v->argv[v->argc - 1] : NULL; + const char *keyword = v->argv[0]; + + if (keyword == end) + keyword = NULL; + if (!keyword) + continue; + + if (!strcmp(keyword, "$timescale")) { + // sim_vcd header allows only integer factors of ns: 1ns, 2us, 3ms, 10s, ... + uint64_t cnt = 0; + char *si = v->argv[1]; + + vcd->vcd_to_ns = 1; + while (si && *si && isdigit(*si)) + cnt = (cnt * 10) + (*si++ - '0'); + while (si && *si == ' ') + si++; + if (si && !*si) + si = v->argv[2]; + if (!strcmp(si, "ns")) { + // no calculation here + vcd->vcd_to_ns = cnt; + } else if (!strcmp(si, "us")) { + cnt*=1000; + vcd->vcd_to_ns = cnt; + } else if (!strcmp(si, "ms")) { + cnt*=1000*1000; + vcd->vcd_to_ns = cnt; + } else if (!strcmp(si, "s")) { + cnt*=1000*1000*1000; + vcd->vcd_to_ns = cnt; + } + // printf("cnt %dus; unit %s\n", (int)cnt, si); + } else if (!strcmp(keyword, "$var")) { + const char *name = v->argv[4]; + + vcd->signal[vcd->signal_count].alias = v->argv[3][0]; + vcd->signal[vcd->signal_count].size = atoi(v->argv[2]); + strncpy(vcd->signal[vcd->signal_count].name, name, + sizeof(vcd->signal[0].name)); + + vcd->signal_count++; + } + } + // reuse this one + vcd->input_line = v; + + for (int i = 0; i < vcd->signal_count; i++) { + AVR_LOG(vcd->avr, LOG_TRACE, "%s %2d '%c' %s : size %d\n", + __func__, i, + vcd->signal[i].alias, vcd->signal[i].name, + vcd->signal[i].size); + /* format is <four-character ioctl>[_<IRQ index>] */ + if (strlen(vcd->signal[i].name) >= 4) { + char *dup = strdupa(vcd->signal[i].name); + char *ioctl = strsep(&dup, "_"); + int index = 0; + if (dup) + index = atoi(dup); + if (strlen(ioctl) == 4) { + uint32_t ioc = AVR_IOCTL_DEF( + ioctl[0], ioctl[1], ioctl[2], ioctl[3]); + avr_irq_t * irq = avr_io_getirq(vcd->avr, ioc, index); + if (irq) { + vcd->signal[i].irq.flags = IRQ_FLAG_INIT; + avr_connect_irq(&vcd->signal[i].irq, irq); + } else { + AVR_LOG(vcd->avr, LOG_WARNING, + "%s IRQ was not found\n", + vcd->signal[i].name); + } + continue; + } + AVR_LOG(vcd->avr, LOG_WARNING, + "%s is an invalid IRQ format\n", + vcd->signal[i].name); + } + } + return 0; +} + +void +avr_vcd_close( + avr_vcd_t * vcd) +{ + avr_vcd_stop(vcd); + + /* dispose of any link and hooks */ + for (int i = 0; i < vcd->signal_count; i++) { + avr_vcd_signal_t * s = &vcd->signal[i]; + + avr_free_irq(&s->irq, 1); + } + + if (vcd->filename) { + free(vcd->filename); + vcd->filename = NULL; + } +} + +static char * +_avr_vcd_get_float_signal_text( + avr_vcd_signal_t * s, + char * out) +{ + char * dst = out; + + if (s->size > 1) + *dst++ = 'b'; + + for (int i = s->size; i > 0; i--) + *dst++ = 'x'; + if (s->size > 1) + *dst++ = ' '; + *dst++ = s->alias; + *dst = 0; + return out; +} + +static char * +_avr_vcd_get_signal_text( + avr_vcd_signal_t * s, + char * out, + uint32_t value) +{ + char * dst = out; + + if (s->size > 1) + *dst++ = 'b'; + + for (int i = s->size; i > 0; i--) + *dst++ = value & (1 << (i-1)) ? '1' : '0'; + if (s->size > 1) + *dst++ = ' '; + *dst++ = s->alias; + *dst = 0; + return out; +} + +/* Write queued output to the VCD file. */ + +static void +avr_vcd_flush_log( + avr_vcd_t * vcd) +{ +#if AVR_VCD_MAX_SIGNALS > 32 + uint64_t seen = 0; +#else + uint32_t seen = 0; +#endif + uint64_t oldbase = 0; // make sure it's different + char out[48]; + + if (avr_vcd_fifo_isempty(&vcd->log) || !vcd->output) + return; + + while (!avr_vcd_fifo_isempty(&vcd->log)) { + avr_vcd_log_t l = avr_vcd_fifo_read(&vcd->log); + // 10ns base -- 100MHz should be enough + uint64_t base = avr_cycles_to_nsec(vcd->avr, l.when - vcd->start) / 10; + + /* + * if that trace was seen in this nsec already, we fudge the + * base time to make sure the new value is offset by one nsec, + * to make sure we get at least a small pulse on the waveform. + * + * This is a bit of a fudge, but it is the only way to represent + * very short "pulses" that are still visible on the waveform. + */ + if (base == oldbase && + (seen & (1 << l.sigindex))) + base++; // this forces a new timestamp + + if (base > oldbase || !seen) { + seen = 0; + fprintf(vcd->output, "#%" PRIu64 "\n", base); + oldbase = base; + } + // mark this trace as seen for this timestamp + seen |= (1 << l.sigindex); + fprintf(vcd->output, "%s\n", + l.floating ? + _avr_vcd_get_float_signal_text( + &vcd->signal[l.sigindex], + out) : + _avr_vcd_get_signal_text( + &vcd->signal[l.sigindex], + out, l.value)); + } +} + +/* Cycle timer for writing queued output. */ + +static avr_cycle_count_t +_avr_vcd_timer( + struct avr_t * avr, + avr_cycle_count_t when, + void * param) +{ + avr_vcd_t * vcd = param; + avr_vcd_flush_log(vcd); + return when + vcd->period; +} + +/* Called for an IRQ that is being recorded. */ + +static void +_avr_vcd_notify( + struct avr_irq_t * irq, + uint32_t value, + void * param) +{ + avr_vcd_t * vcd = (avr_vcd_t *)param; + + if (!vcd->output) { + AVR_LOG(vcd->avr, LOG_WARNING, + "%s: no output\n", + __FUNCTION__); + return; + } + + avr_vcd_signal_t * s = (avr_vcd_signal_t*)irq; + avr_vcd_log_t l = { + .sigindex = s->irq.irq, + .when = vcd->avr->cycle, + .value = value, + .floating = !!(avr_irq_get_flags(irq) & IRQ_FLAG_FLOATING), + }; + if (avr_vcd_fifo_isfull(&vcd->log)) { + AVR_LOG(vcd->avr, LOG_WARNING, + "%s FIFO Overload, flushing!\n", + __func__); + /* Decrease period by a quarter, for next time */ + vcd->period -= vcd->period >> 2; + avr_vcd_flush_log(vcd); + } + avr_vcd_fifo_write(&vcd->log, l); +} + +/* Register an IRQ whose value is to be logged. */ + +int +avr_vcd_add_signal( + avr_vcd_t * vcd, + avr_irq_t * signal_irq, + int signal_bit_size, + const char * name ) +{ + if (vcd->signal_count == AVR_VCD_MAX_SIGNALS) { + AVR_LOG(vcd->avr, LOG_ERROR, + " %s: unable add signal '%s'\n", + __FUNCTION__, name); + return -1; + } + int index = vcd->signal_count++; + avr_vcd_signal_t * s = &vcd->signal[index]; + strncpy(s->name, name, sizeof(s->name)); + s->size = signal_bit_size; + s->alias = ' ' + vcd->signal_count ; + + /* manufacture a nice IRQ name */ + int l = strlen(name); + char iname[10 + l + 1]; + if (signal_bit_size > 1) + sprintf(iname, "%d>vcd.%s", signal_bit_size, name); + else + sprintf(iname, ">vcd.%s", name); + + const char * names[1] = { iname }; + avr_init_irq(&vcd->avr->irq_pool, &s->irq, index, 1, names); + avr_irq_register_notify(&s->irq, _avr_vcd_notify, vcd); + + avr_connect_irq(signal_irq, &s->irq); + return 0; +} + +/* Open the VCD output file and write header. Does nothing for input. */ + +int +avr_vcd_start( + avr_vcd_t * vcd) +{ + time_t now; + + vcd->start = vcd->avr->cycle; + avr_vcd_fifo_reset(&vcd->log); + + if (vcd->input) { + /* + * nothing to do here, the first cycle timer will take care + * if it. + */ + return 0; + } + if (vcd->output) + avr_vcd_stop(vcd); + vcd->output = fopen(vcd->filename, "w"); + if (vcd->output == NULL) { + perror(vcd->filename); + return -1; + } + + time(&now); + fprintf(vcd->output, "$date %s$end\n", ctime(&now)); + fprintf(vcd->output, + "$version Simavr " CONFIG_SIMAVR_VERSION " $end\n"); + fprintf(vcd->output, "$timescale 10ns $end\n"); // 10ns base, aka 100MHz + fprintf(vcd->output, "$scope module logic $end\n"); + + for (int i = 0; i < vcd->signal_count; i++) { + fprintf(vcd->output, "$var wire %d %c %s $end\n", + vcd->signal[i].size, vcd->signal[i].alias, vcd->signal[i].name); + } + + fprintf(vcd->output, "$upscope $end\n"); + fprintf(vcd->output, "$enddefinitions $end\n"); + + fprintf(vcd->output, "$dumpvars\n"); + for (int i = 0; i < vcd->signal_count; i++) { + avr_vcd_signal_t * s = &vcd->signal[i]; + char out[48]; + fprintf(vcd->output, "%s\n", + _avr_vcd_get_float_signal_text(s, out)); + } + fprintf(vcd->output, "$end\n"); + avr_cycle_timer_register(vcd->avr, vcd->period, _avr_vcd_timer, vcd); + return 0; +} + +int +avr_vcd_stop( + avr_vcd_t * vcd) +{ + avr_cycle_timer_cancel(vcd->avr, _avr_vcd_timer, vcd); + avr_cycle_timer_cancel(vcd->avr, _avr_vcd_input_timer, vcd); + + avr_vcd_flush_log(vcd); + + if (vcd->input_line) + free(vcd->input_line); + vcd->input_line = NULL; + if (vcd->input) + fclose(vcd->input); + vcd->input = NULL; + if (vcd->output) + fclose(vcd->output); + vcd->output = NULL; + return 0; +} + + diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_vcd_file.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_vcd_file.h new file mode 100644 index 0000000..2dd6219 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_vcd_file.h @@ -0,0 +1,131 @@ +/* + sim_vcd_file.c + + Implements a Value Change Dump file outout to generate + traces & curves and display them in gtkwave. + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __SIM_VCD_FILE_H__ +#define __SIM_VCD_FILE_H__ + +#include <stdio.h> +#include "sim_irq.h" +#include "fifo_declare.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Value Change dump module for simavr. + * + * This structure registers IRQ change hooks to various "source" IRQs + * and dumps their values (if changed) at certain intervals into the VCD + * file. + * + * It can also do the reverse, load a VCD file generated by for example + * sigrock signal analyzer, and 'replay' digital input with the proper + * timing. + * + * TODO: Add support for 'looping' a VCD input. + */ + +#define AVR_VCD_MAX_SIGNALS 64 + +typedef struct avr_vcd_signal_t { + /* + * For VCD output this is the IRQ we receive new values from. + * For VCD input, this is the IRQ we broadcast the values to + */ + avr_irq_t irq; + char alias; // vcd one character alias + uint8_t size; // in bits + char name[32]; // full human name +} avr_vcd_signal_t, *avr_vcd_signal_p; + +typedef struct avr_vcd_log_t { + uint64_t when; // Cycles for output, + // nS for input. + uint64_t sigindex : 8, // index in signal table + floating : 1, + value : 32; +} avr_vcd_log_t, *avr_vcd_log_p; + +DECLARE_FIFO(avr_vcd_log_t, avr_vcd_fifo, 256); + +struct argv_t; + +typedef struct avr_vcd_t { + struct avr_t * avr; // AVR we are attaching timers to.. + + char * filename; // .vcd filename + /* can be input OR output, not both */ + FILE * output; + FILE * input; + struct argv_t * input_line; + + int signal_count; + avr_vcd_signal_t signal[AVR_VCD_MAX_SIGNALS]; + + uint64_t start; + uint64_t period; // for output cycles + uint64_t vcd_to_ns; // for input unit mapping + + avr_vcd_fifo_t log; +} avr_vcd_t; + +// initializes a new VCD trace file, and returns zero if all is well +int +avr_vcd_init( + struct avr_t * avr, + const char * filename, // filename to write + avr_vcd_t * vcd, // vcd struct to initialize + uint32_t period ); // file flushing period is in usec +int +avr_vcd_init_input( + struct avr_t * avr, + const char * filename, // filename to read + avr_vcd_t * vcd ); // vcd struct to initialize +void +avr_vcd_close( + avr_vcd_t * vcd ); + +// Add a trace signal to the vcd file. Must be called before avr_vcd_start() +int +avr_vcd_add_signal( + avr_vcd_t * vcd, + avr_irq_t * signal_irq, + int signal_bit_size, + const char * name ); + +// Starts recording the signal value into the file +int +avr_vcd_start( + avr_vcd_t * vcd); +// stops recording signal values into the file +int +avr_vcd_stop( + avr_vcd_t * vcd); + +#ifdef __cplusplus +}; +#endif + +#endif /* __SIM_VCD_FILE_H__ */ diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/simuc b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/simuc new file mode 100755 index 0000000000000000000000000000000000000000..966bd1f1fef2c8ad96d4c10ce19072af1de44a61 GIT binary patch literal 1820968 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 HTl4<`JTJDT literal 0 HcmV?d00001 diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/main.cpp b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/main.cpp new file mode 100644 index 0000000..0af4178 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/main.cpp @@ -0,0 +1,190 @@ +#include <stdio.h> +#include <unistd.h> +#include <string.h> + +#include "sim/sim.h" +#include "simavr/simavr.h" + +void printHelp () { + printf("simuc V1.0.0 (%s,%s)\n", __DATE__, __TIME__); + printf("usage: simuc [options] elf-file\n\n"); + printf(" available options:\n"); + printf(" --board ... set board (arduino, sure, evws1)\n"); + printf(" --sync sync elapsed µC-time with real time\n\n"); + printf(" --mmcu ... set target device type\n"); + printf(" --frequency ... set target frequency in Hz\n"); + printf(" --pc ... set start program counter (default is 0)\n"); + printf(" --vcc ... set voltage VCC in Volt\n"); + printf(" --avcc ... set voltage AVCC in Volt\n"); + printf(" --aref ... set voltage AREF in Volt\n\n"); + printf(" example:\n"); + printf(" simuc --mmcu atmega328p --frequency 16000000 --pc 0x7000 a.out\n\n"); + printf(" simuc --board arduino a.out\n\n"); +} + +int main (int argc, char **argv) { + struct StartParameters params = { + filename: NULL, + gdbPort: -1, + frequency: -1, + mmcu: NULL, + board: BoardUnknown, + vcc: -1, + avcc: -1, + aref: -1 + }; + + if (argc <= 1) { + printHelp(); + return 1; + } + + for (int i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + if (strcmp(argv[i], "--help") == 0) { + printHelp(); + return 0; + } else if (strcmp(argv[i], "--board") == 0 && argc >= (i + 1)) { + i++; + if (strcmp("arduino", argv[i]) == 0) { + params.board = BoardNano; + params.mmcu = "atmega328p"; + params.frequency = 16000000; + params.vcc = 5000; + params.avcc = 5000; + params.aref = 2500; + } else if (strcmp("sure", argv[i]) == 0) { + params.board = BoardSure; + params.mmcu = "atmega16"; + params.frequency = 12000000; + params.vcc = 5000; + params.avcc = 5000; + params.aref = 2500; + } else if (strcmp("evws1", argv[i]) == 0) { + params.board = BoardEWS1; + params.mmcu = "atmega324p"; + params.frequency = 20000000; + params.vcc = 5000; + params.avcc = 5000; + params.aref = 2500; + } else { + fprintf(stderr, "ERROR: invalid board %s, use --help to show usage\n\n", argv[i]); + return 1; + } + + } else if (strcmp(argv[i], "--mmcu") == 0) { + params.mmcu = argv[++i]; + } else if (strcmp(argv[i], "--port") == 0) { + sscanf(argv[++i], "%d", ¶ms.gdbPort); + } else if (strcmp(argv[i], "--frequency") == 0) { + sscanf(argv[++i], "%" PRIu64, ¶ms.frequency); + } else if (strcmp(argv[i], "--pc") == 0) { + i++; + if (argv[i][0] == '0' && argv[i][1] == 'x') { + sscanf(&argv[i][2], "%x", ¶ms.pc); + } else { + sscanf(argv[++i], "%d", ¶ms.pc); + } + } else if (strcmp(argv[i], "--vcc") == 0) { + sscanf(argv[++i], "%d", ¶ms.vcc); + } else if (strcmp(argv[i], "--avcc") == 0) { + sscanf(argv[++i], "%d", ¶ms.avcc); + } else if (strcmp(argv[i], "--aref") == 0) { + sscanf(argv[++i], "%d", ¶ms.aref); + } else { + fprintf(stderr, "ERROR: invalid option %s, use --help to show usage\n\n", argv[i]); + return 1; + } + continue; + } + params.filename = argv[i]; + break; + } + + if (params.filename == NULL) { + printf("ERROR: missing target elf file, use --help to show usage\n\n"); + return 1; + } + + init(¶ms); + if (errno == 1) { + return 1; + } + printf("init done - press key to start\n"); + getchar(); + start(); + + // int cnt = 0; + char *line = NULL; + size_t size = 0; + while (1) { + // struct SimAvrEvent ev = waitForEvent(); + // printf("%10.03lf: event %s (%d) received \r", ev.cycle / 20E6, eventText((EnumSimEvent)ev.event), ev.event); + // fflush(stdout); + // if (++cnt == 10000) { + // stop(); + // shutdown(); + // break; + // } + + if (getline(&line, &size, stdin) > 0) { + const char *commands[] = { "interrupt", "continue", "stack" }; + try { + int foundIndex = -1; + int foundCnt = 0; + size_t length = strlen(line) - 1; + if (length > 0 && size >= (length + 1)) { + line[length] = 0; + for (long unsigned int i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) { + const char *cmd = commands[i]; + size_t max = strlen(cmd); + bool ok = true; + for (size_t j = 0; j < length; j++) { + if (j >= max || line[j] != cmd[j]) { + ok = false; + break; + } + } + if (ok) { + foundCnt++; + foundIndex = i; + } + } + } + // printf("foundCnt=%d foundIndex=%d command=%s\n", foundCnt, foundIndex, foundIndex >= 0 ? commands[foundIndex] : ""); + if (foundCnt == 1 || length == 0) { + setCommand((EnumSimAvrCommand)(foundCnt > 0 ? foundIndex + 2 : 1), NULL); + while (1) { + struct SimAvrEvent ev = waitForEvent(); + if (ev.event == EventCommandExecuted) { + break; + } + } + + } else { + printf("invalid command, valid commands are <Enter> for status and:"); + for (long unsigned int i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) { + printf(" %s", commands[i]); + } + printf("\n"); + continue; + } + + } catch (std::exception& e) { + printf("ERROR\n"); + } + + } + + } + while (1) { + struct SimAvrEvent ev = waitForEvent(); + printf("event %s (%d) received\n", eventText((EnumSimEvent)ev.event), ev.event); + if (ev.event == EventShutdown) { + break; + } + } + + usleep(10000); + return 0; +} \ No newline at end of file diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/error.cpp b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/error.cpp new file mode 100644 index 0000000..f59ddbd --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/error.cpp @@ -0,0 +1,18 @@ +#include "error.h" +#include <stdarg.h> + +std::string error (const char *location, const char *format, ...) { + va_list args; + va_start (args, format); + int length = std::vsnprintf (NULL, 0, format, args); + va_end (args); + + va_start (args, format); + char* str = new char[length + 1]; // one more character for null terminator + std::vsnprintf (str, length + 1, format, args); + std::string rv = "Error at " + std::string(location) + " -> " + str; + delete[] str; + va_end (args); + + return rv; +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/error.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/error.h new file mode 100644 index 0000000..80d5682 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/error.h @@ -0,0 +1,11 @@ +#ifndef ERROR_H +#define ERROR_H + +#include <string> + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) +#define AT __FILE__ ":" TOSTRING(__LINE__) +std::string error (const char *location, const char *format, ...); + +#endif // ERROR_H diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/sim.cpp b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/sim.cpp new file mode 100644 index 0000000..32a23b6 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/sim.cpp @@ -0,0 +1,282 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <libgen.h> +#include <errno.h> +#include <stdarg.h> + +#include <stdexcept> +#include <string> +#include <iostream> +#include <vector> + +#include <GL/glut.h> +#include <pthread.h> +#include <simavr/sim_avr.h> +#include <simavr/sim_elf.h> +#include <simavr/sim_gdb.h> + +#include "sim.h" +#include "error.h" + + + +// https://github.com/java-native-access/jna/blob/master/www/CallbacksAndClosures.md#callbacks-function-pointers-and-closures + + +int SIGUSR1 = 30; + +// avr_t * avr = NULL; +SimAvr simavr; +std::string lastErrorMessage; + +static int fdStdOut = -1, fdStdErr = -1; +// static fpos_t posStdOut, posStdErr; + +void switchStdOut (const char * filename) { + fflush(stdout); + // fgetpos(stdout, &posStdOut); + if (filename == NULL) { + int fd = open("/dev/null", O_WRONLY); + fdStdOut = dup2(fd, fileno(stdout)); + } else { + fdStdOut = dup(fileno(stdout)); + } +} + +void switchStdErr (const char * filename) { + fflush(stderr); + // fgetpos(stderr, &posStdErr); + if (filename == NULL) { + int fd = open("/dev/null", O_WRONLY); + fdStdErr = dup2(fd, fileno(stderr)); + } else { + fdStdErr = dup(fileno(stderr)); + } +} + +void revertStdErrOut () { + if (fdStdOut >= 0) { + fflush(stdout); + dup2(fdStdOut, fileno(stdout)); + close(fdStdOut); + fdStdOut = -1; + clearerr(stdout); + // fsetpos(stdout, &posStdOut); + } + if (fdStdErr >= 0) { + fflush(stderr); + dup2(fdStdErr, fileno(stderr)); + close(fdStdErr); + fdStdErr = -1; + clearerr(stderr); + // fsetpos(stderr, &posStdErr); + } +} + +const char * lastError () { + return lastErrorMessage.c_str(); +} + + +// static void handleWritePortB (struct avr_t * avr, __attribute__((unused)) avr_io_addr_t addr, uint8_t v, SimAvr *simavr) { +// static int value = 0; +// if (value != v) { +// value = v; +// if (simavr != NULL) { +// if ((value << PORTB0) != 0) { +// simavr->addEvent(EventLedOn); +// } else { +// simavr->addEvent(EventLedOff); +// } +// } +// } +// } + +std::vector<uint8_t> gdbFromUartBuffer; +std::vector<uint8_t> gdbToUartBuffer; + +__attribute__((unused)) static void fromGdbUart (uint8_t b) { + static int cnt = 0; + if (b == '$') { + cnt = 1; + } else if (cnt > 0 && b == '#') { + cnt = -1; + } else if (cnt < 0) { + cnt--; + } + gdbFromUartBuffer.push_back(b); + + if (cnt <= -3 || (cnt == 0 && b == '+')) { + printf("\n\rgdb-uart OUT -> "); + for (uint8_t c : gdbFromUartBuffer) { + putchar(c); + } + printf("\n\r"); + gdbFromUartBuffer.clear(); + } +} + +__attribute__((unused)) static void toGdbUart (uint8_t b) { + static int cnt = 0; + if (b == '$') { + cnt = 1; + } else if (cnt > 0 && b == '#') { + cnt = -1; + } else if (cnt < 0) { + cnt--; + } + gdbToUartBuffer.push_back(b); + + if (cnt <= -3 || (cnt == 0 && b == '+')) { + printf("\n\rgdb-uart IN <-- "); + for (uint8_t c : gdbToUartBuffer) { + putchar(c); + } + printf("\n\r"); + gdbToUartBuffer.clear(); + } + +} + +void init (struct StartParameters *param) { + try { + // switchStdOut(NULL); + // switchStdErr(NULL); + // std::cout.rdbuf(0); + // std::cerr.rdbuf(0); + const char *filename = param->filename != NULL + ? param->filename + // : "../gdb-stub-sm_atmega324p/sim/dist/gdb-stub-sm_atmega324p.axf"; + : "../gdb-stub-sm_atmega324p/sim/dist/gdb-stub-sm_atmega324p.axf"; + printf("firmware file \"%s\"\n", filename); + simavr.load(param); + if (strcmp(simavr.getTargetDeviceName(), "atmega324p") != 0) { + std::logic_error(error(AT, "invalid target device %s", simavr.getTargetDeviceName())); + } + + simavr.setUartDumpEnabled(false); + // simavr.registerIoWrite(PORTB, handleWritePortB); + simavr.setUartPtyEnabled(0, true); + int uartCnt = 1; + if (strcmp(simavr.getTargetDeviceName(), "atmega324p") == 0) { + simavr.setUartPtyEnabled(1, true); + simavr.setUartPtyHook(1, fromGdbUart, toGdbUart); + uartCnt = 2; + } + // printf("uart0 -> picocom --imap lfcrlf -b 115200 %s\n", simavr.getUartPtyDeviceName(0)); + // printf("uart1 -> picocom --imap lfcrlf -b 115200 %s\n", simavr.getUartPtyDeviceName(1)); + + printf("device %s\n", simavr.getTargetDeviceName()); + printf("frequency %.2lfMHz\n", simavr.getTargetFrequency() / 1E6); + + for (int i = 0; i < uartCnt; i++) { + char s[128]; + snprintf(s, 128, "/tmp/sim-megaavr-%s-uart%1d", simavr.getTargetDeviceName(), i); + FILE *f = fopen(s, "w"); + if (f == NULL) { + std::logic_error(error(AT, "cannot write file %s", s)); + } + printf("uart%1d -> picocom %s (see file %s)\n", i, simavr.getUartPtyDeviceName(i), s); + fprintf(f, "%s\n", simavr.getUartPtyDeviceName(i)); + fclose(f); + } + + } catch (std::exception& e) { + lastErrorMessage = "init() fails, caused by " + std::string(e.what()); + std::cerr << lastErrorMessage << "\n"; + errno = 1; + } +} + +void shutdown () { + try { + simavr.shutdown(); + } catch (std::exception& e) { + lastErrorMessage = "shutdown() fails, caused by " + std::string(e.what()); + std::cerr << lastErrorMessage << "\n"; + errno = 1; + } +} + +void start () { + try { + simavr.start(); + + } catch (std::exception& e) { + lastErrorMessage = "start() fails, caused by " + std::string(e.what()); + std::cerr << lastErrorMessage << "\n"; + errno = 1; + } +} + +void stop () { + try { + simavr.stop(); + + } catch (std::exception& e) { + lastErrorMessage = "stop() fails, caused by " + std::string(e.what()); + std::cerr << lastErrorMessage << "\n"; + errno = 1; + } +} + +void setCommand (EnumSimAvrCommand cmd, void *param) { + try { + simavr.setCommand(cmd, param); + + } catch (std::exception& e) { + lastErrorMessage = "setCommand(..) fails, caused by " + std::string(e.what()); + std::cerr << lastErrorMessage << "\n"; + errno = 1; + throw e; + } + +} + +void addEvent (EnumSimEvent event) { + try { + simavr.addEvent(event); + + } catch (std::exception& e) { + lastErrorMessage = "addEvent(..) fails, caused by " + std::string(e.what()); + std::cerr << lastErrorMessage << "\n"; + errno = 1; + } +} + +void setTimeSync (bool sync) { + try { + simavr.setTimeSync(sync); + + } catch (std::exception& e) { + lastErrorMessage = "setTimeSync() fails, caused by " + std::string(e.what()); + std::cerr << lastErrorMessage << "\n"; + errno = 1; + } +} + +struct SimAvrStatus getStatus () { + return simavr.getStatus();; +} + +struct SimAvrEvent waitForEvent () { + return simavr.waitForEvent(); +} + +const char *eventText (EnumSimEvent event) { + const char *rv = simavr.eventText((EnumSimAvrEvent)event); + if (rv != NULL) { + return rv; + } else { + switch (event) { + case EventLedOff: return "LedOff"; + case EventLedOn: return "LedOn"; + default: return "?"; + } + } +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/sim.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/sim.h new file mode 100644 index 0000000..d980f26 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/sim.h @@ -0,0 +1,43 @@ +#ifndef SIM_H +#define SIM_H + +#include "../simavr/simavr.h" + +// #define _AVR_IO_H_ +// #define _SFR_IO8(reg) (0x20 + reg) +// #include "iom324p.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + EventInterrupt = 1, + EventLedOff = 10, + EventLedOn = 11 +} EnumSimEvent; + + + +extern void init (struct StartParameters *param); +extern void shutdown (); +extern const char * lastError (); +extern void start (); +extern void stop (); +extern void setCommand (EnumSimAvrCommand cmd, void *param); +extern void addEvent (EnumSimEvent event); +extern void setTimeSync (bool sync); +extern struct SimAvrStatus getStatus (); +extern struct SimAvrEvent waitForEvent (); +extern const char *eventText (EnumSimEvent event); + +typedef void (*NotificationListener)(char *, int); +void callbackTrigger(const NotificationListener l); +void getDeviceRandomStatus(char *answer, int sizeOfChars); +int randNum( int min, int max); + +#ifdef __cplusplus +} +#endif + +#endif // SIM_H diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/fifo_declare.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/fifo_declare.h new file mode 100644 index 0000000..8a3b2fb --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/fifo_declare.h @@ -0,0 +1,189 @@ +/* + fido_declare.h + Copyright (C) 2003-2012 Michel Pollet <buserror@gmail.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* + * FIFO helpers, aka circular buffers + * + * these macros define accessories for FIFOs of any name, type and + * any (power of two) size + */ + +#ifndef __FIFO_DECLARE__ +#define __FIFO_DECLARE__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + doing a : + DECLARE_FIFO(uint8_t, myfifo, 128); + + will declare : + enum : myfifo_overflow_f + type : myfifo_t + functions: + // write a byte into the fifo, return 1 if there was room, 0 if there wasn't + int myfifo_write(myfifo_t *c, uint8_t b); + // reads a byte from the fifo, return 0 if empty. Use myfifo_isempty() to check beforehand + uint8_t myfifo_read(myfifo_t *c); + int myfifo_isfull(myfifo_t *c); + int myfifo_isempty(myfifo_t *c); + // returns number of items to read now + uint16_t myfifo_get_read_size(myfifo_t *c); + // read item at offset o from read cursor, no cursor advance + uint8_t myfifo_read_at(myfifo_t *c, uint16_t o); + // write b at offset o compared to current write cursor, no cursor advance + void myfifo_write_at(myfifo_t *c, uint16_t o, uint8_t b); + + In your .c you need to 'implement' the fifo: + DEFINE_FIFO(uint8_t, myfifo) + + To use the fifo, you must declare at least one : + myfifo_t fifo = FIFO_NULL; + + while (!myfifo_isfull(&fifo)) + myfifo_write(&fifo, 0xaa); + .... + while (!myfifo_isempty(&fifo)) + b = myfifo_read(&fifo); + */ + +#include <stdint.h> + +#if __AVR__ +#define FIFO_CURSOR_TYPE uint8_t +#define FIFO_BOOL_TYPE char +#define FIFO_INLINE +#define FIFO_SYNC +#endif + +#ifndef FIFO_CURSOR_TYPE +#define FIFO_CURSOR_TYPE uint16_t +#endif +#ifndef FIFO_BOOL_TYPE +#define FIFO_BOOL_TYPE int +#endif +#ifndef FIFO_INLINE +#define FIFO_INLINE inline +#endif + +/* We should not need volatile */ +#ifndef FIFO_VOLATILE +#define FIFO_VOLATILE +#endif +#ifndef FIFO_SYNC +#define FIFO_SYNC __sync_synchronize() +#endif + +#ifndef FIFO_ZERO_INIT +#define FIFO_ZERO_INIT {0} +#endif +#define FIFO_NULL { FIFO_ZERO_INIT, 0, 0, 0 } + +/* New compilers don't like unused static functions. However, + * we do like 'static inlines' for these small accessors, + * so we mark them as 'unused'. It stops it complaining */ +#ifdef __GNUC__ +#define FIFO_DECL static __attribute__ ((unused)) +#else +#define FIFO_DECL static +#endif + +#define DECLARE_FIFO(__type, __name, __size) \ +enum { __name##_overflow_f = (1 << 0) }; \ +enum { __name##_fifo_size = (__size) }; \ +typedef struct __name##_t { \ + __type buffer[__name##_fifo_size]; \ + FIFO_VOLATILE FIFO_CURSOR_TYPE read; \ + FIFO_VOLATILE FIFO_CURSOR_TYPE write; \ + FIFO_VOLATILE uint8_t flags; \ +} __name##_t + +#define DEFINE_FIFO(__type, __name) \ +FIFO_DECL FIFO_INLINE FIFO_BOOL_TYPE __name##_write(__name##_t * c, __type b)\ +{\ + FIFO_CURSOR_TYPE now = c->write;\ + FIFO_CURSOR_TYPE next = (now + 1) & (__name##_fifo_size-1);\ + if (c->read != next) { \ + c->buffer[now] = b;\ + FIFO_SYNC; \ + c->write = next;\ + return 1;\ + }\ + return 0;\ +}\ +FIFO_DECL FIFO_INLINE FIFO_BOOL_TYPE __name##_isfull(__name##_t *c)\ +{\ + FIFO_CURSOR_TYPE next = (c->write + 1) & (__name##_fifo_size-1);\ + return c->read == next;\ +}\ +FIFO_DECL FIFO_INLINE FIFO_BOOL_TYPE __name##_isempty(__name##_t * c)\ +{\ + return c->read == c->write;\ +}\ +FIFO_DECL FIFO_INLINE __type __name##_read(__name##_t * c)\ +{\ + __type res = FIFO_ZERO_INIT; \ + FIFO_CURSOR_TYPE read = c->read;\ + if (read == c->write)\ + return res;\ + res = c->buffer[read];\ + FIFO_SYNC; \ + c->read = (read + 1) & (__name##_fifo_size-1);\ + return res;\ +}\ +FIFO_DECL FIFO_INLINE FIFO_CURSOR_TYPE __name##_get_read_size(__name##_t *c)\ +{\ + return ((c->write + __name##_fifo_size) - c->read) & (__name##_fifo_size-1);\ +}\ +FIFO_DECL FIFO_INLINE FIFO_CURSOR_TYPE __name##_get_write_size(__name##_t *c)\ +{\ + return (__name##_fifo_size-1) - __name##_get_read_size(c);\ +}\ +FIFO_DECL FIFO_INLINE void __name##_read_offset(__name##_t *c, FIFO_CURSOR_TYPE o)\ +{\ + FIFO_SYNC; \ + c->read = (c->read + o) & (__name##_fifo_size-1);\ +}\ +FIFO_DECL FIFO_INLINE __type __name##_read_at(__name##_t *c, FIFO_CURSOR_TYPE o)\ +{\ + return c->buffer[(c->read + o) & (__name##_fifo_size-1)];\ +}\ +FIFO_DECL FIFO_INLINE void __name##_write_at(__name##_t *c, FIFO_CURSOR_TYPE o, __type b)\ +{\ + c->buffer[(c->write + o) & (__name##_fifo_size-1)] = b;\ +}\ +FIFO_DECL FIFO_INLINE void __name##_write_offset(__name##_t *c, FIFO_CURSOR_TYPE o)\ +{\ + FIFO_SYNC; \ + c->write = (c->write + o) & (__name##_fifo_size-1);\ +}\ +FIFO_DECL FIFO_INLINE void __name##_reset(__name##_t *c)\ +{\ + FIFO_SYNC; \ + c->read = c->write = c->flags = 0;\ +}\ +struct __name##_t + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/uart_pty.c b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/uart_pty.c new file mode 100644 index 0000000..a283fef --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/uart_pty.c @@ -0,0 +1,371 @@ +/* + uart_pty.c + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <simavr/sim_network.h> +#include <stdlib.h> +#include <pthread.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <signal.h> +#ifdef __APPLE__ +#include <util.h> +#elif defined (__FreeBSD__) +#include <sys/types.h> +#include <sys/ioctl.h> +#include <termios.h> +#include <libutil.h> +#else +#include <pty.h> +#endif + +#include "uart_pty.h" +#include <simavr/avr_uart.h> +#include <simavr/sim_time.h> +#include <simavr/sim_hex.h> + +DEFINE_FIFO(uint8_t,uart_pty_fifo); + +//#define TRACE(_w) _w +#ifndef TRACE +#define TRACE(_w) +#endif + +TRACE(static const char * +uart_pty_toPrintableChar( + uint32_t value) +{ + static char rv[2] = ""; + if (value >= ' ' && value <= 126) { + rv[0] = (char)value; + rv[1] = 0; + } else if (value == '\n') { + return "\\n"; + } else if (value == '\r') { + return "\\r"; + } else { + rv[0] = 0; + } + return rv; +}) + + +/* + * called when a byte is send via the uart on the AVR + */ +static void +uart_pty_in_hook( + struct avr_irq_t * irq, + uint32_t value, + void * param) +{ + uart_pty_t * p = (uart_pty_t*)param; + TRACE(printf("uart_pty_in_hook %02x %s\n", value, uart_pty_toPrintableChar(value));) + if (p->port[0].crlf && value == '\n') { + uart_pty_fifo_write(&p->port[0].in, '\r'); + } + uart_pty_fifo_write(&p->pty.in, value); + if (p->port[0].hook_from_uart != NULL) { + p->port[0].hook_from_uart(value); + } else if (p->hook_from_uart != NULL) { + p->hook_from_uart(value); + } + + if (p->tap.s) { + if (p->tap.crlf && value == '\n') + uart_pty_fifo_write(&p->tap.in, '\r'); + uart_pty_fifo_write(&p->tap.in, value); + } +} + +// try to empty our fifo, the uart_pty_xoff_hook() will be called when +// other side is full +static void +uart_pty_flush_incoming( + uart_pty_t * p) +{ + while (p->xon && !uart_pty_fifo_isempty(&p->pty.out)) { + TRACE(int r = p->pty.out.read;) + uint8_t byte = uart_pty_fifo_read(&p->pty.out); + TRACE(printf("uart_pty_flush_incoming send r %03d:%02x\n", r, byte);) + avr_raise_irq(p->irq + IRQ_UART_PTY_BYTE_OUT, byte); + + if (p->tap.s) { + if (p->tap.crlf && byte == '\n') + uart_pty_fifo_write(&p->tap.in, '\r'); + uart_pty_fifo_write(&p->tap.in, byte); + } + } + if (p->tap.s) { + while (p->xon && !uart_pty_fifo_isempty(&p->tap.out)) { + uint8_t byte = uart_pty_fifo_read(&p->tap.out); + if (p->tap.crlf && byte == '\r') { + uart_pty_fifo_write(&p->tap.in, '\n'); + } + if (byte == '\n') + continue; + uart_pty_fifo_write(&p->tap.in, byte); + avr_raise_irq(p->irq + IRQ_UART_PTY_BYTE_OUT, byte); + } + } +} + +avr_cycle_count_t +uart_pty_flush_timer( + struct avr_t * avr, + avr_cycle_count_t when, + void * param) +{ + uart_pty_t * p = (uart_pty_t*)param; + + uart_pty_flush_incoming(p); + /* always return a cycle NUMBER not a cycle count */ + return p->xon ? when + avr_hz_to_cycles(p->avr, 1000) : 0; +} + +/* + * Called when the uart has room in it's input buffer. This is called repeateadly + * if necessary, while the xoff is called only when the uart fifo is FULL + */ +static void +uart_pty_xon_hook( + struct avr_irq_t * irq, + uint32_t value, + void * param) +{ + uart_pty_t * p = (uart_pty_t*)param; + TRACE(if (!p->xon) printf("uart_pty_xon_hook\n");) + p->xon = 1; + + uart_pty_flush_incoming(p); + + // if the buffer is not flushed, try to do it later + if (p->xon) + avr_cycle_timer_register(p->avr, avr_hz_to_cycles(p->avr, 1000), + uart_pty_flush_timer, param); +} + +/* + * Called when the uart ran out of room in it's input buffer + */ +static void +uart_pty_xoff_hook( + struct avr_irq_t * irq, + uint32_t value, + void * param) +{ + uart_pty_t * p = (uart_pty_t*)param; + TRACE(if (p->xon) printf("uart_pty_xoff_hook\n");) + p->xon = 0; + avr_cycle_timer_cancel(p->avr, uart_pty_flush_timer, param); +} + +static void * +uart_pty_thread( + void * param) +{ + uart_pty_t * p = (uart_pty_t*)param; + + while (1) { + fd_set read_set, write_set; + int max = 0; + FD_ZERO(&read_set); + FD_ZERO(&write_set); + + for (int ti = 0; ti < 2; ti++) if (p->port[ti].s) { + // read more only if buffer was flushed + if (p->port[ti].buffer_len == p->port[ti].buffer_done) { + FD_SET(p->port[ti].s, &read_set); + max = p->port[ti].s > max ? p->port[ti].s : max; + } + if (!uart_pty_fifo_isempty(&p->port[ti].in)) { + FD_SET(p->port[ti].s, &write_set); + max = p->port[ti].s > max ? p->port[ti].s : max; + } + } + + // short, but not too short interval + struct timeval timo = { 0, 500 }; + int ret = select(max+1, &read_set, &write_set, NULL, &timo); + + if (ret < 0) + break; + + for (int ti = 0; ti < 2; ti++) if (p->port[ti].s) { + if (FD_ISSET(p->port[ti].s, &read_set)) { + ssize_t r = read(p->port[ti].s, p->port[ti].buffer, + sizeof(p->port[ti].buffer)-1); + p->port[ti].buffer_len = r; + p->port[ti].buffer_done = 0; + TRACE(if (!p->port[ti].tap) + hdump("pty recv", p->port[ti].buffer, r);) + } + if (p->port[ti].buffer_done < p->port[ti].buffer_len) { + // write them in fifo + while (p->port[ti].buffer_done < p->port[ti].buffer_len && + !uart_pty_fifo_isfull(&p->port[ti].out)) { + int index = p->port[ti].buffer_done++; + TRACE(int wi = p->port[ti].out.write;) + uart_pty_fifo_write(&p->port[ti].out, + p->port[ti].buffer[index]); + TRACE(printf("w %3d:%02x (%d/%d) %s\n", + wi, p->port[ti].buffer[index], + p->port[ti].out.read, + p->port[ti].out.write, + p->xon ? "XON" : "XOFF");) + if (p->port[ti].hook_to_uart != NULL) { + p->port[ti].hook_to_uart(p->port[ti].buffer[index]); + } else if (p->hook_to_uart != NULL) { + p->hook_to_uart(p->port[ti].buffer[index]); + } + } + } + if (FD_ISSET(p->port[ti].s, &write_set)) { + uint8_t buffer[512]; + // write them in fifo + uint8_t * dst = buffer; + while (!uart_pty_fifo_isempty(&p->port[ti].in) && + (dst - buffer) < sizeof(buffer)) { + *dst = uart_pty_fifo_read(&p->port[ti].in); + dst++; + } + size_t len = dst - buffer; + TRACE(size_t r =) write(p->port[ti].s, buffer, len); + TRACE(if (!p->port[ti].tap) hdump("pty send", buffer, r);) + } + } + /* DO NOT call this, this create a concurency issue with the + * FIFO that can't be solved cleanly with a memory barrier + uart_pty_flush_incoming(p); + */ + } + return NULL; +} + +static const char * irq_names[IRQ_UART_PTY_COUNT] = { + [IRQ_UART_PTY_BYTE_IN] = "8<uart_pty.in", + [IRQ_UART_PTY_BYTE_OUT] = "8>uart_pty.out", +}; + +void +uart_pty_init( + struct avr_t * avr, + uart_pty_t * p) +{ + memset(p, 0, sizeof(*p)); + + p->avr = avr; + p->irq = avr_alloc_irq(&avr->irq_pool, 0, IRQ_UART_PTY_COUNT, irq_names); + avr_irq_register_notify(p->irq + IRQ_UART_PTY_BYTE_IN, uart_pty_in_hook, p); + + const int hastap = (getenv("SIMAVR_UART_TAP") && atoi(getenv("SIMAVR_UART_TAP"))) || + (getenv("SIMAVR_UART_XTERM") && atoi(getenv("SIMAVR_UART_XTERM"))); + p->hastap = hastap; + p->hook_from_uart = NULL; + p->hook_to_uart = NULL; + + for (int ti = 0; ti < 1 + hastap; ti++) { + int m, s; + + if (openpty(&m, &s, p->port[ti].slavename, NULL, NULL) < 0) { + fprintf(stderr, "%s: Can't create pty: %s", __FUNCTION__, strerror(errno)); + return; + } + struct termios tio; + tcgetattr(m, &tio); + cfmakeraw(&tio); + tio.c_cflag &= ~(ECHO | ECHONL); // no input echo + // tio.c_oflag |= (OPOST | ONLCR); // LF -> CRLF + tcsetattr(m, TCSANOW, &tio); + p->port[ti].s = m; + p->port[ti].tap = ti != 0; + // p->port[ti].crlf = ti != 0; + p->port[ti].crlf = 1; + p->port[ti].hook_from_uart = NULL; + p->port[ti].hook_to_uart = NULL; + if (ti > 0) { + printf("uart_pty_init %s on port *** %s ***\n", + ti == 0 ? "bridge" : "tap", p->port[ti].slavename); + } + } + + pthread_create(&p->thread, NULL, uart_pty_thread, p); + +} + +void +uart_pty_stop( + uart_pty_t * p) +{ + puts(__func__); + pthread_kill(p->thread, SIGINT); + for (int ti = 0; ti < 2; ti++) + if (p->port[ti].s) + close(p->port[ti].s); + void * ret; + pthread_join(p->thread, &ret); +} + +void +uart_pty_connect( + uart_pty_t * p, + char uart) +{ + // disable the stdio dump, as we are sending binary there + uint32_t f = 0; + avr_ioctl(p->avr, AVR_IOCTL_UART_GET_FLAGS(uart), &f); + f &= ~AVR_UART_FLAG_STDIO; + avr_ioctl(p->avr, AVR_IOCTL_UART_SET_FLAGS(uart), &f); + + avr_irq_t * src = avr_io_getirq(p->avr, AVR_IOCTL_UART_GETIRQ(uart), UART_IRQ_OUTPUT); + avr_irq_t * dst = avr_io_getirq(p->avr, AVR_IOCTL_UART_GETIRQ(uart), UART_IRQ_INPUT); + avr_irq_t * xon = avr_io_getirq(p->avr, AVR_IOCTL_UART_GETIRQ(uart), UART_IRQ_OUT_XON); + avr_irq_t * xoff = avr_io_getirq(p->avr, AVR_IOCTL_UART_GETIRQ(uart), UART_IRQ_OUT_XOFF); + + if (src && dst) { + avr_connect_irq(src, p->irq + IRQ_UART_PTY_BYTE_IN); + avr_connect_irq(p->irq + IRQ_UART_PTY_BYTE_OUT, dst); + } + if (xon) + avr_irq_register_notify(xon, uart_pty_xon_hook, p); + if (xoff) + avr_irq_register_notify(xoff, uart_pty_xoff_hook, p); + + for (int ti = 0; ti < 1+(p->hastap?1:0); ti++) if (p->port[ti].s) { + char link[128]; + snprintf(link, sizeof(link), "/tmp/simavr-uart%c%s", uart, ti == 1 ? "-tap" : ""); + unlink(link); + if (symlink(p->port[ti].slavename, link) != 0) { + fprintf(stderr, "WARN %s: Can't create %s: %s", __func__, link, strerror(errno)); + } else { + // printf("%s: %s now points to %s\n", __func__, link, p->port[ti].slavename); + } + } + if (getenv("SIMAVR_UART_XTERM") && atoi(getenv("SIMAVR_UART_XTERM"))) { + char cmd[256]; + sprintf(cmd, "xterm -e picocom -b 115200 %s >/dev/null 2>&1 &", + p->tap.slavename); + system(cmd); + } else { + // printf("note: export SIMAVR_UART_XTERM=1 and install picocom to get a terminal\n"); + } +} diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/uart_pty.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/uart_pty.h new file mode 100644 index 0000000..482de7d --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/uart_pty.h @@ -0,0 +1,90 @@ +/* + uart_pty.h + + Copyright 2012 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef __UART_PTY_H___ +#define __UART_PTY_H___ + +#include <pthread.h> +#include <simavr/sim_irq.h> +#include "fifo_declare.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + IRQ_UART_PTY_BYTE_IN = 0, + IRQ_UART_PTY_BYTE_OUT, + IRQ_UART_PTY_COUNT +}; + +DECLARE_FIFO(uint8_t,uart_pty_fifo, 512); + +typedef struct uart_pty_port_t { + unsigned int tap : 1, crlf : 1; + int s; // socket we chat on + char slavename[64]; + uart_pty_fifo_t in; + uart_pty_fifo_t out; + uint8_t buffer[512]; + size_t buffer_len, buffer_done; + void (*hook_from_uart)(uint8_t); + void (*hook_to_uart)(uint8_t); +} uart_pty_port_t, *uart_pty_port_p; + +typedef struct uart_pty_t { + avr_irq_t * irq; // irq list + struct avr_t *avr; // keep it around so we can pause it + + pthread_t thread; + int xon; + int hastap; + + union { + struct { + uart_pty_port_t pty; + uart_pty_port_t tap; + }; + uart_pty_port_t port[2]; + }; + void (*hook_from_uart)(uint8_t); + void (*hook_to_uart)(uint8_t); +} uart_pty_t; + +void +uart_pty_init( + struct avr_t * avr, + uart_pty_t * b); +void +uart_pty_stop(uart_pty_t * p); + +void +uart_pty_connect( + uart_pty_t * p, + char uart); + +#ifdef __cplusplus +} +#endif + +#endif /* __UART_PTY_H___ */ + diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/semaphore.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/semaphore.h new file mode 100644 index 0000000..289a45d --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/semaphore.h @@ -0,0 +1,32 @@ +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +#include <mutex> +#include <condition_variable> + +class Semaphore { + public: + Semaphore (int count_ = 0) : count(count_) { + } + + inline void notify () { + std::unique_lock<std::mutex> lock(mtx); + count++; + //notify the waiting thread + cv.notify_one(); + } + inline void wait () { + std::unique_lock<std::mutex> lock(mtx); + while(count == 0) { + //wait on the mutex until notify is called + cv.wait(lock); + } + count--; + } + private: + std::mutex mtx; + std::condition_variable cv; + int count; +}; + +#endif // SEMAPHORE_H diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/simavr.cpp b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/simavr.cpp new file mode 100644 index 0000000..ba63390 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/simavr.cpp @@ -0,0 +1,749 @@ +#include "simavr.h" +#include "../sim/error.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <limits.h> +#include <sys/time.h> + +#include <iostream> +#include <iomanip> +#include <thread> + +#include <simavr/sim_gdb.h> +#include <simavr/sim_irq.h> +#include <simavr/sim_avr.h> +#include <simavr/sim_core.h> +#include <simavr/avr_uart.h> + + +SimAvr::SimAvr () { + memset(&status, 0, sizeof(status)); +} + +SimAvr::~SimAvr () { + if (firmware != NULL) { + free(firmware); + firmware = NULL; + } + if (avr != NULL) { + free(avr); + avr = NULL; + } +} + +void SimAvr::shutdown () { + // if (pthread_mutex_lock(&lock)) { + // throw std::logic_error(error(AT, "shutdown() fails caused by mutex error")); + // } + // cancelThread = true; + // isShutdown = true; + // pthread_mutex_unlock(&lock); + addEvent(EventShutdown); +} + + +void SimAvr::load (struct StartParameters *params) { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "load() fails caused by mutex error")); + } + try { + if (isShutdown) { + throw std::logic_error(error(AT, "cannot load after simavr shutdown")); + } + if (firmware != NULL) { + throw std::logic_error(error(AT, "firmware already loaded")); + } + + startParameters = params; + firmware = (elf_firmware_t *) malloc(sizeof(elf_firmware_t)); + std::string filename = std::string(params->filename); + if (firmware == NULL || elf_read_firmware(filename.c_str(), firmware) != 0) { + throw std::logic_error(error(AT, "elf_read_firmware() from %s fails", filename.c_str())); + } + if (params->mmcu != NULL) { + strncpy(firmware->mmcu, params->mmcu, sizeof(firmware->mmcu)); + } + if (params->frequency > 0) { + firmware->frequency = (uint32_t)params->frequency; + } + if (params->vcc > 0) { + firmware->vcc = (uint32_t)params->vcc; + } + if (params->avcc > 0) { + firmware->avcc = (uint32_t)params->avcc; + } + if (params->aref > 0) { + firmware->aref = (uint32_t)params->aref; + } + + // strncpy(firmware->mmcu, "atmega324p", sizeof(firmware->mmcu)); + // firmware->frequency = 20000000L; + if (firmware->frequency == 0) { + firmware->frequency = 8000000L; + } + if (firmware->vcc == 0) { + firmware->vcc = 5000; + } + if (firmware->avcc == 0) { + firmware->avcc = 5000; + } + if (firmware->aref == 0) { + firmware->aref = 2500; + } + if (firmware->mmcu[0] == 0) { + throw std::logic_error(error(AT, "missing cpu type, use --mmcu ... to set mmcu manually)", firmware->mmcu)); + } + + avr = avr_make_mcu_by_name(firmware->mmcu); + if (!avr) { + throw std::logic_error(error(AT, "avr_make_mcu_by_name() fails (mmcu=%s)", firmware->mmcu)); + } + if (params->gdbPort > 0) { + avr->gdb_port = params->gdbPort; + } else { + avr->gdb_port = 1234; + } + printf("init with port=%d, mmcu=%s, f=%u, vcc=%d, avcc=%d, aref=%d, pc=0x%04x\n", + avr->gdb_port, firmware->mmcu, firmware->frequency, firmware->vcc, firmware->avcc, firmware->aref, params->pc < 0 ? 0 : params->pc); + status.freqHz = firmware->frequency; + + if (avr_init(avr) != 0) { + throw std::logic_error(error(AT, "avr_init() fails")); + } + + + firmware->eeprom = (uint8_t *)malloc(1024); + for (int i = 0; i < 1024; i++) { + firmware->eeprom[i] = 0xff; + } + firmware->eeprom[0] = 0xf0; + firmware->eesize = 1024; + + avr_load_firmware(avr, firmware); + status.state = StateLoaded; + + avr->fuse[AVR_FUSE_LOW] = 0xe7; + avr->fuse[AVR_FUSE_HIGH] = 0xd8; + avr->fuse[AVR_FUSE_EXT] = 0xff; + avr->lockbits = 0xff; + + avr->gdb_port = 1234; + avr_gdb_init(avr); + if (params->pc >= 0) { + avr->pc = params->pc; + } + + pthread_mutex_unlock(&lock); + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } + addEvent(EventLoad); +} + +// enabled/disable character output on stdout in case of avr uart write +void SimAvr::setUartDumpEnabled (bool enabled) { + if (avr == NULL) { + throw std::logic_error(error(AT, "setUartDumpEnabled() fails because no avr available")); + } + uint32_t f = 0; + avr_ioctl(avr, AVR_IOCTL_UART_GET_FLAGS('0'), &f); + f = enabled ? f | AVR_UART_FLAG_STDIO : f & ~AVR_UART_FLAG_STDIO; + avr_ioctl(avr, AVR_IOCTL_UART_SET_FLAGS('0'), &f); + avr_ioctl(avr, AVR_IOCTL_UART_GET_FLAGS('1'), &f); + f = enabled ? f | AVR_UART_FLAG_STDIO : f & ~AVR_UART_FLAG_STDIO; + avr_ioctl(avr, AVR_IOCTL_UART_SET_FLAGS('1'), &f); +} + +void SimAvr::registerIoWrite (avr_io_addr_t addr, avrsim_io_write_callback_t callback) { + avr_register_io_write(avr, addr, (avr_io_write_t)callback, this); +} + +void SimAvr::setUartPtyEnabled (int uart, bool enable) { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "start() fails caused by mutex error")); + } + uart_pty_t *p = NULL; + try { + if (uart < 0 || uart > 1) { + throw std::logic_error(error(AT, "setUartPtyEnabled() fails (invalid uart %d)", uart)); + } + if (enable && uartPty[uart] != NULL) { + throw std::logic_error(error(AT, "enableUartPty() fails (uart %d already enabled)", uart)); + } + if (!enable && uartPty[uart] == NULL) { + throw std::logic_error(error(AT, "enableUartPty() fails (uart %d not enabled)", uart)); + } + if (avr == NULL) { + throw std::logic_error(error(AT, "enableUartPty() fails (avr not ready)")); + } + if (enable) { + p = (uart_pty_t *)malloc(sizeof(uart_pty_t)); + if (p == NULL) { + throw std::logic_error(error(AT, "enableUartPty() fails (malloc fails)")); + } + memset(p, 0, sizeof(uart_pty_t)); + // setenv("SIMAVR_UART_TAP", "1", 1); + uart_pty_init(avr, p); + uart_pty_connect(p, uart + '0'); + uartPty[uart] = p; + } else { + uart_pty_stop(uartPty[uart]); + free(uartPty[uart]); + uartPty[uart] = NULL; + } + pthread_mutex_unlock(&lock); + + } catch (std::exception& e) { + if (p != NULL) { + free(p); + } + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } +} + +void SimAvr::setUartPtyHook (int uart, void (*fromUart)(uint8_t), void (*toUart)(uint8_t)) { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "setUartPtyHook() fails caused by mutex error")); + } + try { + if (uart < 0 || uart > 1) { + throw std::logic_error(error(AT, "setUartPtyHook() fails (invalid uart %d)", uart)); + } + if (uartPty[uart] == NULL) { + throw std::logic_error(error(AT, "setUartPtyHook() fails (uart %d not enabled)", uart)); + } + uartPty[uart]->hook_from_uart = fromUart; + uartPty[uart]->hook_to_uart = toUart; + pthread_mutex_unlock(&lock); + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } +} + +const char *SimAvr::getUartPtyDeviceName (int uart) { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "start() fails caused by mutex error")); + } + try { + if (uart < 0 || uart > 1) { + throw std::logic_error(error(AT, "getUartPtyDeviceName() fails (invalid uart %d)", uart)); + } + uart_pty_t *p = uartPty[uart]; + pthread_mutex_unlock(&lock); + return p == NULL ? NULL : p->port[0].slavename; + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } +} + +const char *SimAvr::getTargetDeviceName () { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "start() fails caused by mutex error")); + } + try { + if (firmware == NULL) { + throw std::logic_error(error(AT, "getTargetDeviceName() fails (no firmware loaded)")); + } + pthread_mutex_unlock(&lock); + return firmware->mmcu; + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } +} + +uint32_t SimAvr::getTargetFrequency () { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "start() fails caused by mutex error")); + } + try { + if (firmware == NULL) { + throw std::logic_error(error(AT, "getTargetDeviceName() fails (no firmware loaded)")); + } + pthread_mutex_unlock(&lock); + return firmware->frequency; + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } +} + +void SimAvr::start () { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "start() fails caused by mutex error")); + } + try { + if (isShutdown) { + throw std::logic_error("start() not allowed after shutdown"); + } + if (avrRunThread != NULL) { + throw std::logic_error("simavr already started"); + } + if (avr == NULL) { + throw std::logic_error("avr not ready (check if load done)"); + } + syncTime[0] = !syncTime[1]; + avrRunThread = new std::thread(&SimAvr::avrRun, this); + pthread_mutex_unlock(&lock); + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } + addEvent(EventStart); +} + + +void SimAvr::stop () { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "stop() fails caused by mutex error")); + } + try { + if (avrRunThread == NULL) { + throw std::logic_error("simavr not started"); + } + cancelThread = true; + pthread_mutex_unlock(&lock); + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } + addEvent(EventStop); +} + +void SimAvr::setCommand (EnumSimAvrCommand cmd, void *param) { + if (command != ReadyForNewCommand) { + throw std::logic_error("another command pending"); + } + command = cmd; +} + +void SimAvr::addEvent (int event) { + struct timeval tp; + gettimeofday(&tp, NULL); + SimAvrEvent *p = (SimAvrEvent *)malloc(sizeof(SimAvrEvent)); + if (p != NULL) { + p->epochMillis = tp.tv_sec * 1000 + (long)tp.tv_usec / 1000; + p->event = event; + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "addEvent() fails caused by mutex error")); + } + try { + p->cycle = avr->cycle; + if (!isShutdown) { + events.push_back(p); + eventCount.notify(); + } + pthread_mutex_unlock(&lock); + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } + } +} + + +void SimAvr::setTimeSync (bool sync) { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "setTimeSync() fails caused by mutex error")); + } + try { + syncTime[1] = sync; + pthread_mutex_unlock(&lock); + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } +} + + +struct SimAvrEvent SimAvr::waitForEvent () { + eventCount.wait(); + + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "waitForEvent() fails caused by mutex error")); + } + try { + struct SimAvrEvent rv = { epochMillis: 0, event: EventUnknown }; + struct SimAvrEvent *p = NULL; + if (events.size() > 0) { + p = events.front(); + rv = *p; + if (p->event != EventShutdown) { + events.pop_front(); + free(p); + } + if (p->event == EventShutdown) { + cancelThread = true; + isShutdown = true; + } + } + pthread_mutex_unlock(&lock); + return rv; + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } +} + +const char *SimAvr::eventText (EnumSimAvrEvent event) { + switch (event) { + case EventUnknown: return "Unknown"; + case EventShutdown: return "Shutdown"; + case EventLoad: return "Load"; + case EventStart: return "Start"; + case EventStop: return "Stop"; + default: return NULL; + } +} + +struct SimAvrStatus SimAvr::getStatus () { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "getStatus() fails caused by mutex error")); + } + struct SimAvrStatus rv = status; + pthread_mutex_unlock(&lock); + return rv; +} + +void SimAvr::printCyclesAndElapsedTime () { + uint64_t time = avr->cycle * 1000000000L / avr->frequency; + uint16_t nanos = time % 1000; time = time / 1000; + uint16_t micros = time % 1000; time = time / 1000; + uint16_t millis = time % 1000; time = time / 1000; + uint16_t seconds = time % 1000; time = time / 1000; + printf("cycle %" PRIu64 " = %ds %03dms %03dµs %03dns", avr->cycle, seconds, millis, micros, nanos); +} + +void SimAvr::avrRun () { + long cnt = 0; + int lastAvrState = -1; + _avr_sp_set(avr, 0); + while (1) { + try { + if (avr->state != lastAvrState) { + switch (avr->state) { + case cpu_Stopped: { + printf("\ncpu stopped at 0x%04x on ", avr->pc); + printCyclesAndElapsedTime(); + char sfr[9]; + sfr[7] = avr->sreg[0] ? 'C' : '-'; + sfr[6] = avr->sreg[1] ? 'Z' : '-'; + sfr[5] = avr->sreg[2] ? 'N' : '-'; + sfr[4] = avr->sreg[3] ? 'V' : '-'; + sfr[3] = avr->sreg[4] ? 'S' : '-'; + sfr[2] = avr->sreg[5] ? 'H' : '-'; + sfr[1] = avr->sreg[6] ? 'T' : '-'; + sfr[0] = avr->sreg[7] ? 'I' : '-'; + sfr[8] = 0; + printf(" SFR: %s\n ", sfr); + uint16_t x = 0, y = 0, z = 0; + for (int i = 0; i < 32; i++) { + uint8_t b = avr->data[i]; + printf(" r%02d=%02x", i, b); + switch (i) { + case 0x0f: printf("\n "); break; + case 0x1a: x = (x & 0xff00) | b; break; + case 0x1b: x = (x & 0x00ff) | (b << 8); break; + case 0x1c: y = (y & 0xff00) | b; break; + case 0x1d: y = (y & 0x00ff) | (b << 8); break; + case 0x1e: z = (z & 0xff00) | b; break; + case 0x1f: z = (z & 0x00ff) | (b << 8); break; + } + } + printf("\n X=0x%04x Y=0x%04x Z=0x%04x\n", x, y, z); + + uint16_t sp = _avr_sp_get(avr); + printf(" Stack (SP=0x%04x)", sp); + int printHeader = 1; + for (int i = 0; i < 16; i++) { + uint16_t addr = sp + 1 + i; + if (addr <= avr->ioend) { continue; } + if (addr > avr->ramend) { break; } + if (printHeader) { + printf(" -> SRAM 0x%04x:", addr); + printHeader = 0; + } + uint8_t b = avr_core_watch_read(avr, addr); + printf(" %02x", b); + + } + printf(printHeader ? "\n" : "\n"); + + printf(" Arduino LED L: "); + printf((avr->data[0x24] & 0x20) && (avr->data[0x25] & 0x20) ? "ON\n" : "OFF\n"); + + printf("\n"); + break; + } + case cpu_Sleeping: printf("cpu enter sleep mode at cycle %" PRIu64 "\n", avr->cycle); break; + case cpu_Running: printf("cpu starts running at cycle %" PRIu64 "\n", avr->cycle); break; + case cpu_Step: printf("cpu step\n"); break; + case cpu_StepDone: printf("cpu step done\n"); break; + case cpu_Done: printf("cpu done\n"); break; + case cpu_Crashed: printf("cpu crashed\n"); break; + default: printf("cpu enter unknown mode at cycle %" PRIu64 "\n", avr->cycle); break; + } + lastAvrState = avr->state; + } + + if (startParameters != NULL) { + switch (startParameters->board) { + case BoardNano: { + static int8_t ledL = -1; // pin floating + uint8_t ddrb = avr->data[0x24]; + uint8_t portb = avr->data[0x25]; + int8_t nextLedL = -1; + if (ddrb & 0x20) { + nextLedL = portb & 0x20 ? 1 : 0; + } + if (nextLedL != ledL) { + ledL = nextLedL; + printCyclesAndElapsedTime(); + printf(": LED L = %c\n", ledL ? 'X' : '.'); + } + break; + } + case BoardSure: { + static int8_t led[4] = { -1, -1, -1, -1 }; // pin floating + uint8_t ddra = avr->data[0x3a]; + uint8_t porta = avr->data[0x3b]; + int change = 0; + for (int i = 0; i < 4; i++) { + int8_t nextLed = -1; + if (ddra & (1 << i)) { + nextLed = porta & (1 << i) ? 0 : 1; + } + if (nextLed != led[i]) { + change = 1; + led[i] = nextLed; + } + } + if (change) { + printCyclesAndElapsedTime(); printf(": "); + printf(" LED PA[3210] ="); + for (int i = 3; i >= 0; i--) { + printf(" %c", led[i] ? 'X' : '.'); + } + printf("\n"); + } + break; + } + case BoardEWS1: { + static int8_t led = -1; // pin floating + uint8_t ddrb = avr->data[0x24]; + uint8_t portb = avr->data[0x25]; + int8_t nextLed = -1; + if (ddrb & 0x01) { + nextLed = portb & 0x01 ? 1 : 0; + } + if (nextLed != led) { + led = nextLed; + printCyclesAndElapsedTime(); + printf(": LED1 (PB0) = %c\n", led ? 'X' : '.'); + } + break; + } + default: break; + } + } + + if (cnt <= 0) { + // usleep(10000); + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "avrRun() fails caused by mutex error (1)")); + } + try { + status.cycle = avr->cycle; + status.state = StateRunning; + status.running = true; + switch (avr->state) { + case cpu_Done: status.state = StateDone; break; + case cpu_Running: status.state = StateRunning; break; + case cpu_Crashed: status.state = StateCrashed; break; + default: status.state = StateOthers; break; + } + if (cancelThread) { + cnt = -1; + cancelThread = false; + } else { + if (syncTime[0] != syncTime[1]) { + syncTime[0] = syncTime[1]; + if (syncTime[0]) { + cyclesOnSyncStart = avr->cycle; + struct timeval tp; + gettimeofday(&tp, NULL); + timeMicrosOnSyncStart = tp.tv_usec + (uint64_t)tp.tv_sec * 1000000L; + } else { + cyclesOnSyncStart = -1; + timeMicrosOnSyncStart = 0; + } + } + if (syncTime[0]) { + uint64_t ucMicros = (uint64_t)(status.cycle - cyclesOnSyncStart) * 1000000L / status.freqHz ; + struct timeval tp; + gettimeofday(&tp, NULL); + const uint64_t timeMicros = tp.tv_usec + (uint64_t)tp.tv_sec * 1000000L - timeMicrosOnSyncStart; + + if (ucMicros > 3000000) { + ucMicros++; + } + + int64_t dt = ucMicros - timeMicros; + if (dt > 0) { + int us = dt > INT_MAX ? INT_MAX : (int)dt; + if (us > 1000) { + timeval ts; + ts.tv_sec = 0; + ts.tv_usec = us; + select(0, 0, 0, 0, &ts); + } + } + } + } + if (avr->state == cpu_Done) { + cnt = -1; + } else if (avr->state == cpu_Crashed) { + throw std::logic_error(error(AT, "avr state is cpu_Crashed")); + } + pthread_mutex_unlock(&lock); + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } + } + + if (avr->state == cpu_Stopped) { + timeval ts; + ts.tv_sec = 0; + ts.tv_usec = 1000; + select(0, 0, 0, 0, &ts); + } + + if (cnt < 0) { + cyclesOnSyncStart = -1; + timeMicrosOnSyncStart = 0; + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "avrRun() fails caused by mutex error (2)")); + } + try { + if (avrRunThread != NULL) { + avrRunThread->detach(); + delete avrRunThread; + avrRunThread = NULL; + } + pthread_mutex_unlock(&lock); + return; + } catch (std::exception& e) { + pthread_mutex_unlock(&lock); + status.state = StateError; + throw; + } + + } else if (++cnt >= 100000) { + cnt = 0; + } + + if (command != ReadyForNewCommand) { + switch (command) { + case CommandStatus: { + printCyclesAndElapsedTime(); + printf("\n"); + break; + } + case CommandInterrupt: { + if (avr->state == cpu_Running) { + avr->state = cpu_Stopped; + } + break; + } + case CommandContinue: { + if (avr->state == cpu_Stopped) { + avr->state = cpu_Running; + } + break; + } + case CommandStack: { + uint16_t sp = _avr_sp_get(avr); + printf("Stack: SP=0x%04x:\n", sp); + for (uint16_t addr = ((sp + 1) / 16) * 16; addr <= avr->ramend; addr++) { + if (addr % 16 == 0) { + printf(" 0x%04x:", addr); + } + if (addr % 4 == 0) { + printf(" "); + } + if (addr <= sp) { + printf(" "); + } else { + uint8_t b = avr_core_watch_read(avr, addr); + printf(" %02x", b); + } + if (addr % 16 == 15) { + printf("\n"); + } + } + printf("\n"); + break; + } + + default: break; + } + command = ReadyForNewCommand; + addEvent(EventCommandExecuted); + } + + avr_run(avr); + + } catch (std::exception& e) { + status.state = StateError; + cyclesOnSyncStart = -1; + timeMicrosOnSyncStart = 0; + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "avrRun() fails caused by mutex error (2)")); + } + try { + if (avrRunThread != NULL) { + avrRunThread->detach(); + delete avrRunThread; + avrRunThread = NULL; + } + pthread_mutex_unlock(&lock); + throw; + } catch (std::exception& e) { + pthread_mutex_unlock(&lock); + status.state = StateError; + throw; + } + + } + } +} + diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/simavr.h b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/simavr.h new file mode 100644 index 0000000..e1455b7 --- /dev/null +++ b/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/simavr.h @@ -0,0 +1,132 @@ +#ifndef SIMAVR_H +#define SIMAVR_H + +#include "semaphore.h" +#include "parts/uart_pty.h" + +#include <simavr/sim_avr.h> +#include <simavr/sim_elf.h> +#include <simavr/sim_io.h> + +#include <string> +#include <thread> +#include <list> + +typedef enum { + BoardUnknown = 0, + BoardNano, + BoardSure, + BoardEWS1 +} EnumStartParameterBoard; + + +struct StartParameters { + char *filename; + int gdbPort; + int64_t frequency; + const char *mmcu; + EnumStartParameterBoard board; + int32_t pc; + int32_t vcc; + int32_t avcc; + int32_t aref; +}; + +enum SimAvrState { + StateInit = 0, + StateError = 1, + StateLoaded = 10, + StateRunning = 11, + StateDone = 12, + StateCrashed = 20, + StateOthers = 99, + StateUnknown = 100 +}; + +typedef enum { + EventUnknown = 0, + EventShutdown = -1, + EventLoad = -2, + EventStart = -3, + EventStop = -4, + EventCommandExecuted = -5 +} EnumSimAvrEvent; + +typedef enum { + ReadyForNewCommand = 0, + CommandStatus, + CommandInterrupt, + CommandContinue, + CommandStack +} EnumSimAvrCommand; + +struct SimAvrStatus { + long long freqHz; + long long cycle; + enum SimAvrState state; + bool running; +}; + +struct SimAvrEvent { + long long epochMillis; + long long cycle; + int event; +}; + + +class SimAvr; +typedef void (*avrsim_io_write_callback_t)(avr_t *avr, avr_io_addr_t addr, uint8_t value, SimAvr *simavr); + +class SimAvr { + +public: + SimAvr (); + ~SimAvr (); + + struct SimAvrStatus getStatus (); + struct SimAvrEvent waitForEvent (); + const char *eventText (EnumSimAvrEvent event); + +public: + void load (struct StartParameters *params); + void shutdown (); + void start (); + void stop (); + void addEvent (int event); + void setUartDumpEnabled (bool enabled); + void setUartPtyEnabled (int uart, bool enabled); + void setUartPtyHook (int uart, void (*fromUart)(uint8_t), void (*toUart)(uint8_t)); + void registerIoWrite (avr_io_addr_t addr, avrsim_io_write_callback_t callback); + + const char *getTargetDeviceName (); + uint32_t getTargetFrequency (); + const char *getUartPtyDeviceName (int uart); + + void avrRun (); + void setLed (bool on); + void setTimeSync (bool sync); + void setCommand (EnumSimAvrCommand cmd, void *param); + +private: + elf_firmware_t *firmware = NULL; + avr_t *avr = NULL;; + StartParameters *startParameters = NULL;; + pthread_mutex_t lock; + std::list<struct SimAvrEvent *> events; + EnumSimAvrCommand command; + struct SimAvrStatus status; + bool cancelThread = false; + bool isShutdown = false; + bool syncTime[2] = { false, true }; + std::thread *avrRunThread = NULL; + long cyclesOnSyncStart = -1; + uint64_t timeMicrosOnSyncStart = 0; + Semaphore eventCount; + uart_pty_t *uartPty[2] = { NULL, NULL }; + void printCyclesAndElapsedTime (); +}; + + + + +#endif // SIMAVR_H \ No newline at end of file diff --git a/examples/simuc/sim/vcd/.gitkeep b/examples/simuc/sim/vcd/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/simuc/src/main.cpp b/examples/simuc/src/main.cpp new file mode 100644 index 0000000..0af4178 --- /dev/null +++ b/examples/simuc/src/main.cpp @@ -0,0 +1,190 @@ +#include <stdio.h> +#include <unistd.h> +#include <string.h> + +#include "sim/sim.h" +#include "simavr/simavr.h" + +void printHelp () { + printf("simuc V1.0.0 (%s,%s)\n", __DATE__, __TIME__); + printf("usage: simuc [options] elf-file\n\n"); + printf(" available options:\n"); + printf(" --board ... set board (arduino, sure, evws1)\n"); + printf(" --sync sync elapsed µC-time with real time\n\n"); + printf(" --mmcu ... set target device type\n"); + printf(" --frequency ... set target frequency in Hz\n"); + printf(" --pc ... set start program counter (default is 0)\n"); + printf(" --vcc ... set voltage VCC in Volt\n"); + printf(" --avcc ... set voltage AVCC in Volt\n"); + printf(" --aref ... set voltage AREF in Volt\n\n"); + printf(" example:\n"); + printf(" simuc --mmcu atmega328p --frequency 16000000 --pc 0x7000 a.out\n\n"); + printf(" simuc --board arduino a.out\n\n"); +} + +int main (int argc, char **argv) { + struct StartParameters params = { + filename: NULL, + gdbPort: -1, + frequency: -1, + mmcu: NULL, + board: BoardUnknown, + vcc: -1, + avcc: -1, + aref: -1 + }; + + if (argc <= 1) { + printHelp(); + return 1; + } + + for (int i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + if (strcmp(argv[i], "--help") == 0) { + printHelp(); + return 0; + } else if (strcmp(argv[i], "--board") == 0 && argc >= (i + 1)) { + i++; + if (strcmp("arduino", argv[i]) == 0) { + params.board = BoardNano; + params.mmcu = "atmega328p"; + params.frequency = 16000000; + params.vcc = 5000; + params.avcc = 5000; + params.aref = 2500; + } else if (strcmp("sure", argv[i]) == 0) { + params.board = BoardSure; + params.mmcu = "atmega16"; + params.frequency = 12000000; + params.vcc = 5000; + params.avcc = 5000; + params.aref = 2500; + } else if (strcmp("evws1", argv[i]) == 0) { + params.board = BoardEWS1; + params.mmcu = "atmega324p"; + params.frequency = 20000000; + params.vcc = 5000; + params.avcc = 5000; + params.aref = 2500; + } else { + fprintf(stderr, "ERROR: invalid board %s, use --help to show usage\n\n", argv[i]); + return 1; + } + + } else if (strcmp(argv[i], "--mmcu") == 0) { + params.mmcu = argv[++i]; + } else if (strcmp(argv[i], "--port") == 0) { + sscanf(argv[++i], "%d", ¶ms.gdbPort); + } else if (strcmp(argv[i], "--frequency") == 0) { + sscanf(argv[++i], "%" PRIu64, ¶ms.frequency); + } else if (strcmp(argv[i], "--pc") == 0) { + i++; + if (argv[i][0] == '0' && argv[i][1] == 'x') { + sscanf(&argv[i][2], "%x", ¶ms.pc); + } else { + sscanf(argv[++i], "%d", ¶ms.pc); + } + } else if (strcmp(argv[i], "--vcc") == 0) { + sscanf(argv[++i], "%d", ¶ms.vcc); + } else if (strcmp(argv[i], "--avcc") == 0) { + sscanf(argv[++i], "%d", ¶ms.avcc); + } else if (strcmp(argv[i], "--aref") == 0) { + sscanf(argv[++i], "%d", ¶ms.aref); + } else { + fprintf(stderr, "ERROR: invalid option %s, use --help to show usage\n\n", argv[i]); + return 1; + } + continue; + } + params.filename = argv[i]; + break; + } + + if (params.filename == NULL) { + printf("ERROR: missing target elf file, use --help to show usage\n\n"); + return 1; + } + + init(¶ms); + if (errno == 1) { + return 1; + } + printf("init done - press key to start\n"); + getchar(); + start(); + + // int cnt = 0; + char *line = NULL; + size_t size = 0; + while (1) { + // struct SimAvrEvent ev = waitForEvent(); + // printf("%10.03lf: event %s (%d) received \r", ev.cycle / 20E6, eventText((EnumSimEvent)ev.event), ev.event); + // fflush(stdout); + // if (++cnt == 10000) { + // stop(); + // shutdown(); + // break; + // } + + if (getline(&line, &size, stdin) > 0) { + const char *commands[] = { "interrupt", "continue", "stack" }; + try { + int foundIndex = -1; + int foundCnt = 0; + size_t length = strlen(line) - 1; + if (length > 0 && size >= (length + 1)) { + line[length] = 0; + for (long unsigned int i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) { + const char *cmd = commands[i]; + size_t max = strlen(cmd); + bool ok = true; + for (size_t j = 0; j < length; j++) { + if (j >= max || line[j] != cmd[j]) { + ok = false; + break; + } + } + if (ok) { + foundCnt++; + foundIndex = i; + } + } + } + // printf("foundCnt=%d foundIndex=%d command=%s\n", foundCnt, foundIndex, foundIndex >= 0 ? commands[foundIndex] : ""); + if (foundCnt == 1 || length == 0) { + setCommand((EnumSimAvrCommand)(foundCnt > 0 ? foundIndex + 2 : 1), NULL); + while (1) { + struct SimAvrEvent ev = waitForEvent(); + if (ev.event == EventCommandExecuted) { + break; + } + } + + } else { + printf("invalid command, valid commands are <Enter> for status and:"); + for (long unsigned int i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) { + printf(" %s", commands[i]); + } + printf("\n"); + continue; + } + + } catch (std::exception& e) { + printf("ERROR\n"); + } + + } + + } + while (1) { + struct SimAvrEvent ev = waitForEvent(); + printf("event %s (%d) received\n", eventText((EnumSimEvent)ev.event), ev.event); + if (ev.event == EventShutdown) { + break; + } + } + + usleep(10000); + return 0; +} \ No newline at end of file diff --git a/examples/simuc/src/sim/error.cpp b/examples/simuc/src/sim/error.cpp new file mode 100644 index 0000000..f59ddbd --- /dev/null +++ b/examples/simuc/src/sim/error.cpp @@ -0,0 +1,18 @@ +#include "error.h" +#include <stdarg.h> + +std::string error (const char *location, const char *format, ...) { + va_list args; + va_start (args, format); + int length = std::vsnprintf (NULL, 0, format, args); + va_end (args); + + va_start (args, format); + char* str = new char[length + 1]; // one more character for null terminator + std::vsnprintf (str, length + 1, format, args); + std::string rv = "Error at " + std::string(location) + " -> " + str; + delete[] str; + va_end (args); + + return rv; +} diff --git a/examples/simuc/src/sim/error.h b/examples/simuc/src/sim/error.h new file mode 100644 index 0000000..80d5682 --- /dev/null +++ b/examples/simuc/src/sim/error.h @@ -0,0 +1,11 @@ +#ifndef ERROR_H +#define ERROR_H + +#include <string> + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) +#define AT __FILE__ ":" TOSTRING(__LINE__) +std::string error (const char *location, const char *format, ...); + +#endif // ERROR_H diff --git a/examples/simuc/src/sim/sim.cpp b/examples/simuc/src/sim/sim.cpp new file mode 100644 index 0000000..32a23b6 --- /dev/null +++ b/examples/simuc/src/sim/sim.cpp @@ -0,0 +1,282 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <libgen.h> +#include <errno.h> +#include <stdarg.h> + +#include <stdexcept> +#include <string> +#include <iostream> +#include <vector> + +#include <GL/glut.h> +#include <pthread.h> +#include <simavr/sim_avr.h> +#include <simavr/sim_elf.h> +#include <simavr/sim_gdb.h> + +#include "sim.h" +#include "error.h" + + + +// https://github.com/java-native-access/jna/blob/master/www/CallbacksAndClosures.md#callbacks-function-pointers-and-closures + + +int SIGUSR1 = 30; + +// avr_t * avr = NULL; +SimAvr simavr; +std::string lastErrorMessage; + +static int fdStdOut = -1, fdStdErr = -1; +// static fpos_t posStdOut, posStdErr; + +void switchStdOut (const char * filename) { + fflush(stdout); + // fgetpos(stdout, &posStdOut); + if (filename == NULL) { + int fd = open("/dev/null", O_WRONLY); + fdStdOut = dup2(fd, fileno(stdout)); + } else { + fdStdOut = dup(fileno(stdout)); + } +} + +void switchStdErr (const char * filename) { + fflush(stderr); + // fgetpos(stderr, &posStdErr); + if (filename == NULL) { + int fd = open("/dev/null", O_WRONLY); + fdStdErr = dup2(fd, fileno(stderr)); + } else { + fdStdErr = dup(fileno(stderr)); + } +} + +void revertStdErrOut () { + if (fdStdOut >= 0) { + fflush(stdout); + dup2(fdStdOut, fileno(stdout)); + close(fdStdOut); + fdStdOut = -1; + clearerr(stdout); + // fsetpos(stdout, &posStdOut); + } + if (fdStdErr >= 0) { + fflush(stderr); + dup2(fdStdErr, fileno(stderr)); + close(fdStdErr); + fdStdErr = -1; + clearerr(stderr); + // fsetpos(stderr, &posStdErr); + } +} + +const char * lastError () { + return lastErrorMessage.c_str(); +} + + +// static void handleWritePortB (struct avr_t * avr, __attribute__((unused)) avr_io_addr_t addr, uint8_t v, SimAvr *simavr) { +// static int value = 0; +// if (value != v) { +// value = v; +// if (simavr != NULL) { +// if ((value << PORTB0) != 0) { +// simavr->addEvent(EventLedOn); +// } else { +// simavr->addEvent(EventLedOff); +// } +// } +// } +// } + +std::vector<uint8_t> gdbFromUartBuffer; +std::vector<uint8_t> gdbToUartBuffer; + +__attribute__((unused)) static void fromGdbUart (uint8_t b) { + static int cnt = 0; + if (b == '$') { + cnt = 1; + } else if (cnt > 0 && b == '#') { + cnt = -1; + } else if (cnt < 0) { + cnt--; + } + gdbFromUartBuffer.push_back(b); + + if (cnt <= -3 || (cnt == 0 && b == '+')) { + printf("\n\rgdb-uart OUT -> "); + for (uint8_t c : gdbFromUartBuffer) { + putchar(c); + } + printf("\n\r"); + gdbFromUartBuffer.clear(); + } +} + +__attribute__((unused)) static void toGdbUart (uint8_t b) { + static int cnt = 0; + if (b == '$') { + cnt = 1; + } else if (cnt > 0 && b == '#') { + cnt = -1; + } else if (cnt < 0) { + cnt--; + } + gdbToUartBuffer.push_back(b); + + if (cnt <= -3 || (cnt == 0 && b == '+')) { + printf("\n\rgdb-uart IN <-- "); + for (uint8_t c : gdbToUartBuffer) { + putchar(c); + } + printf("\n\r"); + gdbToUartBuffer.clear(); + } + +} + +void init (struct StartParameters *param) { + try { + // switchStdOut(NULL); + // switchStdErr(NULL); + // std::cout.rdbuf(0); + // std::cerr.rdbuf(0); + const char *filename = param->filename != NULL + ? param->filename + // : "../gdb-stub-sm_atmega324p/sim/dist/gdb-stub-sm_atmega324p.axf"; + : "../gdb-stub-sm_atmega324p/sim/dist/gdb-stub-sm_atmega324p.axf"; + printf("firmware file \"%s\"\n", filename); + simavr.load(param); + if (strcmp(simavr.getTargetDeviceName(), "atmega324p") != 0) { + std::logic_error(error(AT, "invalid target device %s", simavr.getTargetDeviceName())); + } + + simavr.setUartDumpEnabled(false); + // simavr.registerIoWrite(PORTB, handleWritePortB); + simavr.setUartPtyEnabled(0, true); + int uartCnt = 1; + if (strcmp(simavr.getTargetDeviceName(), "atmega324p") == 0) { + simavr.setUartPtyEnabled(1, true); + simavr.setUartPtyHook(1, fromGdbUart, toGdbUart); + uartCnt = 2; + } + // printf("uart0 -> picocom --imap lfcrlf -b 115200 %s\n", simavr.getUartPtyDeviceName(0)); + // printf("uart1 -> picocom --imap lfcrlf -b 115200 %s\n", simavr.getUartPtyDeviceName(1)); + + printf("device %s\n", simavr.getTargetDeviceName()); + printf("frequency %.2lfMHz\n", simavr.getTargetFrequency() / 1E6); + + for (int i = 0; i < uartCnt; i++) { + char s[128]; + snprintf(s, 128, "/tmp/sim-megaavr-%s-uart%1d", simavr.getTargetDeviceName(), i); + FILE *f = fopen(s, "w"); + if (f == NULL) { + std::logic_error(error(AT, "cannot write file %s", s)); + } + printf("uart%1d -> picocom %s (see file %s)\n", i, simavr.getUartPtyDeviceName(i), s); + fprintf(f, "%s\n", simavr.getUartPtyDeviceName(i)); + fclose(f); + } + + } catch (std::exception& e) { + lastErrorMessage = "init() fails, caused by " + std::string(e.what()); + std::cerr << lastErrorMessage << "\n"; + errno = 1; + } +} + +void shutdown () { + try { + simavr.shutdown(); + } catch (std::exception& e) { + lastErrorMessage = "shutdown() fails, caused by " + std::string(e.what()); + std::cerr << lastErrorMessage << "\n"; + errno = 1; + } +} + +void start () { + try { + simavr.start(); + + } catch (std::exception& e) { + lastErrorMessage = "start() fails, caused by " + std::string(e.what()); + std::cerr << lastErrorMessage << "\n"; + errno = 1; + } +} + +void stop () { + try { + simavr.stop(); + + } catch (std::exception& e) { + lastErrorMessage = "stop() fails, caused by " + std::string(e.what()); + std::cerr << lastErrorMessage << "\n"; + errno = 1; + } +} + +void setCommand (EnumSimAvrCommand cmd, void *param) { + try { + simavr.setCommand(cmd, param); + + } catch (std::exception& e) { + lastErrorMessage = "setCommand(..) fails, caused by " + std::string(e.what()); + std::cerr << lastErrorMessage << "\n"; + errno = 1; + throw e; + } + +} + +void addEvent (EnumSimEvent event) { + try { + simavr.addEvent(event); + + } catch (std::exception& e) { + lastErrorMessage = "addEvent(..) fails, caused by " + std::string(e.what()); + std::cerr << lastErrorMessage << "\n"; + errno = 1; + } +} + +void setTimeSync (bool sync) { + try { + simavr.setTimeSync(sync); + + } catch (std::exception& e) { + lastErrorMessage = "setTimeSync() fails, caused by " + std::string(e.what()); + std::cerr << lastErrorMessage << "\n"; + errno = 1; + } +} + +struct SimAvrStatus getStatus () { + return simavr.getStatus();; +} + +struct SimAvrEvent waitForEvent () { + return simavr.waitForEvent(); +} + +const char *eventText (EnumSimEvent event) { + const char *rv = simavr.eventText((EnumSimAvrEvent)event); + if (rv != NULL) { + return rv; + } else { + switch (event) { + case EventLedOff: return "LedOff"; + case EventLedOn: return "LedOn"; + default: return "?"; + } + } +} diff --git a/examples/simuc/src/sim/sim.h b/examples/simuc/src/sim/sim.h new file mode 100644 index 0000000..d980f26 --- /dev/null +++ b/examples/simuc/src/sim/sim.h @@ -0,0 +1,43 @@ +#ifndef SIM_H +#define SIM_H + +#include "../simavr/simavr.h" + +// #define _AVR_IO_H_ +// #define _SFR_IO8(reg) (0x20 + reg) +// #include "iom324p.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + EventInterrupt = 1, + EventLedOff = 10, + EventLedOn = 11 +} EnumSimEvent; + + + +extern void init (struct StartParameters *param); +extern void shutdown (); +extern const char * lastError (); +extern void start (); +extern void stop (); +extern void setCommand (EnumSimAvrCommand cmd, void *param); +extern void addEvent (EnumSimEvent event); +extern void setTimeSync (bool sync); +extern struct SimAvrStatus getStatus (); +extern struct SimAvrEvent waitForEvent (); +extern const char *eventText (EnumSimEvent event); + +typedef void (*NotificationListener)(char *, int); +void callbackTrigger(const NotificationListener l); +void getDeviceRandomStatus(char *answer, int sizeOfChars); +int randNum( int min, int max); + +#ifdef __cplusplus +} +#endif + +#endif // SIM_H diff --git a/examples/simuc/src/simavr/parts/fifo_declare.h b/examples/simuc/src/simavr/parts/fifo_declare.h new file mode 100644 index 0000000..8a3b2fb --- /dev/null +++ b/examples/simuc/src/simavr/parts/fifo_declare.h @@ -0,0 +1,189 @@ +/* + fido_declare.h + Copyright (C) 2003-2012 Michel Pollet <buserror@gmail.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* + * FIFO helpers, aka circular buffers + * + * these macros define accessories for FIFOs of any name, type and + * any (power of two) size + */ + +#ifndef __FIFO_DECLARE__ +#define __FIFO_DECLARE__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + doing a : + DECLARE_FIFO(uint8_t, myfifo, 128); + + will declare : + enum : myfifo_overflow_f + type : myfifo_t + functions: + // write a byte into the fifo, return 1 if there was room, 0 if there wasn't + int myfifo_write(myfifo_t *c, uint8_t b); + // reads a byte from the fifo, return 0 if empty. Use myfifo_isempty() to check beforehand + uint8_t myfifo_read(myfifo_t *c); + int myfifo_isfull(myfifo_t *c); + int myfifo_isempty(myfifo_t *c); + // returns number of items to read now + uint16_t myfifo_get_read_size(myfifo_t *c); + // read item at offset o from read cursor, no cursor advance + uint8_t myfifo_read_at(myfifo_t *c, uint16_t o); + // write b at offset o compared to current write cursor, no cursor advance + void myfifo_write_at(myfifo_t *c, uint16_t o, uint8_t b); + + In your .c you need to 'implement' the fifo: + DEFINE_FIFO(uint8_t, myfifo) + + To use the fifo, you must declare at least one : + myfifo_t fifo = FIFO_NULL; + + while (!myfifo_isfull(&fifo)) + myfifo_write(&fifo, 0xaa); + .... + while (!myfifo_isempty(&fifo)) + b = myfifo_read(&fifo); + */ + +#include <stdint.h> + +#if __AVR__ +#define FIFO_CURSOR_TYPE uint8_t +#define FIFO_BOOL_TYPE char +#define FIFO_INLINE +#define FIFO_SYNC +#endif + +#ifndef FIFO_CURSOR_TYPE +#define FIFO_CURSOR_TYPE uint16_t +#endif +#ifndef FIFO_BOOL_TYPE +#define FIFO_BOOL_TYPE int +#endif +#ifndef FIFO_INLINE +#define FIFO_INLINE inline +#endif + +/* We should not need volatile */ +#ifndef FIFO_VOLATILE +#define FIFO_VOLATILE +#endif +#ifndef FIFO_SYNC +#define FIFO_SYNC __sync_synchronize() +#endif + +#ifndef FIFO_ZERO_INIT +#define FIFO_ZERO_INIT {0} +#endif +#define FIFO_NULL { FIFO_ZERO_INIT, 0, 0, 0 } + +/* New compilers don't like unused static functions. However, + * we do like 'static inlines' for these small accessors, + * so we mark them as 'unused'. It stops it complaining */ +#ifdef __GNUC__ +#define FIFO_DECL static __attribute__ ((unused)) +#else +#define FIFO_DECL static +#endif + +#define DECLARE_FIFO(__type, __name, __size) \ +enum { __name##_overflow_f = (1 << 0) }; \ +enum { __name##_fifo_size = (__size) }; \ +typedef struct __name##_t { \ + __type buffer[__name##_fifo_size]; \ + FIFO_VOLATILE FIFO_CURSOR_TYPE read; \ + FIFO_VOLATILE FIFO_CURSOR_TYPE write; \ + FIFO_VOLATILE uint8_t flags; \ +} __name##_t + +#define DEFINE_FIFO(__type, __name) \ +FIFO_DECL FIFO_INLINE FIFO_BOOL_TYPE __name##_write(__name##_t * c, __type b)\ +{\ + FIFO_CURSOR_TYPE now = c->write;\ + FIFO_CURSOR_TYPE next = (now + 1) & (__name##_fifo_size-1);\ + if (c->read != next) { \ + c->buffer[now] = b;\ + FIFO_SYNC; \ + c->write = next;\ + return 1;\ + }\ + return 0;\ +}\ +FIFO_DECL FIFO_INLINE FIFO_BOOL_TYPE __name##_isfull(__name##_t *c)\ +{\ + FIFO_CURSOR_TYPE next = (c->write + 1) & (__name##_fifo_size-1);\ + return c->read == next;\ +}\ +FIFO_DECL FIFO_INLINE FIFO_BOOL_TYPE __name##_isempty(__name##_t * c)\ +{\ + return c->read == c->write;\ +}\ +FIFO_DECL FIFO_INLINE __type __name##_read(__name##_t * c)\ +{\ + __type res = FIFO_ZERO_INIT; \ + FIFO_CURSOR_TYPE read = c->read;\ + if (read == c->write)\ + return res;\ + res = c->buffer[read];\ + FIFO_SYNC; \ + c->read = (read + 1) & (__name##_fifo_size-1);\ + return res;\ +}\ +FIFO_DECL FIFO_INLINE FIFO_CURSOR_TYPE __name##_get_read_size(__name##_t *c)\ +{\ + return ((c->write + __name##_fifo_size) - c->read) & (__name##_fifo_size-1);\ +}\ +FIFO_DECL FIFO_INLINE FIFO_CURSOR_TYPE __name##_get_write_size(__name##_t *c)\ +{\ + return (__name##_fifo_size-1) - __name##_get_read_size(c);\ +}\ +FIFO_DECL FIFO_INLINE void __name##_read_offset(__name##_t *c, FIFO_CURSOR_TYPE o)\ +{\ + FIFO_SYNC; \ + c->read = (c->read + o) & (__name##_fifo_size-1);\ +}\ +FIFO_DECL FIFO_INLINE __type __name##_read_at(__name##_t *c, FIFO_CURSOR_TYPE o)\ +{\ + return c->buffer[(c->read + o) & (__name##_fifo_size-1)];\ +}\ +FIFO_DECL FIFO_INLINE void __name##_write_at(__name##_t *c, FIFO_CURSOR_TYPE o, __type b)\ +{\ + c->buffer[(c->write + o) & (__name##_fifo_size-1)] = b;\ +}\ +FIFO_DECL FIFO_INLINE void __name##_write_offset(__name##_t *c, FIFO_CURSOR_TYPE o)\ +{\ + FIFO_SYNC; \ + c->write = (c->write + o) & (__name##_fifo_size-1);\ +}\ +FIFO_DECL FIFO_INLINE void __name##_reset(__name##_t *c)\ +{\ + FIFO_SYNC; \ + c->read = c->write = c->flags = 0;\ +}\ +struct __name##_t + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/examples/simuc/src/simavr/parts/uart_pty.c b/examples/simuc/src/simavr/parts/uart_pty.c new file mode 100644 index 0000000..a283fef --- /dev/null +++ b/examples/simuc/src/simavr/parts/uart_pty.c @@ -0,0 +1,371 @@ +/* + uart_pty.c + + Copyright 2008, 2009 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <simavr/sim_network.h> +#include <stdlib.h> +#include <pthread.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <signal.h> +#ifdef __APPLE__ +#include <util.h> +#elif defined (__FreeBSD__) +#include <sys/types.h> +#include <sys/ioctl.h> +#include <termios.h> +#include <libutil.h> +#else +#include <pty.h> +#endif + +#include "uart_pty.h" +#include <simavr/avr_uart.h> +#include <simavr/sim_time.h> +#include <simavr/sim_hex.h> + +DEFINE_FIFO(uint8_t,uart_pty_fifo); + +//#define TRACE(_w) _w +#ifndef TRACE +#define TRACE(_w) +#endif + +TRACE(static const char * +uart_pty_toPrintableChar( + uint32_t value) +{ + static char rv[2] = ""; + if (value >= ' ' && value <= 126) { + rv[0] = (char)value; + rv[1] = 0; + } else if (value == '\n') { + return "\\n"; + } else if (value == '\r') { + return "\\r"; + } else { + rv[0] = 0; + } + return rv; +}) + + +/* + * called when a byte is send via the uart on the AVR + */ +static void +uart_pty_in_hook( + struct avr_irq_t * irq, + uint32_t value, + void * param) +{ + uart_pty_t * p = (uart_pty_t*)param; + TRACE(printf("uart_pty_in_hook %02x %s\n", value, uart_pty_toPrintableChar(value));) + if (p->port[0].crlf && value == '\n') { + uart_pty_fifo_write(&p->port[0].in, '\r'); + } + uart_pty_fifo_write(&p->pty.in, value); + if (p->port[0].hook_from_uart != NULL) { + p->port[0].hook_from_uart(value); + } else if (p->hook_from_uart != NULL) { + p->hook_from_uart(value); + } + + if (p->tap.s) { + if (p->tap.crlf && value == '\n') + uart_pty_fifo_write(&p->tap.in, '\r'); + uart_pty_fifo_write(&p->tap.in, value); + } +} + +// try to empty our fifo, the uart_pty_xoff_hook() will be called when +// other side is full +static void +uart_pty_flush_incoming( + uart_pty_t * p) +{ + while (p->xon && !uart_pty_fifo_isempty(&p->pty.out)) { + TRACE(int r = p->pty.out.read;) + uint8_t byte = uart_pty_fifo_read(&p->pty.out); + TRACE(printf("uart_pty_flush_incoming send r %03d:%02x\n", r, byte);) + avr_raise_irq(p->irq + IRQ_UART_PTY_BYTE_OUT, byte); + + if (p->tap.s) { + if (p->tap.crlf && byte == '\n') + uart_pty_fifo_write(&p->tap.in, '\r'); + uart_pty_fifo_write(&p->tap.in, byte); + } + } + if (p->tap.s) { + while (p->xon && !uart_pty_fifo_isempty(&p->tap.out)) { + uint8_t byte = uart_pty_fifo_read(&p->tap.out); + if (p->tap.crlf && byte == '\r') { + uart_pty_fifo_write(&p->tap.in, '\n'); + } + if (byte == '\n') + continue; + uart_pty_fifo_write(&p->tap.in, byte); + avr_raise_irq(p->irq + IRQ_UART_PTY_BYTE_OUT, byte); + } + } +} + +avr_cycle_count_t +uart_pty_flush_timer( + struct avr_t * avr, + avr_cycle_count_t when, + void * param) +{ + uart_pty_t * p = (uart_pty_t*)param; + + uart_pty_flush_incoming(p); + /* always return a cycle NUMBER not a cycle count */ + return p->xon ? when + avr_hz_to_cycles(p->avr, 1000) : 0; +} + +/* + * Called when the uart has room in it's input buffer. This is called repeateadly + * if necessary, while the xoff is called only when the uart fifo is FULL + */ +static void +uart_pty_xon_hook( + struct avr_irq_t * irq, + uint32_t value, + void * param) +{ + uart_pty_t * p = (uart_pty_t*)param; + TRACE(if (!p->xon) printf("uart_pty_xon_hook\n");) + p->xon = 1; + + uart_pty_flush_incoming(p); + + // if the buffer is not flushed, try to do it later + if (p->xon) + avr_cycle_timer_register(p->avr, avr_hz_to_cycles(p->avr, 1000), + uart_pty_flush_timer, param); +} + +/* + * Called when the uart ran out of room in it's input buffer + */ +static void +uart_pty_xoff_hook( + struct avr_irq_t * irq, + uint32_t value, + void * param) +{ + uart_pty_t * p = (uart_pty_t*)param; + TRACE(if (p->xon) printf("uart_pty_xoff_hook\n");) + p->xon = 0; + avr_cycle_timer_cancel(p->avr, uart_pty_flush_timer, param); +} + +static void * +uart_pty_thread( + void * param) +{ + uart_pty_t * p = (uart_pty_t*)param; + + while (1) { + fd_set read_set, write_set; + int max = 0; + FD_ZERO(&read_set); + FD_ZERO(&write_set); + + for (int ti = 0; ti < 2; ti++) if (p->port[ti].s) { + // read more only if buffer was flushed + if (p->port[ti].buffer_len == p->port[ti].buffer_done) { + FD_SET(p->port[ti].s, &read_set); + max = p->port[ti].s > max ? p->port[ti].s : max; + } + if (!uart_pty_fifo_isempty(&p->port[ti].in)) { + FD_SET(p->port[ti].s, &write_set); + max = p->port[ti].s > max ? p->port[ti].s : max; + } + } + + // short, but not too short interval + struct timeval timo = { 0, 500 }; + int ret = select(max+1, &read_set, &write_set, NULL, &timo); + + if (ret < 0) + break; + + for (int ti = 0; ti < 2; ti++) if (p->port[ti].s) { + if (FD_ISSET(p->port[ti].s, &read_set)) { + ssize_t r = read(p->port[ti].s, p->port[ti].buffer, + sizeof(p->port[ti].buffer)-1); + p->port[ti].buffer_len = r; + p->port[ti].buffer_done = 0; + TRACE(if (!p->port[ti].tap) + hdump("pty recv", p->port[ti].buffer, r);) + } + if (p->port[ti].buffer_done < p->port[ti].buffer_len) { + // write them in fifo + while (p->port[ti].buffer_done < p->port[ti].buffer_len && + !uart_pty_fifo_isfull(&p->port[ti].out)) { + int index = p->port[ti].buffer_done++; + TRACE(int wi = p->port[ti].out.write;) + uart_pty_fifo_write(&p->port[ti].out, + p->port[ti].buffer[index]); + TRACE(printf("w %3d:%02x (%d/%d) %s\n", + wi, p->port[ti].buffer[index], + p->port[ti].out.read, + p->port[ti].out.write, + p->xon ? "XON" : "XOFF");) + if (p->port[ti].hook_to_uart != NULL) { + p->port[ti].hook_to_uart(p->port[ti].buffer[index]); + } else if (p->hook_to_uart != NULL) { + p->hook_to_uart(p->port[ti].buffer[index]); + } + } + } + if (FD_ISSET(p->port[ti].s, &write_set)) { + uint8_t buffer[512]; + // write them in fifo + uint8_t * dst = buffer; + while (!uart_pty_fifo_isempty(&p->port[ti].in) && + (dst - buffer) < sizeof(buffer)) { + *dst = uart_pty_fifo_read(&p->port[ti].in); + dst++; + } + size_t len = dst - buffer; + TRACE(size_t r =) write(p->port[ti].s, buffer, len); + TRACE(if (!p->port[ti].tap) hdump("pty send", buffer, r);) + } + } + /* DO NOT call this, this create a concurency issue with the + * FIFO that can't be solved cleanly with a memory barrier + uart_pty_flush_incoming(p); + */ + } + return NULL; +} + +static const char * irq_names[IRQ_UART_PTY_COUNT] = { + [IRQ_UART_PTY_BYTE_IN] = "8<uart_pty.in", + [IRQ_UART_PTY_BYTE_OUT] = "8>uart_pty.out", +}; + +void +uart_pty_init( + struct avr_t * avr, + uart_pty_t * p) +{ + memset(p, 0, sizeof(*p)); + + p->avr = avr; + p->irq = avr_alloc_irq(&avr->irq_pool, 0, IRQ_UART_PTY_COUNT, irq_names); + avr_irq_register_notify(p->irq + IRQ_UART_PTY_BYTE_IN, uart_pty_in_hook, p); + + const int hastap = (getenv("SIMAVR_UART_TAP") && atoi(getenv("SIMAVR_UART_TAP"))) || + (getenv("SIMAVR_UART_XTERM") && atoi(getenv("SIMAVR_UART_XTERM"))); + p->hastap = hastap; + p->hook_from_uart = NULL; + p->hook_to_uart = NULL; + + for (int ti = 0; ti < 1 + hastap; ti++) { + int m, s; + + if (openpty(&m, &s, p->port[ti].slavename, NULL, NULL) < 0) { + fprintf(stderr, "%s: Can't create pty: %s", __FUNCTION__, strerror(errno)); + return; + } + struct termios tio; + tcgetattr(m, &tio); + cfmakeraw(&tio); + tio.c_cflag &= ~(ECHO | ECHONL); // no input echo + // tio.c_oflag |= (OPOST | ONLCR); // LF -> CRLF + tcsetattr(m, TCSANOW, &tio); + p->port[ti].s = m; + p->port[ti].tap = ti != 0; + // p->port[ti].crlf = ti != 0; + p->port[ti].crlf = 1; + p->port[ti].hook_from_uart = NULL; + p->port[ti].hook_to_uart = NULL; + if (ti > 0) { + printf("uart_pty_init %s on port *** %s ***\n", + ti == 0 ? "bridge" : "tap", p->port[ti].slavename); + } + } + + pthread_create(&p->thread, NULL, uart_pty_thread, p); + +} + +void +uart_pty_stop( + uart_pty_t * p) +{ + puts(__func__); + pthread_kill(p->thread, SIGINT); + for (int ti = 0; ti < 2; ti++) + if (p->port[ti].s) + close(p->port[ti].s); + void * ret; + pthread_join(p->thread, &ret); +} + +void +uart_pty_connect( + uart_pty_t * p, + char uart) +{ + // disable the stdio dump, as we are sending binary there + uint32_t f = 0; + avr_ioctl(p->avr, AVR_IOCTL_UART_GET_FLAGS(uart), &f); + f &= ~AVR_UART_FLAG_STDIO; + avr_ioctl(p->avr, AVR_IOCTL_UART_SET_FLAGS(uart), &f); + + avr_irq_t * src = avr_io_getirq(p->avr, AVR_IOCTL_UART_GETIRQ(uart), UART_IRQ_OUTPUT); + avr_irq_t * dst = avr_io_getirq(p->avr, AVR_IOCTL_UART_GETIRQ(uart), UART_IRQ_INPUT); + avr_irq_t * xon = avr_io_getirq(p->avr, AVR_IOCTL_UART_GETIRQ(uart), UART_IRQ_OUT_XON); + avr_irq_t * xoff = avr_io_getirq(p->avr, AVR_IOCTL_UART_GETIRQ(uart), UART_IRQ_OUT_XOFF); + + if (src && dst) { + avr_connect_irq(src, p->irq + IRQ_UART_PTY_BYTE_IN); + avr_connect_irq(p->irq + IRQ_UART_PTY_BYTE_OUT, dst); + } + if (xon) + avr_irq_register_notify(xon, uart_pty_xon_hook, p); + if (xoff) + avr_irq_register_notify(xoff, uart_pty_xoff_hook, p); + + for (int ti = 0; ti < 1+(p->hastap?1:0); ti++) if (p->port[ti].s) { + char link[128]; + snprintf(link, sizeof(link), "/tmp/simavr-uart%c%s", uart, ti == 1 ? "-tap" : ""); + unlink(link); + if (symlink(p->port[ti].slavename, link) != 0) { + fprintf(stderr, "WARN %s: Can't create %s: %s", __func__, link, strerror(errno)); + } else { + // printf("%s: %s now points to %s\n", __func__, link, p->port[ti].slavename); + } + } + if (getenv("SIMAVR_UART_XTERM") && atoi(getenv("SIMAVR_UART_XTERM"))) { + char cmd[256]; + sprintf(cmd, "xterm -e picocom -b 115200 %s >/dev/null 2>&1 &", + p->tap.slavename); + system(cmd); + } else { + // printf("note: export SIMAVR_UART_XTERM=1 and install picocom to get a terminal\n"); + } +} diff --git a/examples/simuc/src/simavr/parts/uart_pty.h b/examples/simuc/src/simavr/parts/uart_pty.h new file mode 100644 index 0000000..482de7d --- /dev/null +++ b/examples/simuc/src/simavr/parts/uart_pty.h @@ -0,0 +1,90 @@ +/* + uart_pty.h + + Copyright 2012 Michel Pollet <buserror@gmail.com> + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef __UART_PTY_H___ +#define __UART_PTY_H___ + +#include <pthread.h> +#include <simavr/sim_irq.h> +#include "fifo_declare.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + IRQ_UART_PTY_BYTE_IN = 0, + IRQ_UART_PTY_BYTE_OUT, + IRQ_UART_PTY_COUNT +}; + +DECLARE_FIFO(uint8_t,uart_pty_fifo, 512); + +typedef struct uart_pty_port_t { + unsigned int tap : 1, crlf : 1; + int s; // socket we chat on + char slavename[64]; + uart_pty_fifo_t in; + uart_pty_fifo_t out; + uint8_t buffer[512]; + size_t buffer_len, buffer_done; + void (*hook_from_uart)(uint8_t); + void (*hook_to_uart)(uint8_t); +} uart_pty_port_t, *uart_pty_port_p; + +typedef struct uart_pty_t { + avr_irq_t * irq; // irq list + struct avr_t *avr; // keep it around so we can pause it + + pthread_t thread; + int xon; + int hastap; + + union { + struct { + uart_pty_port_t pty; + uart_pty_port_t tap; + }; + uart_pty_port_t port[2]; + }; + void (*hook_from_uart)(uint8_t); + void (*hook_to_uart)(uint8_t); +} uart_pty_t; + +void +uart_pty_init( + struct avr_t * avr, + uart_pty_t * b); +void +uart_pty_stop(uart_pty_t * p); + +void +uart_pty_connect( + uart_pty_t * p, + char uart); + +#ifdef __cplusplus +} +#endif + +#endif /* __UART_PTY_H___ */ + diff --git a/examples/simuc/src/simavr/semaphore.h b/examples/simuc/src/simavr/semaphore.h new file mode 100644 index 0000000..289a45d --- /dev/null +++ b/examples/simuc/src/simavr/semaphore.h @@ -0,0 +1,32 @@ +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +#include <mutex> +#include <condition_variable> + +class Semaphore { + public: + Semaphore (int count_ = 0) : count(count_) { + } + + inline void notify () { + std::unique_lock<std::mutex> lock(mtx); + count++; + //notify the waiting thread + cv.notify_one(); + } + inline void wait () { + std::unique_lock<std::mutex> lock(mtx); + while(count == 0) { + //wait on the mutex until notify is called + cv.wait(lock); + } + count--; + } + private: + std::mutex mtx; + std::condition_variable cv; + int count; +}; + +#endif // SEMAPHORE_H diff --git a/examples/simuc/src/simavr/simavr.cpp b/examples/simuc/src/simavr/simavr.cpp new file mode 100644 index 0000000..ba63390 --- /dev/null +++ b/examples/simuc/src/simavr/simavr.cpp @@ -0,0 +1,749 @@ +#include "simavr.h" +#include "../sim/error.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <limits.h> +#include <sys/time.h> + +#include <iostream> +#include <iomanip> +#include <thread> + +#include <simavr/sim_gdb.h> +#include <simavr/sim_irq.h> +#include <simavr/sim_avr.h> +#include <simavr/sim_core.h> +#include <simavr/avr_uart.h> + + +SimAvr::SimAvr () { + memset(&status, 0, sizeof(status)); +} + +SimAvr::~SimAvr () { + if (firmware != NULL) { + free(firmware); + firmware = NULL; + } + if (avr != NULL) { + free(avr); + avr = NULL; + } +} + +void SimAvr::shutdown () { + // if (pthread_mutex_lock(&lock)) { + // throw std::logic_error(error(AT, "shutdown() fails caused by mutex error")); + // } + // cancelThread = true; + // isShutdown = true; + // pthread_mutex_unlock(&lock); + addEvent(EventShutdown); +} + + +void SimAvr::load (struct StartParameters *params) { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "load() fails caused by mutex error")); + } + try { + if (isShutdown) { + throw std::logic_error(error(AT, "cannot load after simavr shutdown")); + } + if (firmware != NULL) { + throw std::logic_error(error(AT, "firmware already loaded")); + } + + startParameters = params; + firmware = (elf_firmware_t *) malloc(sizeof(elf_firmware_t)); + std::string filename = std::string(params->filename); + if (firmware == NULL || elf_read_firmware(filename.c_str(), firmware) != 0) { + throw std::logic_error(error(AT, "elf_read_firmware() from %s fails", filename.c_str())); + } + if (params->mmcu != NULL) { + strncpy(firmware->mmcu, params->mmcu, sizeof(firmware->mmcu)); + } + if (params->frequency > 0) { + firmware->frequency = (uint32_t)params->frequency; + } + if (params->vcc > 0) { + firmware->vcc = (uint32_t)params->vcc; + } + if (params->avcc > 0) { + firmware->avcc = (uint32_t)params->avcc; + } + if (params->aref > 0) { + firmware->aref = (uint32_t)params->aref; + } + + // strncpy(firmware->mmcu, "atmega324p", sizeof(firmware->mmcu)); + // firmware->frequency = 20000000L; + if (firmware->frequency == 0) { + firmware->frequency = 8000000L; + } + if (firmware->vcc == 0) { + firmware->vcc = 5000; + } + if (firmware->avcc == 0) { + firmware->avcc = 5000; + } + if (firmware->aref == 0) { + firmware->aref = 2500; + } + if (firmware->mmcu[0] == 0) { + throw std::logic_error(error(AT, "missing cpu type, use --mmcu ... to set mmcu manually)", firmware->mmcu)); + } + + avr = avr_make_mcu_by_name(firmware->mmcu); + if (!avr) { + throw std::logic_error(error(AT, "avr_make_mcu_by_name() fails (mmcu=%s)", firmware->mmcu)); + } + if (params->gdbPort > 0) { + avr->gdb_port = params->gdbPort; + } else { + avr->gdb_port = 1234; + } + printf("init with port=%d, mmcu=%s, f=%u, vcc=%d, avcc=%d, aref=%d, pc=0x%04x\n", + avr->gdb_port, firmware->mmcu, firmware->frequency, firmware->vcc, firmware->avcc, firmware->aref, params->pc < 0 ? 0 : params->pc); + status.freqHz = firmware->frequency; + + if (avr_init(avr) != 0) { + throw std::logic_error(error(AT, "avr_init() fails")); + } + + + firmware->eeprom = (uint8_t *)malloc(1024); + for (int i = 0; i < 1024; i++) { + firmware->eeprom[i] = 0xff; + } + firmware->eeprom[0] = 0xf0; + firmware->eesize = 1024; + + avr_load_firmware(avr, firmware); + status.state = StateLoaded; + + avr->fuse[AVR_FUSE_LOW] = 0xe7; + avr->fuse[AVR_FUSE_HIGH] = 0xd8; + avr->fuse[AVR_FUSE_EXT] = 0xff; + avr->lockbits = 0xff; + + avr->gdb_port = 1234; + avr_gdb_init(avr); + if (params->pc >= 0) { + avr->pc = params->pc; + } + + pthread_mutex_unlock(&lock); + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } + addEvent(EventLoad); +} + +// enabled/disable character output on stdout in case of avr uart write +void SimAvr::setUartDumpEnabled (bool enabled) { + if (avr == NULL) { + throw std::logic_error(error(AT, "setUartDumpEnabled() fails because no avr available")); + } + uint32_t f = 0; + avr_ioctl(avr, AVR_IOCTL_UART_GET_FLAGS('0'), &f); + f = enabled ? f | AVR_UART_FLAG_STDIO : f & ~AVR_UART_FLAG_STDIO; + avr_ioctl(avr, AVR_IOCTL_UART_SET_FLAGS('0'), &f); + avr_ioctl(avr, AVR_IOCTL_UART_GET_FLAGS('1'), &f); + f = enabled ? f | AVR_UART_FLAG_STDIO : f & ~AVR_UART_FLAG_STDIO; + avr_ioctl(avr, AVR_IOCTL_UART_SET_FLAGS('1'), &f); +} + +void SimAvr::registerIoWrite (avr_io_addr_t addr, avrsim_io_write_callback_t callback) { + avr_register_io_write(avr, addr, (avr_io_write_t)callback, this); +} + +void SimAvr::setUartPtyEnabled (int uart, bool enable) { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "start() fails caused by mutex error")); + } + uart_pty_t *p = NULL; + try { + if (uart < 0 || uart > 1) { + throw std::logic_error(error(AT, "setUartPtyEnabled() fails (invalid uart %d)", uart)); + } + if (enable && uartPty[uart] != NULL) { + throw std::logic_error(error(AT, "enableUartPty() fails (uart %d already enabled)", uart)); + } + if (!enable && uartPty[uart] == NULL) { + throw std::logic_error(error(AT, "enableUartPty() fails (uart %d not enabled)", uart)); + } + if (avr == NULL) { + throw std::logic_error(error(AT, "enableUartPty() fails (avr not ready)")); + } + if (enable) { + p = (uart_pty_t *)malloc(sizeof(uart_pty_t)); + if (p == NULL) { + throw std::logic_error(error(AT, "enableUartPty() fails (malloc fails)")); + } + memset(p, 0, sizeof(uart_pty_t)); + // setenv("SIMAVR_UART_TAP", "1", 1); + uart_pty_init(avr, p); + uart_pty_connect(p, uart + '0'); + uartPty[uart] = p; + } else { + uart_pty_stop(uartPty[uart]); + free(uartPty[uart]); + uartPty[uart] = NULL; + } + pthread_mutex_unlock(&lock); + + } catch (std::exception& e) { + if (p != NULL) { + free(p); + } + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } +} + +void SimAvr::setUartPtyHook (int uart, void (*fromUart)(uint8_t), void (*toUart)(uint8_t)) { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "setUartPtyHook() fails caused by mutex error")); + } + try { + if (uart < 0 || uart > 1) { + throw std::logic_error(error(AT, "setUartPtyHook() fails (invalid uart %d)", uart)); + } + if (uartPty[uart] == NULL) { + throw std::logic_error(error(AT, "setUartPtyHook() fails (uart %d not enabled)", uart)); + } + uartPty[uart]->hook_from_uart = fromUart; + uartPty[uart]->hook_to_uart = toUart; + pthread_mutex_unlock(&lock); + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } +} + +const char *SimAvr::getUartPtyDeviceName (int uart) { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "start() fails caused by mutex error")); + } + try { + if (uart < 0 || uart > 1) { + throw std::logic_error(error(AT, "getUartPtyDeviceName() fails (invalid uart %d)", uart)); + } + uart_pty_t *p = uartPty[uart]; + pthread_mutex_unlock(&lock); + return p == NULL ? NULL : p->port[0].slavename; + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } +} + +const char *SimAvr::getTargetDeviceName () { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "start() fails caused by mutex error")); + } + try { + if (firmware == NULL) { + throw std::logic_error(error(AT, "getTargetDeviceName() fails (no firmware loaded)")); + } + pthread_mutex_unlock(&lock); + return firmware->mmcu; + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } +} + +uint32_t SimAvr::getTargetFrequency () { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "start() fails caused by mutex error")); + } + try { + if (firmware == NULL) { + throw std::logic_error(error(AT, "getTargetDeviceName() fails (no firmware loaded)")); + } + pthread_mutex_unlock(&lock); + return firmware->frequency; + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } +} + +void SimAvr::start () { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "start() fails caused by mutex error")); + } + try { + if (isShutdown) { + throw std::logic_error("start() not allowed after shutdown"); + } + if (avrRunThread != NULL) { + throw std::logic_error("simavr already started"); + } + if (avr == NULL) { + throw std::logic_error("avr not ready (check if load done)"); + } + syncTime[0] = !syncTime[1]; + avrRunThread = new std::thread(&SimAvr::avrRun, this); + pthread_mutex_unlock(&lock); + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } + addEvent(EventStart); +} + + +void SimAvr::stop () { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "stop() fails caused by mutex error")); + } + try { + if (avrRunThread == NULL) { + throw std::logic_error("simavr not started"); + } + cancelThread = true; + pthread_mutex_unlock(&lock); + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } + addEvent(EventStop); +} + +void SimAvr::setCommand (EnumSimAvrCommand cmd, void *param) { + if (command != ReadyForNewCommand) { + throw std::logic_error("another command pending"); + } + command = cmd; +} + +void SimAvr::addEvent (int event) { + struct timeval tp; + gettimeofday(&tp, NULL); + SimAvrEvent *p = (SimAvrEvent *)malloc(sizeof(SimAvrEvent)); + if (p != NULL) { + p->epochMillis = tp.tv_sec * 1000 + (long)tp.tv_usec / 1000; + p->event = event; + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "addEvent() fails caused by mutex error")); + } + try { + p->cycle = avr->cycle; + if (!isShutdown) { + events.push_back(p); + eventCount.notify(); + } + pthread_mutex_unlock(&lock); + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } + } +} + + +void SimAvr::setTimeSync (bool sync) { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "setTimeSync() fails caused by mutex error")); + } + try { + syncTime[1] = sync; + pthread_mutex_unlock(&lock); + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } +} + + +struct SimAvrEvent SimAvr::waitForEvent () { + eventCount.wait(); + + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "waitForEvent() fails caused by mutex error")); + } + try { + struct SimAvrEvent rv = { epochMillis: 0, event: EventUnknown }; + struct SimAvrEvent *p = NULL; + if (events.size() > 0) { + p = events.front(); + rv = *p; + if (p->event != EventShutdown) { + events.pop_front(); + free(p); + } + if (p->event == EventShutdown) { + cancelThread = true; + isShutdown = true; + } + } + pthread_mutex_unlock(&lock); + return rv; + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } +} + +const char *SimAvr::eventText (EnumSimAvrEvent event) { + switch (event) { + case EventUnknown: return "Unknown"; + case EventShutdown: return "Shutdown"; + case EventLoad: return "Load"; + case EventStart: return "Start"; + case EventStop: return "Stop"; + default: return NULL; + } +} + +struct SimAvrStatus SimAvr::getStatus () { + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "getStatus() fails caused by mutex error")); + } + struct SimAvrStatus rv = status; + pthread_mutex_unlock(&lock); + return rv; +} + +void SimAvr::printCyclesAndElapsedTime () { + uint64_t time = avr->cycle * 1000000000L / avr->frequency; + uint16_t nanos = time % 1000; time = time / 1000; + uint16_t micros = time % 1000; time = time / 1000; + uint16_t millis = time % 1000; time = time / 1000; + uint16_t seconds = time % 1000; time = time / 1000; + printf("cycle %" PRIu64 " = %ds %03dms %03dµs %03dns", avr->cycle, seconds, millis, micros, nanos); +} + +void SimAvr::avrRun () { + long cnt = 0; + int lastAvrState = -1; + _avr_sp_set(avr, 0); + while (1) { + try { + if (avr->state != lastAvrState) { + switch (avr->state) { + case cpu_Stopped: { + printf("\ncpu stopped at 0x%04x on ", avr->pc); + printCyclesAndElapsedTime(); + char sfr[9]; + sfr[7] = avr->sreg[0] ? 'C' : '-'; + sfr[6] = avr->sreg[1] ? 'Z' : '-'; + sfr[5] = avr->sreg[2] ? 'N' : '-'; + sfr[4] = avr->sreg[3] ? 'V' : '-'; + sfr[3] = avr->sreg[4] ? 'S' : '-'; + sfr[2] = avr->sreg[5] ? 'H' : '-'; + sfr[1] = avr->sreg[6] ? 'T' : '-'; + sfr[0] = avr->sreg[7] ? 'I' : '-'; + sfr[8] = 0; + printf(" SFR: %s\n ", sfr); + uint16_t x = 0, y = 0, z = 0; + for (int i = 0; i < 32; i++) { + uint8_t b = avr->data[i]; + printf(" r%02d=%02x", i, b); + switch (i) { + case 0x0f: printf("\n "); break; + case 0x1a: x = (x & 0xff00) | b; break; + case 0x1b: x = (x & 0x00ff) | (b << 8); break; + case 0x1c: y = (y & 0xff00) | b; break; + case 0x1d: y = (y & 0x00ff) | (b << 8); break; + case 0x1e: z = (z & 0xff00) | b; break; + case 0x1f: z = (z & 0x00ff) | (b << 8); break; + } + } + printf("\n X=0x%04x Y=0x%04x Z=0x%04x\n", x, y, z); + + uint16_t sp = _avr_sp_get(avr); + printf(" Stack (SP=0x%04x)", sp); + int printHeader = 1; + for (int i = 0; i < 16; i++) { + uint16_t addr = sp + 1 + i; + if (addr <= avr->ioend) { continue; } + if (addr > avr->ramend) { break; } + if (printHeader) { + printf(" -> SRAM 0x%04x:", addr); + printHeader = 0; + } + uint8_t b = avr_core_watch_read(avr, addr); + printf(" %02x", b); + + } + printf(printHeader ? "\n" : "\n"); + + printf(" Arduino LED L: "); + printf((avr->data[0x24] & 0x20) && (avr->data[0x25] & 0x20) ? "ON\n" : "OFF\n"); + + printf("\n"); + break; + } + case cpu_Sleeping: printf("cpu enter sleep mode at cycle %" PRIu64 "\n", avr->cycle); break; + case cpu_Running: printf("cpu starts running at cycle %" PRIu64 "\n", avr->cycle); break; + case cpu_Step: printf("cpu step\n"); break; + case cpu_StepDone: printf("cpu step done\n"); break; + case cpu_Done: printf("cpu done\n"); break; + case cpu_Crashed: printf("cpu crashed\n"); break; + default: printf("cpu enter unknown mode at cycle %" PRIu64 "\n", avr->cycle); break; + } + lastAvrState = avr->state; + } + + if (startParameters != NULL) { + switch (startParameters->board) { + case BoardNano: { + static int8_t ledL = -1; // pin floating + uint8_t ddrb = avr->data[0x24]; + uint8_t portb = avr->data[0x25]; + int8_t nextLedL = -1; + if (ddrb & 0x20) { + nextLedL = portb & 0x20 ? 1 : 0; + } + if (nextLedL != ledL) { + ledL = nextLedL; + printCyclesAndElapsedTime(); + printf(": LED L = %c\n", ledL ? 'X' : '.'); + } + break; + } + case BoardSure: { + static int8_t led[4] = { -1, -1, -1, -1 }; // pin floating + uint8_t ddra = avr->data[0x3a]; + uint8_t porta = avr->data[0x3b]; + int change = 0; + for (int i = 0; i < 4; i++) { + int8_t nextLed = -1; + if (ddra & (1 << i)) { + nextLed = porta & (1 << i) ? 0 : 1; + } + if (nextLed != led[i]) { + change = 1; + led[i] = nextLed; + } + } + if (change) { + printCyclesAndElapsedTime(); printf(": "); + printf(" LED PA[3210] ="); + for (int i = 3; i >= 0; i--) { + printf(" %c", led[i] ? 'X' : '.'); + } + printf("\n"); + } + break; + } + case BoardEWS1: { + static int8_t led = -1; // pin floating + uint8_t ddrb = avr->data[0x24]; + uint8_t portb = avr->data[0x25]; + int8_t nextLed = -1; + if (ddrb & 0x01) { + nextLed = portb & 0x01 ? 1 : 0; + } + if (nextLed != led) { + led = nextLed; + printCyclesAndElapsedTime(); + printf(": LED1 (PB0) = %c\n", led ? 'X' : '.'); + } + break; + } + default: break; + } + } + + if (cnt <= 0) { + // usleep(10000); + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "avrRun() fails caused by mutex error (1)")); + } + try { + status.cycle = avr->cycle; + status.state = StateRunning; + status.running = true; + switch (avr->state) { + case cpu_Done: status.state = StateDone; break; + case cpu_Running: status.state = StateRunning; break; + case cpu_Crashed: status.state = StateCrashed; break; + default: status.state = StateOthers; break; + } + if (cancelThread) { + cnt = -1; + cancelThread = false; + } else { + if (syncTime[0] != syncTime[1]) { + syncTime[0] = syncTime[1]; + if (syncTime[0]) { + cyclesOnSyncStart = avr->cycle; + struct timeval tp; + gettimeofday(&tp, NULL); + timeMicrosOnSyncStart = tp.tv_usec + (uint64_t)tp.tv_sec * 1000000L; + } else { + cyclesOnSyncStart = -1; + timeMicrosOnSyncStart = 0; + } + } + if (syncTime[0]) { + uint64_t ucMicros = (uint64_t)(status.cycle - cyclesOnSyncStart) * 1000000L / status.freqHz ; + struct timeval tp; + gettimeofday(&tp, NULL); + const uint64_t timeMicros = tp.tv_usec + (uint64_t)tp.tv_sec * 1000000L - timeMicrosOnSyncStart; + + if (ucMicros > 3000000) { + ucMicros++; + } + + int64_t dt = ucMicros - timeMicros; + if (dt > 0) { + int us = dt > INT_MAX ? INT_MAX : (int)dt; + if (us > 1000) { + timeval ts; + ts.tv_sec = 0; + ts.tv_usec = us; + select(0, 0, 0, 0, &ts); + } + } + } + } + if (avr->state == cpu_Done) { + cnt = -1; + } else if (avr->state == cpu_Crashed) { + throw std::logic_error(error(AT, "avr state is cpu_Crashed")); + } + pthread_mutex_unlock(&lock); + + } catch (std::exception& e) { + status.state = StateError; + pthread_mutex_unlock(&lock); + throw; + } + } + + if (avr->state == cpu_Stopped) { + timeval ts; + ts.tv_sec = 0; + ts.tv_usec = 1000; + select(0, 0, 0, 0, &ts); + } + + if (cnt < 0) { + cyclesOnSyncStart = -1; + timeMicrosOnSyncStart = 0; + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "avrRun() fails caused by mutex error (2)")); + } + try { + if (avrRunThread != NULL) { + avrRunThread->detach(); + delete avrRunThread; + avrRunThread = NULL; + } + pthread_mutex_unlock(&lock); + return; + } catch (std::exception& e) { + pthread_mutex_unlock(&lock); + status.state = StateError; + throw; + } + + } else if (++cnt >= 100000) { + cnt = 0; + } + + if (command != ReadyForNewCommand) { + switch (command) { + case CommandStatus: { + printCyclesAndElapsedTime(); + printf("\n"); + break; + } + case CommandInterrupt: { + if (avr->state == cpu_Running) { + avr->state = cpu_Stopped; + } + break; + } + case CommandContinue: { + if (avr->state == cpu_Stopped) { + avr->state = cpu_Running; + } + break; + } + case CommandStack: { + uint16_t sp = _avr_sp_get(avr); + printf("Stack: SP=0x%04x:\n", sp); + for (uint16_t addr = ((sp + 1) / 16) * 16; addr <= avr->ramend; addr++) { + if (addr % 16 == 0) { + printf(" 0x%04x:", addr); + } + if (addr % 4 == 0) { + printf(" "); + } + if (addr <= sp) { + printf(" "); + } else { + uint8_t b = avr_core_watch_read(avr, addr); + printf(" %02x", b); + } + if (addr % 16 == 15) { + printf("\n"); + } + } + printf("\n"); + break; + } + + default: break; + } + command = ReadyForNewCommand; + addEvent(EventCommandExecuted); + } + + avr_run(avr); + + } catch (std::exception& e) { + status.state = StateError; + cyclesOnSyncStart = -1; + timeMicrosOnSyncStart = 0; + if (pthread_mutex_lock(&lock)) { + throw std::logic_error(error(AT, "avrRun() fails caused by mutex error (2)")); + } + try { + if (avrRunThread != NULL) { + avrRunThread->detach(); + delete avrRunThread; + avrRunThread = NULL; + } + pthread_mutex_unlock(&lock); + throw; + } catch (std::exception& e) { + pthread_mutex_unlock(&lock); + status.state = StateError; + throw; + } + + } + } +} + diff --git a/examples/simuc/src/simavr/simavr.h b/examples/simuc/src/simavr/simavr.h new file mode 100644 index 0000000..e1455b7 --- /dev/null +++ b/examples/simuc/src/simavr/simavr.h @@ -0,0 +1,132 @@ +#ifndef SIMAVR_H +#define SIMAVR_H + +#include "semaphore.h" +#include "parts/uart_pty.h" + +#include <simavr/sim_avr.h> +#include <simavr/sim_elf.h> +#include <simavr/sim_io.h> + +#include <string> +#include <thread> +#include <list> + +typedef enum { + BoardUnknown = 0, + BoardNano, + BoardSure, + BoardEWS1 +} EnumStartParameterBoard; + + +struct StartParameters { + char *filename; + int gdbPort; + int64_t frequency; + const char *mmcu; + EnumStartParameterBoard board; + int32_t pc; + int32_t vcc; + int32_t avcc; + int32_t aref; +}; + +enum SimAvrState { + StateInit = 0, + StateError = 1, + StateLoaded = 10, + StateRunning = 11, + StateDone = 12, + StateCrashed = 20, + StateOthers = 99, + StateUnknown = 100 +}; + +typedef enum { + EventUnknown = 0, + EventShutdown = -1, + EventLoad = -2, + EventStart = -3, + EventStop = -4, + EventCommandExecuted = -5 +} EnumSimAvrEvent; + +typedef enum { + ReadyForNewCommand = 0, + CommandStatus, + CommandInterrupt, + CommandContinue, + CommandStack +} EnumSimAvrCommand; + +struct SimAvrStatus { + long long freqHz; + long long cycle; + enum SimAvrState state; + bool running; +}; + +struct SimAvrEvent { + long long epochMillis; + long long cycle; + int event; +}; + + +class SimAvr; +typedef void (*avrsim_io_write_callback_t)(avr_t *avr, avr_io_addr_t addr, uint8_t value, SimAvr *simavr); + +class SimAvr { + +public: + SimAvr (); + ~SimAvr (); + + struct SimAvrStatus getStatus (); + struct SimAvrEvent waitForEvent (); + const char *eventText (EnumSimAvrEvent event); + +public: + void load (struct StartParameters *params); + void shutdown (); + void start (); + void stop (); + void addEvent (int event); + void setUartDumpEnabled (bool enabled); + void setUartPtyEnabled (int uart, bool enabled); + void setUartPtyHook (int uart, void (*fromUart)(uint8_t), void (*toUart)(uint8_t)); + void registerIoWrite (avr_io_addr_t addr, avrsim_io_write_callback_t callback); + + const char *getTargetDeviceName (); + uint32_t getTargetFrequency (); + const char *getUartPtyDeviceName (int uart); + + void avrRun (); + void setLed (bool on); + void setTimeSync (bool sync); + void setCommand (EnumSimAvrCommand cmd, void *param); + +private: + elf_firmware_t *firmware = NULL; + avr_t *avr = NULL;; + StartParameters *startParameters = NULL;; + pthread_mutex_t lock; + std::list<struct SimAvrEvent *> events; + EnumSimAvrCommand command; + struct SimAvrStatus status; + bool cancelThread = false; + bool isShutdown = false; + bool syncTime[2] = { false, true }; + std::thread *avrRunThread = NULL; + long cyclesOnSyncStart = -1; + uint64_t timeMicrosOnSyncStart = 0; + Semaphore eventCount; + uart_pty_t *uartPty[2] = { NULL, NULL }; + void printCyclesAndElapsedTime (); +}; + + + + +#endif // SIMAVR_H \ No newline at end of file -- 2.39.5