From 52f4c0ed3c8d0718f40062ab927f208af0fd656f Mon Sep 17 00:00:00 2001 From: Manfred Steiner Date: Sun, 27 Nov 2022 18:49:11 +0100 Subject: [PATCH] debian packet fails created by make removed from repositoy --- .../htl-simuc_version_arch/DEBIAN/control | 10 - .../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 1820968 -> 0 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 -- 73 files changed, 17631 deletions(-) delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/DEBIAN/control delete mode 120000 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/readme delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr/avr_mcu_section.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_acomp.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_acomp.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_adc.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_adc.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_bitbang.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_bitbang.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_eeprom.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_eeprom.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_extint.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_extint.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_flash.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_flash.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_ioport.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_ioport.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_lin.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_lin.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_spi.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_spi.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_timer.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_timer.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_twi.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_twi.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_uart.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_uart.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_usb.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_usb.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_watchdog.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_watchdog.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/fifo_declare.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/run_avr.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr_types.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cmds.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cmds.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_core.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_core.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cycle_timers.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cycle_timers.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_elf.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_elf.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_gdb.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_gdb.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_hex.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_hex.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_interrupts.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_interrupts.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_io.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_io.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_irq.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_irq.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_network.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_regbit.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_time.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_utils.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_utils.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_vcd_file.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_vcd_file.h delete mode 100755 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/simuc delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/main.cpp delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/error.cpp delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/error.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/sim.cpp delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/sim.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/fifo_declare.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/uart_pty.c delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/uart_pty.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/semaphore.h delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/simavr.cpp delete mode 100644 examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/simavr.h diff --git a/examples/simuc/dpkg/htl-simuc_version_arch/DEBIAN/control b/examples/simuc/dpkg/htl-simuc_version_arch/DEBIAN/control deleted file mode 100644 index 6b155e4..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/DEBIAN/control +++ /dev/null @@ -1,10 +0,0 @@ -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 -Description: megaavr microcontroller simulation 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 deleted file mode 120000 index bf9863d..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/readme +++ /dev/null @@ -1 +0,0 @@ -../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 deleted file mode 100644 index 3deae7b..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr/avr_mcu_section.h +++ /dev/null @@ -1,332 +0,0 @@ -/* - avr_mcu_section.h - - Copyright 2008-2013 Michel Pollet - - 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 . - */ - -#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 - -#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 deleted file mode 100644 index f3e14e1..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_acomp.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - 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 . - */ - -#include -#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] = "16io = _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 deleted file mode 100644 index caa3c4e..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_acomp.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - 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 . - */ - -#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 deleted file mode 100644 index 6adf1f2..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_adc.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - avr_adc.c - - Copyright 2008, 2010 Michel Pollet - - 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 . - */ - -#include -#include -#include -#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] = "16io = _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 deleted file mode 100644 index c9dbfa0..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_adc.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - avr_adc.h - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#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 deleted file mode 100644 index e34aab2..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_bitbang.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - avr_bitbang.c - - Copyright 2008, 2009 Michel Pollet - 2011 Stephan Veigl - - 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 . - */ - -#ifndef __AVR_BITBANG_H__ -#define __AVR_BITBANG_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#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 deleted file mode 100644 index 3d8832f..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_bitbang.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - avr_bitbang.h - - Copyright 2008, 2009 Michel Pollet - 2011 Stephan Veigl - - 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 . - */ - -/** - @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 deleted file mode 100644 index c348f3f..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_eeprom.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - avr_eeprom.c - - IO module that simulates the AVR EEProm - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#include -#include -#include -#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 deleted file mode 100644 index 9ad1c5a..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_eeprom.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - avr_eeprom.h - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#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 deleted file mode 100644 index 6f85660..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_extint.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - avr_extint.c - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - - -#include -#include -#include -#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] = "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 deleted file mode 100644 index 62aa154..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_extint.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - avr_extint.h - - External Interrupt Handling (for INT0-3) - - Copyright 2008, 2009 Michel Pollet - Copyright 2014 Doug Szumski - - 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 . - */ - -#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 deleted file mode 100644 index cc1fd96..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_flash.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - avr_flash.c - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#include -#include -#include -#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 deleted file mode 100644 index 07747fc..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_flash.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - avr_flash.h - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - - -#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 deleted file mode 100644 index 91cf106..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_ioport.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - avr_ioport.c - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#include -#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 deleted file mode 100644 index 024b695..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_ioport.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - avr_ioport.h - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#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 deleted file mode 100644 index 001b34c..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_lin.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - avr_lin.h - - Copyright 2008, 2011 Michel Pollet - Copyright 2011 Markus Lampert - - 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 . - */ - -#include -#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 deleted file mode 100644 index b1ecadf..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_lin.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - avr_lin.h - - Copyright 2008, 2011 Michel Pollet - Copyright 2011 Markus Lampert - - 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 . - */ - -#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 deleted file mode 100644 index bb602ac..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_spi.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - avr_spi.c - - Copyright 2008, 2009 Michel Pollet - Modified 2020 by 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 . - */ - -#include -#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] = "8io = _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 deleted file mode 100644 index c676adb..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_spi.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - avr_spi.h - - Copyright 2008, 2009 Michel Pollet - Modified 2020 by 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 . - */ - -#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 deleted file mode 100644 index 39a46bd..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_timer.c +++ /dev/null @@ -1,985 +0,0 @@ -/* - avr_timer.c - - Handles the 8 bits and 16 bits AVR timer. - Handles - + CDC - + Fast PWM - - Copyright 2008-2012 Michel Pollet - - 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 . - */ - -#include -#include - -#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] = "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 deleted file mode 100644 index 837936c..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_timer.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - avr_timer.h - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#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 deleted file mode 100644 index 521c03c..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_twi.c +++ /dev/null @@ -1,521 +0,0 @@ -/* - avr_twi.c - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#include -#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] = "8io = _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 deleted file mode 100644 index 8b37ba3..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_twi.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - avr_twi.h - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#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 deleted file mode 100644 index 25b6fe6..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_uart.c +++ /dev/null @@ -1,546 +0,0 @@ -/* - 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 - - 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 . - */ - -#ifdef NO_COLOR - #define FONT_GREEN - #define FONT_DEFAULT -#else - #define FONT_GREEN "\e[32m" - #define FONT_DEFAULT "\e[0m" -#endif - -#include -#include -#include -#include -#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] = "8io = _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 deleted file mode 100644 index 107359e..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_uart.h +++ /dev/null @@ -1,229 +0,0 @@ -/* - avr_uart.h - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#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 deleted file mode 100644 index 4acbcfd..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_usb.c +++ /dev/null @@ -1,801 +0,0 @@ -/* vim: set sts=4:sw=4:ts=4:noexpandtab - avr_usb.c - - Copyright 2012 Torbjorn Tyridal - - 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 . - */ - -/* 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 -#include -#include -#include -#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 deleted file mode 100644 index 17e5c0d..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_usb.h +++ /dev/null @@ -1,74 +0,0 @@ -/* vim: set sts=4:sw=4:ts=4:noexpandtab - avr_usb.h - - Copyright 2012 Torbjorn Tyridal - - 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 . - */ - -#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 deleted file mode 100644 index b7a5d01..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_watchdog.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - avr_watchdog.c - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - - -#include -#include -#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 deleted file mode 100644 index da86371..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/avr_watchdog.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - avr_watchdog.h - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - - -#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 deleted file mode 100644 index 8a3b2fb..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/fifo_declare.h +++ /dev/null @@ -1,189 +0,0 @@ -/* - fido_declare.h - Copyright (C) 2003-2012 Michel Pollet - - 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 - -#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 deleted file mode 100644 index dfa6fce..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/run_avr.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - run_avr.c - - Copyright 2008, 2010 Michel Pollet - - 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 . - */ - -#include -#include -#include -#include -#include -#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 [...] \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 ] Sets the frequency for an .hex firmware\n" - " [--mcu|-m ] Sets the MCU type for an .hex firmware\n" - " [--gdb|-g []] Listen for gdb connection on " - "(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 ] Add traces for IRQ vector \n" - " [--input|-i ] A VCD file to use as input signals\n" - " [--output|-o ] A VCD file to save the traced signals\n" - " [--add-trace|-at ]\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" - " 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 deleted file mode 100644 index 24cb244..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - sim_avr.c - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#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 deleted file mode 100644 index e9a97cd..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr.h +++ /dev/null @@ -1,517 +0,0 @@ -/* - sim_avr.h - - Copyright 2008-2012 Michel Pollet - - 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 . - */ - -#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 -/* - * 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 deleted file mode 100644 index b15bafc..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_avr_types.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - sim_avr_types.h - - Copyright 2008-2012 Michel Pollet - - 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 . - */ - - -#ifndef __SIM_AVR_TYPES_H___ -#define __SIM_AVR_TYPES_H___ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -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 deleted file mode 100644 index 587f259..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cmds.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - sim_cmds.c - - Copyright 2014 Florian Albrechtskirchinger - - 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 . - */ - - -#include -#include -#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 deleted file mode 100644 index aac75fc..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cmds.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - sim_cmds.h - - Copyright 2014 Florian Albrechtskirchinger - - 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 . - */ - -#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 deleted file mode 100644 index ab8015c..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_core.c +++ /dev/null @@ -1,1457 +0,0 @@ -/* - sim_core.c - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#include -#include -#include -#include -#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 deleted file mode 100644 index 874651e..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_core.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - sim_core.h - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#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 deleted file mode 100644 index 93cf265..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cycle_timers.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - sim_cycle_timers.c - - Copyright 2008-2012 Michel Pollet - - 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 . - */ - -#include -#include -#include -#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 deleted file mode 100644 index a4dfdf7..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_cycle_timers.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - sim_cycle_timers.h - - Copyright 2008-2012 Michel Pollet - - 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 . - */ - -/* - * 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 deleted file mode 100644 index df69b81..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_elf.c +++ /dev/null @@ -1,499 +0,0 @@ -/* - 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 - - 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#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 deleted file mode 100644 index 37d61d7..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_elf.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - sim_elf.h - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#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 deleted file mode 100644 index cd2196e..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_gdb.c +++ /dev/null @@ -1,1026 +0,0 @@ -/* - sim_gdb.c - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#include "sim_network.h" -#include -#include -#include -#include -#include -#include -#include -#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 - // 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\n" - " \n" - " \n" - " 0x80\n" - " \n" - "", - 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 deleted file mode 100644 index 2936df7..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_gdb.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - sim_gdb.h - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#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 deleted file mode 100644 index fea67c4..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_hex.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - sim_hex.c - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#include -#include -#include -#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 deleted file mode 100644 index e3a1d1f..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_hex.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - sim_hex.h - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - - -#ifndef __SIM_HEX_H___ -#define __SIM_HEX_H___ - -#include -#include - -#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 deleted file mode 100644 index 9e3ed9c..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_interrupts.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - sim_interrupts.c - - Copyright 2008-2012 Michel Pollet - - 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 . - */ - - -#include -#include -#include -#include -#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 deleted file mode 100644 index bebf614..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_interrupts.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - sim_interrupts.h - - Copyright 2008-2012 Michel Pollet - - 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 . - */ - -#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 deleted file mode 100644 index 548f030..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_io.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - sim_io.c - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - - -#include -#include -#include -#include -#include -#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 deleted file mode 100644 index cfd2fdb..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_io.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - sim_io.h - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#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 deleted file mode 100644 index 6d175cf..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_irq.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - sim_irq.c - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#include -#include -#include -#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 deleted file mode 100644 index b96fd47..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_irq.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - sim_irq.h - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#ifndef __SIM_IRQ_H__ -#define __SIM_IRQ_H__ - -#include - -#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 deleted file mode 100644 index da4600a..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_network.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - sim_network.h - - Copyright 2012 Stephan Veigl - - 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 . - */ - -#ifndef __SIM_NETWORK_H__ -#define __SIM_NETWORK_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __MINGW32__ - -// Windows with MinGW - -#include -#include -#include - -#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 -#include -#include -#include -#include -#include - -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 deleted file mode 100644 index 862f490..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_regbit.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - sim_regbit.h - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#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 deleted file mode 100644 index 4b81f43..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_time.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - sim_time.h - - Copyright 2008-2012 Michel Pollet - - 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 . - */ - - -#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 deleted file mode 100644 index eeb4986..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_utils.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - sim_utils.c - - Implements a Value Change Dump file outout to generate - traces & curves and display them in gtkwave. - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#include -#include - -#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 deleted file mode 100644 index 44cb2c5..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_utils.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - sim_utils.h - - Implements a Value Change Dump file outout to generate - traces & curves and display them in gtkwave. - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#ifndef __SIM_UTILS_H__ -#define __SIM_UTILS_H__ - -#include - -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 deleted file mode 100644 index 16e4d25..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_vcd_file.c +++ /dev/null @@ -1,630 +0,0 @@ -/* - 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 - - 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 . - */ - -#include -#include -#include -#include -#include -#include -#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: - * #[\n][| - * b[x/z/0/1]?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 [_] */ - 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 deleted file mode 100644 index 2dd6219..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simavr/sim/sim_vcd_file.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - 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 - - 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 . - */ - -#ifndef __SIM_VCD_FILE_H__ -#define __SIM_VCD_FILE_H__ - -#include -#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 deleted file mode 100755 index 966bd1f1fef2c8ad96d4c10ce19072af1de44a61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1820968 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

jYLP-V2|xnd#%O<5*YpS7*-s!qtp{%h zJGDQ`4K5{pTGEj+ewo0H<4~ayM(yX~A3vLG_Hb>2#6n;Ctrfaa$ONaI9{Wc0#|MNc zE5<%3BpTZ2$R8};=*}wwJ=FPGCGCxx%UK{L@Z*QG>nox!O{qiRdRF!#>j_7qst2^+ z%lM3%%InQ3GxYRW*BM34pNc*6G3j}mWe}k=CJ~*W?cyeExN&{BT%)TfcEqTXd%!@J zIp!T45}tzF*D=w>nl@s8rn6Ml7OLi))Ow^S_Lk0r1;HJXdFsMKh|uF<`KZ-p6@s-M zF-<83p2fC>zAfji>M%@@fv#&4q?0@f$}Gm1h>_t@%=9z{W>h`TGf^90!4kWjRjviT ziVTpQL963NMEV1iTH6s7=IRaosD!Bf2NVHW0a;4mB;b*=>3~QeBQOHgwq%QC@r8Xb zpDJuC34C*yCULEp%`*A(k`t2kRTIKKuD91yIE8=8f2Ge`IX*X-wf3zacc$BjeL+hk z89m;=Zp1`(aw0&naA2+A;UnWv>8uRo#Vecho6;HKN*mU8#0ozjuR6C*p-D;-IO} zI9t=NOIm@ZTa=~;{5b&A^Knczp^M$5o^=*<=JhbsR6n7Ig*Y6_aO8bO{Pzma_XeW< z3JB6xh|o^NsU6E-1!3WYuD zP>94^TJf1`y@+l(3#$TIVEu^r34VGIqjD^RCsjPrOWqijCeS{FP0BxDwy-gJrTo$k z>*0V^`(ijSaKfC{eR90G z%k_qV7v39H^VU7@f2|lv%w}(dY^M>jt7b^r(Sthz^}9K8s6?j5eb?V_)Yg`>fNH4W z34$l;s}UOpekeSe68aBGyk*Ku7=qn_{Br5VsQLa}+BJV9t$%d`&I~S~dRpIdTDkom zjo*o91hv$u4QntbEnN&#sKs8ngJCHZ$B6xj>PbBXRVZh0{H<1%9R5eV5xbllz7Dpi zO%xgY(>Sl}JJsM_om2Ps>wxM{p`((n^e0UC7*dLTWq-2ge0+aJ(x3QB(n!qZ-})G~ zTsf?FPT=AqK90%CVZ;gmYwD6P7>n8-HDZz%2D+0`imcJ`Hc6RM=jh@Tcd1gJGyWUp z9i|U67N&2+yz;lU8P*AJ)7%jrnq-hdC#KTXopB_}yzvJ`caI+N-g;Af8zE9sS z2}Hy{zAGe8{F2h|tT#4Oikeb|$Bqt-zm(KL9;;bl~-<~~6Drv*8u*K?md`~Y5?mL4^5vsa2;1!|qS~iPv zPC-l6Ea7+ZOyu7|0NvUaZ;)$YWLMStF%Bztl2zTQ)jdC#IytAwH4uGe+2wQ}!m{mH zpUF4tpCiS){ZfIFn4uyxy88=+GfM2P@J3KDroOlYsg&mv%D8GN-VrMhO*133KoqNT zzM_Q~u@89{ocB<{LLPAOH!-_DPKU{_$kDTmHD~a;(Q`p?UQ9g`r9`RV9^=G`~n@P(r(`}e1!nE8p{9l*XUZ0ji>Jnc1v6ryqVUTB}ldARKl%3HNe>@`=)`$a3`} ziMWs%YF%9@Um|P;9`X-7p0JR`X{-mMP6eaZRu4H5Y`TG@iao)u_FrkfBdJYgNj1XX zHJ%B{a_}Uz!o*s+E1NE!#?s7*(f%yn9FO*c#IcsiE8#P*$m&>kEs+GMdim|1yjrV| z-e3aP0WamensAeA^|sZ~!0#w^th`BP=SJEXH4n&Y$X-ty5W)#%#BQRmC^yx=sF1h% zK`DTE<+T)R;1gb?#QcLYb2x~6q+^H?%i+lh4UMBzhmbW8Mfn}e0bQpFMFYN6wI)+{ zP%~rSI~uLyOT66$@AJeNj|9x`xaz*U3>d1k3ZZX4G+ za|)3$&{49A#Sl#?s@qe&*SX>~M7Wb0unhP1%Y<>5bC{p`;A}m8`RLZl+7q;5#8xQA zr=;PmfY(y-A6n0`3RJ6V*!F6*=Gs0~`oVQ@m0-NfJ$UK{{^AWLu6=Z}B?F)R%AgNto+MY(-N>U~c?52>eI z9FePJUUAaK5K{ssT3fvG*qVQ3>xbue9{cWpNJm$y0WDj)I5U1N-R3L}fCIKy}({qpUlD7!ALT~ z*I-IcNV~eB=pOF5LEmxpCx7+Sg8s@qWD@|V)wZWB37ze-&gG2GS6G)0sK5@YyP1Ig zJC;b{OF!mKnmiIv zz*$$n&K9d0x4n`AS{|CkD?#sMem3nttUtId|J4dPm7R@29&~BA>+H<2*$wvRY=tHD zU9aS8R$fW-U`^! z+~Jt*%irjazmxqc%+sa6s@K>&8-I2tCyVUe>>nxjT!&f}9XTxCxtt5NPW(R4(?oNZ z^*>`3KK*-A!(Ff1OA%5ElkVqDyg^&t;E??|za9UTxK~p|^ot3i9HrYP5Aei6H^Cyu zU#AJ}A{;wlrBpZk)ur5du6Xo~T?#|t%2ebjdZTK=Fsd?H^rR5)vYs35G;ZjU{H2yH zH)`s2qwHQ7keoqQ-OxiRQXnx#0Yov)bWen8MPz~1PxUx}C2<@o@2a&p5pV=cjwiFz z*s;}Z=tk`y>p{gBj?$cj*B(2r&o5TvIuYSB>=Tabfv+6b$`g+3o~_4>>spHGe4}R1 zo|pCGHX4-oaU2%&O_l75e;(J5IP}ltlCl0Zd=IFb#d2R%U#~3U@fol1olMDF?iI@h z7R`^VIl!WC7O?(wDM*aEE%Oy)*mt4+E$bq`3!UGhNy_hhe(Q)!omLqsB@vg)=Z39s zpkgXZBpDt#3JW_@EecQumKX`KtnuTddbg~NH?sL^O<)+>-k=i-JX;{ObX=u1f|sh& zGXBQY8@24B$Z}dm4#?o(6=Ow4*mVh|U7HYKokb);_%c<0vWTads`&`bYrot=^=d}4 zfn+=4bwy&i8nuGJK2bKFyfM(54nljdpmaaQv)1UfYdZpWlC@BL^mCQ_)+|#{e^QUPAWzWW)rXd>CTgb8nML^TO*1A0ZDW~f_3*QYJ@wen|yB-5isD-0^ zY-=C+b7xokv#$Om_5u#L@<5y$Q&3N`D0rGnO?kmXM}eI%<1}dqW>eaXjLZ=#GR0reB(UwXJm1L z{jMwqoIO+eQQjoGl+mV{ql$lU%O^LXupx<%5+N}JFP%Fcna?yfLY1FoNUUY$DWaTl zRW-Yy}X|Ak#Dw@m2^9DuXZ|&R*6_c( z-2N6>MW7#SHFmB#uIhnV-5WABYPcu$=#!a7)qYu(_~$sJVs*Fm>9{JB$j0}1hC0+! zZTi>QARU5zOoOpzoqB;K5j9n{`au1TUZfk$%EsU7eVdCsmUE7E5{5M^P6WIxaU6;) z&E>N+L#;PKJHr~)YX1@gS+^rsB0>_)$j=@@+y`oZ496z%D4F46R3Bovr+KOecGPEt zUWMZOcUHuwW_7l2aOWFHTsCP2o{7IQ-StI`&G)?gwI_qV0&jDgCqB@e+W!lxebK&V zt-|Z}A5rbX>!|h^)t;wlS9?suw`>M+h~H!h*Z-Dg*t9uJF-m*rL?CHRyuKR(X?RZn zDaV7elVL;-6Y_guLj7PKJ2C@_QGGhD%=CsX8JD?YDN^-bnLLO71NFOlm3p@XyoZgN zJNpDliP>{Q7Ox!0e?0b}@ss-Y0+|OjM;kR8G}Jl+^&bPZ&VYAcgnAx=5agU){SFA7 z)Q?`UID;IG*-h0M8_TR=OpnQ>z ziZ@7`$^480lX!E4?3HU|a~F^ObaJ}=RCf2`uj-3ih~X|ZuP*nswq2FwKl$|Nk-o+n z@#U0~uVp$57H__WQ@@kQeBmSYMNOTq1zs^FD#?^ey-ofsFtaGjc%pgv*@7m{`3VYb zl@dWOw><=V<@qAFWqEFUKVaTkE~Nsi8->f*CBp?B{IZm~JS|27y^10$vpg$X(%Pec z>DTErl9km_l$8~JT9p7ZzGT4bg-XDT52h*1sJa+D8hu@7msN+eR?+u#uCZ_uD4UZV zcBV3&ibj<&$QL;bxaw(T(mXiY&E?mSfH=q`u1-wtDH-B_tMS7UxR-jZQg0pJ8tN{~ z_H~T!;SG^Ud`2+#UTA5g-5WZuG;U2yjN1xNlJejb;IaaVP;Ug-oxQV3#uV`Gu}+>P zH=87{`mCh;hvOceD}xl*0?Rmls7kd#<<}uzmwj7D-mwhXeC+ z{^Tw|!29auT{|^hQoVQYZtLXlopsFb9>@G932G8gq<+t1eyhaqKnD!Lik#}uDNsYATA_jk`i-2YLlX~RIdk#m6xZmL|^}?{n_lUN2!U@J}=%lsJ>&Ulz-CaFC z9ZsqP#y|_auO8o%#o(8aAjH3{Cnq_35l@16axY(^ z@)Y51z#gG$|K(*Rhos$T(@)jB^86=h&*wv8Schw-unsDbT4MC-$!Zpy+*7XR3H zSDoV%)ns0azq%}l_!^iECSCTAGMG&OX5jMM7y8fwBxAQS!ktpdebKCIU!cN0H4pQV$Z#)&>u8@Q`GE5BVCHe&a~ z{fspi(a`G7$?C~&^?kW~uWIBwusV-`Elz3N%`sA;(B3F_c%ir?tGqNZs)bbUq;@a3 z7?4aY=+V)TXH@-$5;*eu`AGalZl72uy`Vk?%!!=Ge3_S&%`AA5F#o}-$}*xO z=~XnD$N3~81{eM1Mb%@U2fR&0IyKU;Cq5<9AKx7r z5J7jbhOtIO#Ywh_inXgdS13sRM3(V5Nc{u&DM;N^K55?P;J9E==A^{99H5g!UU`)x z8z^N0rK;yC?LH&Dya2BU!2BA6HEO1idA^d3r7kOoRmPRI7y2Uo3L@m8V8<8h?b8=1 z=CSUVU?51#y?D|&jI8h3lNYY4PHu708&vB4L~g}3Nfp=%{#rEBl5*}*dYC5B%*CLT zf5#~4$Li?a@?exqjg)3&bClYj(Wm|pOvW2xu(T?WO*}n@1-9NSP>|&8Uy>ex;n~D2 za--ti(VcfIy+H;MoVSUQmO}&-C`MyK1OpCXJRm}(yvGL+K2N#Pu|YrFV&xNwjkBqm zy#LHcz$EDdU!Y@;iswH8m;@e|2jXK<$VY-`cYqO?#On_P zerdmmIJf>qCuwk8H_5SmFnqk^HnoQ%2Gic>roG?sOWEufnz7rElIG>{v1VxG7x9qy z3;Rae)+7;atBW@%tu%5ZVpPc{-Iii;9biP*=krSe6u@$@8}_CywTP4sI^7$|%0M^C z2w(9$ZFSim8AxqtBnooK+i7>wqtx&o}zK*N1GT2%&!{v^e zWSvRstM;ehW2;I5Vgz23K1jOhvZwPWje{xvi#;=bDjOos@H+h7EN`ek_Y0@z<(h!Z z{LE30Bc|&3_RrU!xx@758HIeF;MnYjp9!kQCb<{J2Z?hox1L37mPF;{SjGMV zQd8_PfB07@Q0+W9;EKF<=IWgu&)%-=hWPYMbNXWES9AQz#R_gSstFE(?_FPgO6F!I_k|MC#o}8>Xe_Tj(SsZqB^($ zI;`O*s-xaqNF9I@Do}USC2{5aJ?h-GsPgt6ilmecW&a4hayw~g{tBb&XW*QhsRO<4 zTAwMYI%{*HJIkq*T11(@z3YjjJ}kcpwZwT#yxwF|JIKlKt4mER<(j}P#HI($=fxOT;E|9- zBGd!Rba?u?lAA@>I9=9XrC-Sz?8bcu%2cs%CSwL_%bd7Ug4Y8}STcNAAgH^WEL$vR z=k!ML7Z2KYoL(vYoHPuj+M%4y^;Y`1Adoqpi{2*SH@aQUwX1GrJ3^Xm-Ra1ZWQ=N* zCLP>L6F+Oo-yYv4tDTrWbs8Jv$b`aj{GLPoupH2 zNJ~dq&jAqM^Kv}KoK^(Z?#CZdLh{%$cH*XTnc@poSB$=4eXw7KTuEy@)$FTp??=dM zA07Nkh0=m+3+qUCL&`r{Pw0zXMxf9YUTh|$NB1OWg}vnwe=?)hJjy^?d4eo6^WywX1+6kQ%Ph4 zl4$;+=$-QgIw=`FMqUvb^Mt=4>Rm8#XTeHlK>EMY`*n4;CbCAP^vzOY#RKM=HmWqP zQ8kU)6=gw9l6r@%>Umx&P8!fyS}7?srv?*?3+A^Ebm=v^F*7i>Jyc}WeoK`KeS(GP zH4#*ea{nh894L{Z1}9%z5`8!Q5dt6E9O(#j6gTGvCoz~x3xX2w7D%>u zTx(9$@=DrLmqQ6%)?9O~d0p9mtmCIn+8mA85Mirv$9|0Om6Y=Aun0NntB_b-+}y!y z{bmWRhszuvhahD7CjJ*<0jWLQi(8MV0LDp6r~-EgE96a;4H>GOoc;3U@AZqTebOYq zxvCVO;a>g|Di9m<@6v^ej3IKOcA8|4H;i@uf&tFan+8@(ajMM0awuYtq?g!Y&HqEE zBug-2f8cc>F-_Fb!VYzxwc_;WB@^h?(T^9t^Hub}DV_e&n**x;xz4@_gAO7o%xM9d z>2~FxQT4R42B#JbU>EQ;&~pgp2m?%6WcJnKOVaxVGIZ;YzbBr~$tF>AXMr)kdfZ3> zi#d(!gTtjsnWm1+$9^Vw8h_VZRfduD4nr%0`YC=b;3CY2+eOGWCADHq> z+L!-<3PO>*PcR50_Bd~X?s>XK0tpnu?IYZqu(TFy2&2-&Cl}ftNv(Mi&Wkx}10{LT zxbg$#*Wr$@Y%Gr?y~=RRX<$rAQj1^+4GM-M^l)PDhQ97Xvz9~6+=s9SzUuFjiT<<~ z3~07~NYtQUkfz6z#fTc96agEXO4(b2Vl|VNIMZ;&hYJ62Qw5P=Maa*fd9|-&6-le9 zrf_abeuI)S4X^RivK~D(QnY8(HucFFAUFzWzWgnuH-wS`$f}E=A)A=eG=3@k%F#|_ za|hnjbL(eb4ihfzxmthrkL%CeAMoiUP&{KD-;cesw-7zR)d@Cp_?l2}lJ~!(nWY?f zc6M5`&y*wOinj?*9WwGr8ig3$y>0vVnoHF#S8j)^77{1I(O0Hx!+#AAkTSy2@mt~MvVCO(z(m$=Us5Y z1@cq=RW1nS>4!sk6JB)l(&2fP;pGd4=PkH(MP=bIj}#g)qVl$z=gGI^KlNb2;OvXwi}dc`Fu$7UnHqFn4jD{FISM?mja7%c>>+^tH=HPFa+apHI zJ+^#$ao-8bFJDm6ZGhd%PcFIAZC~KEVCCE;%N8%t>!p|20pQ%wk_9)-{nmwJmNAAD zAPO%Uss8a0IE-9*F~9QWUa&MA(%^U7(2MM>v0Groh=mIlFY`Ef;c?!2QeAlj7o6XP z7kLy;BwvqO<|&yx`I^a>Fo9d=E?zX>!6XnhFI>5R5lQQLp{0413zx3o5%BEOhu#Ds z_*k}dd5DkXTs-G2R*&cL5E%1UKrJ6Y@Yt?2V(0ybzMSzbSyWlM=;oVTG=fy}gjD{` zFg=TIUIcb7y_so%MGGn`^S=B4vG+dkRUKvi|J-|XAs2@Oe_+?3E#r3Rwc7Ax(di^^(uw<^1f zyZvdu`>ifNMYqlUzMq+M?!8HFD73j)x^rGRdCqxe=9!t#JoC&mbIzU9yh+zZ6iYRB zw1->Udzuw`)_51O4FHWD8#XkwH%$ulyX_89gHS=KsNkH?+Kw*K&TtRx_NJMpV(K<} z!fow6ZEdQ&xv669T20#3T-Dvu6K?9**q(K3Xf3@OY#SRu7qB;lB=@fH5Fs6%i36I$ z#io>5Q>G-6+0fKfdQWqEc!*%Mw}#GLjYUW(KkdqOO=~9iNbg&?G*mEoa!93J$zPOP zv8*OEc}_@8nR1)(y2CyE+fe5!U0&yH=)}7|NWI+qQN|*}ZA%w(tgBkjc{P z8t&Vd|FLRsC-(S%rZ z(Y1tFu4(9QZLI4KccHv9XVxvLL+!ZhX$*%%RYFn=EiVGmyRR$x2>bGuC=|p z8BI0EmTgmtXt`w+sHA5@XKA~P4oz;Rp*77~sSwE6(G?p%T;yO1fDi{i2B&z{i_^&s zJ>llwP;*yTN7qoPr{AuevQ&mQ4J=BQ+n2NoWj5V9l$05Hs##YF&Ek}xj93YB-%0;fM;%Q&JZo1J9WCkcW|1$M0*fR8#XjYD}2Ev&C4Dt zi)qs&iyG~uB+7w~616~W9Su#*Luywpw#KnP1A0;JjHyG0%uo$r)Pl?63@M?`=JqDc zfV9p)`+HHnZ|aO}wXFTFc7_yH?Tjs|oGPel>Cyb}=#;v1#}F08^kS4KFL#D&+|-C& zW<(Fo4rMlVhcdILHf=EEyI(i7y<0`c8fPH7xSCAMR)YQODkEtfGcF=R4Qs_cG$syr z#SFPav<_Z+wC!CJV{~As1lX6hwRO_{>)e!5=q@uH=wW?`q|@`1>%25}_GmxZ^;)8C zwK!OKtok1BqX%oTX(%&sJBoErSKWq&yPE6p!s^y+s%!7pbwtW+<{3kjCnr1CxJKI5 z7Y}ZBChm@tYEo$J?93j#pTCtp`9 zPZe9F$1QDu^_bP%q$-xCsfzjY(^Q&(D$+Y~s2alf&r-HfM|%igym~&aZDw~`h?}m= z?A)f={OeWRhiaW#ghDH$SF55mBLcmr@vcx-b)~~(u7ML!T~)Ni$pa5xOCxTPnRtcD zOG`rKGeb(sg#RV_*w)va0JZoZkJ zX!FgK$&^u!nL`wI#?)-Jv7t3QzoW~z&#%j*<Oel+T-VAZ zc;V9Oy8OC@?e}!t)!enPIy^1h!_0W$q9xO-TQ?Nl(>4E|drB*-r`DC~LzRlhDZM~d zFI-ZzysBe^wi;|AxM=^w5- zmOzYLXu^aEatmPs8*b=~&JRG=%nKSxzM`mVDbWT97Y2d7^ym$t$zXAu zWxkH&InfDVD0j}doX|LxUm$+0lx9k6yUL#vy<=`~oOlql_#-EVsi8t&?=UytEV#z zSZmi#3fivgVj5%mnq3IDJb)H?0wBVa=e8p&@HyR|g<3SyH?V7qNY9 z>pC~NiluL847c9XpfQrh2joW9=9(K@I%b6yR^1W8hK4d38oJT-PPh1R>Ep`}_^wsy zYF@|eyt%8nNvDbBNBLZLH5NxNc*IGH=HtMn>WpI5HEw9C(>mJL(b2g^mQ~Cl?V-ck zU7>Eu{^5y3m8x?Ew06|#IlGhmhC8R`Y$&d%DxGP%H+nNOguT&ASrwhS$czA5pDGMV zyW!644Q}qSq$|1_I!%wzO9FVcdc~-+*rXaDP4T7G7x(c8&*3BnMN29(b& znOSytjXdIoo9q}a=<257x?igvVvIugO{%qHrgnX5 z%T;ZeT3N1EmZ??cYE_x4t}N$-5?M9g+kQ`XOSo12U*0qLG|%GYyq@bisGQ0-@$S=Mj5b&Tl}aq&7k zI@-kH5%U=zMXR1xXPI8rX&L<&dWbPF+--GNZx`S`U|cu0G`H&|2{G1UY&V6Q$&o=c zvscDZthr1p2+%w3x( z;w=bV%Zp2#%If7u87dh#8&U4e?kW7|c|%)M)Z?O}Y0SB!wRfS^)44Pr`RI~XI?pP~ z=zC~Jnwl?_RHdbrRTWFreAaxsDJg#2n$~c)()Chxb!OqO+ihE+yZKf7(ZBDD)SuvY zADo4p*_^_UKSS`+IbSC3^PKsFyJrjcu1wJ<8J?qaS9Oc-zbJHO?<{IOlYb0xhUr|$ zO?I|og}1J~IlQr>>#jO?=xS(eZ0-yv4C-obyhkl4nHOro{gO5Iu8y|JjcTH*?&%ai z3|AJf0afFoc5QRl%ni*OI=VJZ-q6rFQ*4&1axC1!_O%_Vicv#l=JfKXw3nk=8hDJ; z%E}~KklC8qu1a;GtEl1>MhAKd)tMxy&QZ*8Gkf_nEmFz^q*-N7xbrlQ4LiC3vCEjOvIjSb<(7S&)#%f>Yn`Yx&P0GF|wc5V(!FN+3h zZCcZcgA*4>&j>fSI}KGMb;-@v#&uS1j;6wzm75#AHqA0ir&!WK2a|^pJ!_m%TR*7a zaSlvD%5@DL`FAHmeB!KbQ;UhSoa#(;^`@;L);e?2Le8C5`q|@g(8kNejs=AA*}eJt z8P@nvTXXxmaLerRnYZ+gzim(&-Roni`bQ^rsDS5v_*dagAz9RzJ$?-i&t2k7j>pBy z&n~#l4Hwb3nbOTkbFV~;WXC&6JF_dZt!b9@G*ZvZpJj~U%qpt-%d3lFQZr>nDrCt$8NcF$VZ*f>)pHu212t-f;d=|<-+I3Jq7 zp=;9xWHmL{$%zY7pYG0RE;-YOr8-lmx_L~UwN5JD+BlP3oO*ROM)RW#!vWvaJU73* zXny3POb^i>%laNX+0F+3iN`M!3B3%HnVsJ|3AZZ0cNQug?$N_T=-%e84m~#M?x)im zjW7={bbOO4lodCfh`QM(U*nApk#H_|MJbKlrM|N$!6P{n(FV{Hbx*5?AsUr%6T_^DtYkLM=Tl%uO4|%Nr3i z#uPeV+z9TB^jY1vO8d7GXvX(YS!r#Ed8=M?HTqy?FTDS_oOM1u+ii86e@P~u5Ph3m zrsPRJ{7#3=<$1FkORu7I_wYy$BYT_tGwtoh>uK+HN3D=qago;?bZi|lE?>z{hPwuI zg4H)3Yc{s97}p&NGiW-FiuMB~p-lO-B&LG+X71|}@-S4^c*JSbzMYKOqCkR>cHJDq zEah7kb=~yDd!eACT^VszoMYj-_6~XSXv%_nG>NqkXXa`gFlKfP zAb$f^4m8`pI}#iXm(NfXx@klp&aREJBjdGM;{Xz!ps zJVly#iu)XRm`e!Bk}0Qo5zLY#aj#E;G2N1hF1L|LYDI|5l~Sr6NW=i69S)e z%L*Uhn* zyyO;3&~z)Sht8uNJY4qZ0Jermlf3S7# z>Jj-@NdM9+L(YR+#ztqMVG@RWZI5}0qa)OD4@*ugrkI&REZxG2=%m$M$v2ZNXQ5?7 zL$9-ndn-v}>1sMUm=v^c;>nLRK?pf+*4-u#jgKjxOwU=pT8Q;FO%&SD)60qsUBFE= zuv}63EWfnL%7$K86hX0K=w$!^=)5hn6Y-j+so7fhI#500GO@_-$3U9Q_HbRN;3>L? z;Omy8Zory{#2FYa`YwD~yu&Uw66=Ti(pFJZsDq^B zuKXU{B)u3}N02b%4#_`0RPM!yxKXQH*R|tBi5q4NJu5P35-z)#x3#>=Wo!)j&nKNc z!vJ}0>v(NVKP6?oP{v%{c}gmlmg;%q#+FU`MVyVzAs(zY&rM?<)7E1aJegB6FYlDM zrbO(*`4yoGluV2x54GBQx?50cy75@#tFbcg?xro9)!2I)m`w0IGna8)1|_cL-8{X1 znWpL_jD8W?s8{czrH3o)Y3)$}C5{ zGS!PqNY?u|fhBM9aE0Zt)r%@BDV`Z}pWe%R zp$({Z$2#}b(y0H_FJ6(n5Sln*|9C?S)bSc|9NU}Qq)Rrowd&{FnLW2<_Jo#826`@` zi{&-Ec3C{Z$8D~29U6lT z1IUKXhOP$IFY4$x8rXOqJ!lY*jys6QJ6G~t4t~rPL7-V!&2}X6s)Q`t)HMvjUlZkv zW3rZ&c88HOK!6)Dr*3e>hE67?&2`Q4>ZRgg0?w&C9f}o8VU_EQxvtBulNYdEYZ(`i zGgLrszW{VqR92q9sRF0H$w|#|ujLt|S$UL})ei*g7FHD3l=HY%)+6hxOKWg}%(D{S zlIjr!aunq?)5*jDWuyIR=;$)Dt7hlVcfo7t>pZJ*B7Svc)q>KcGO1vF z*rb>BND1kb*VRoWj7#r?%ev(G!mFFj^IBOe(`(D2ECylbpfWX)V}Kk{8Yi#(UM8jD z4)YGJUaaoE3sa+uSy5GkD{D-x|Wq>)Yo|oy{&v+Rh2v{kpi=LU>^BtykqfV_O)M3$!1F4+R&O#RwMGwgOMDj zgdOG?u1;Uo(X*~aKP#7a@f+o_vwl{Rrc%-iw{&;5@_vE5R!|^4-5fRYM2hCx(8&_8 z`1+l^*d8OQz#4z!A6Pl)N)cTUigRG8DiBVBpCB7fF9RE+-&uFB3S{vkv4=+Bn zPYTsk@JQ8(&IQ=iEL>8m-?S33@;4=SZP~q2NyaXjYdRy4*rBLkGrN!m5j{h)cC)p- z_;|cV?o2fjM%5MSmp{czPyk&R!BLvBUwoLlZW<1^cBaAm$BSDG(v>jKZd|uP(2%Eq zCec9o24-2aY?c+xwFB{T8)(_m>SdLc^t#fLs36l^DwU6t%UQ;`g)_^!|7}+!aznQ{ z^PwtiuEikfB05jYWA{;gbR-)R3&&o$9zk4;Sh!v+t?Ov)GUKE4>Wv$+4aqS?jAmn} znxn^eL)IA57!$c=F1xmUhkGbA3EAX9B_- zO%IpZ(A3;HW^xO}BBsZz6~s!X>%bfqa~_qgtFD!DU_5#4M+Q|VL*~)ua3Bp;*I?to zor{V}p{5!5If&-gtf;Qi&!hMmM6^zlk>t}Rj+V@gqi?HC;>|_5lL@%VN$bM*uO089~HKxk{_wL=syZXJJEGy>w0<1UOHip^l|B z>4!G75}w&;{HLl~mLO!DF>6;n7{ay=o>MTabj{8*FU988n)9|XQKAB}yb+R{ zO`)z{N0JM>a^ufiwtxY#w~@CD^s1eHJu5*XH-6Zaq{}33tL_85c9Oe+@mjyZA@Ad$ zH8M!d>FvNl?8OE-__;*z)$i>L0C-t7k2Nbh@QN_uyu7LXSy`3uX@=K3g@>VSQVD0> zX^gxPBUakHh(N7z{^Q$*b%;)p=H{#AisLE4%JX5Ez!y%237f(yI9j6)RJ>X~eqMOlefSm|MVac{bF! zgtS z@wK{&G}_j@N@#-l5dvIoBl^iTkMjL1ifW3>N-EHKGoG^Muixf~@frN}&zxAXG{1Lp zsrCcKOz7wEO&xq*iX)aVPM}^06>AqQ+>}t2IGy5Cn=TkjC!P-;o$I!Q3PUVG-F0s$ zi4L6?Ui;3z$Y{bdZlZk9Jm{gf zDfJ8JNoe7_`Xc9`?+x+(%G;It5VQn(U@Y~7{%{;y=|Xp8@!rbSN@Y!;e$eM8@;(c6 z+@!upYKBsM&_d|^$-ILM&7ML$=x*p?;b)T%v+`7}baV;$K#!He z2j7}9%1^o4pq3^b4Ue}Eo>zIQSBUPt+%qoLo2PJ;d)Xd(0y zOTim@Yeiq=81%YI@PjUfjvcMkXQ1WKpR|SV?_qfkM_dw4<_d`d$gL@}Y;IC!lAbXP_Bts4uhx zn*L7YLdQaD8o?cU3fcrM;hpqe=ppD%=vdw(-vgW7aX89p8z+xho;_4IP^y7nNK1Yy6sbx3tF?Ecdl-seGb4E`Zwe! z^vjeB+H??ohaUS1;bSTH*9eF1|1NlCQjVwLLz|9KAEDnvKcIQvryk?T7djSt_BeVg z_q^}51De6tS@uI~en`CW;PVgY5j4y*_?^&G(0$Mnp3fhG?%}!p%g{s6lq|{v9Su$4 znf@eb-cP{+n(?!~$Pwrv=vldcp88|Awn4L?hj=Gp8#Ir17EVC-LsKRo4>}sU{{?Ur z`U~m-JqtYpZTeU25N{bBV^gnsXxeh)nZ&6tGz|LBXfKui9Ueh%FaJpq+( zr)Ny&9-0NM`TxiVdIq`$dKS6|n(}M(1bXTv`VBPvf52}F^8PRQLGyk`|A6lKZ}i|c z;z7%xC1;TXJ@iNVDRj^O(0`zLub|&@56#L(UIcpy-3HwO-4ERhZQ@f~MaBQyib+i5BfS_0jc5{WcH_dt80hoC#5XZ(!!(6i8^&QHbF<_k{&u1x*u8qJqE3To`SYO&q6mt4_(1}uJECUgbzId%}Ar1&^+iX&=P3+ zROCa)LbnAdCv-n_HS`!X3_Szg2~8OliR_1tg&u*{Tp5YH0BwSvmHQy_^03f%)e08M!t<%DKHPeb#dXQ8K{8Pg~SGz*&YcIpq^4_ysC z1`SI%bSLyIbRRT>4U`T+4?#~sPeEUjaA?YO!ZTg38oG_mn?~gm z9~y!lgYqayWv~nGPUs=%VdyD#=6xBOl1aU9r<~AAXwyX67rJc{a)q+@-3!qD(6i8E z(Da$qlQn(zFHkkC^>2ojOhq2_4D`lX)FUqvsfC_mPpg-pP5Icon$_ZT!Jq6tZ%_sp+ zXc&4DdIy>JuL*^#o!Aqf$o5wg&u+KFGtUz zrH!%GFGHpodz)sT8?)q5sfRZQvyLcT>*!$b;rX z4?)YJHDTHp8it;b@E-jB1(XMx1+BRUeSns1#GXK#pgW-{ThXsF!l5B(#x~?Z&upiB za{mGFhK3)a9t$bQ!{`BY+lOcmXvs&IV?fV-ly+ML-k+kMLc^b?9MG|!LH=UWK||29 z&^&0#e(DF^58Vkp1l=5>0Ddqn<^%43F>na(1XzMljL7P z`M-%BfsXw<^cI?-%;CAWN_l$IJvWRRnY!C!_%{+Xn*FxNNtBY2=|ULV73PWkU|)^w zPK5^3=LbhGx+<_Sb&Hz&j+qmtj=foeMeb_OmX}|RgrM#r{4i%H{4J8+IfTEH^AYlU zT6m?wbnlbFR4IcTo_j0HbqPm4e*ez`>IS!*K&H#I@sF=YewPA{SEGdUgXtgiE(nf( z*jE}1?Mj&!%-ZQM3TAH~Q54MII&wkqq{sJMN-!T*Q7~&>Ff=bXdR{PnUXb!g{W7S3 z<+)cQs0$BFgX!Cm6&2CvuMy@2AAuEAq;N z>07D*{d#UL?HA!@htL&LL@JPs=6nbUndrr_{42m|hAH5`LqXdDRf%qX{n{ z{1b#@?sOftdN&G$=!{bGO?oeN9xq{9cD)Xp#BG?cAYuEXVMW2w+kMo1Yf4El+xy{Q z2nP7kB89}^BigEqd@?C-%8DW_Z6vqqF4f1}%MYHC z?%&;X=u9l#YhqB2j6WgcR*~_vD}(NPfig-cM|O%*zaP~Xd6jF^&uE8-eRQHh{j4Nd z={=pOmr0-KMb3dM`y%fWIUJ%FJK=2|(HD7E7+Pog>&4+Xy^#1vh=1eA3yVLN_%9K^ z=ufXkeioHqCVE#!pL^2Px7CD&iMI>6p8&6v?=bjMmJf=)4XS5}u_p(;zDGU5!`}J9 zqu$lfvLKwpo}ua<_OqEj^ZDzf92{c%cECFeFH;zlsFvO$IPHV)ozWM$S@;|h_Yk~v zcsf0{;|}6VpF07+m$vz$L|mwCz&`18Quh}L8v)*HBuv{Iur;=7nQL!EKRbz6NW9si zBO^`SdY`XX10e2z-aBghio_28NE4>&m*NAxY;E-#4M<@v!a z9^Xsev|v6)V1QvR4Ioc!eLDG!V$Ej^{V2uPuWhugFBMx~Dl!+Cw(0aO^9&(UrJRAjyyF| zsYkEvi~N_v`D}51Z?hr;*24u@l8L_IE=t^_dflU)z1!))8k5 z@vj}t99H6g%H+RG;_sAkZhOiiI{62%y;vgG_G-PYMen{rx&@?@Bb)Pt}A&PSRaFf}wSy)1q@nprJhGJYJ`Jng=j!l{`dXH8{ zeVl_H-+zxBLh+F&y1yEklcw;yP$}Evu1u}_FJf2|%OkN*AP3({W~CNKfg&Iie(=Kp^+GLdW34y!~RbbTffHjDiKQt~Pu zoR_u@+7Hxrdr@$=&v&Ocac7qL+z8fP=+_j&nP zrTBV|*JRSYK)QF6?!P1*+T_@AMi-|ah_m(6{=GoPiVT$h>U`EGC7srF{1ZJ^G`K^B z9#it~1O~k7p-pnW#OQL$KeRHk1Wr9UX5FPua zC;)m_*55fV4J=GFqS8*}ahyCdXR^k~wUl|QcPYbqqxQk2d@mAyKjF)wWf-96S}#ha z3{}CCUf%>y@Of`T@U-_%Xb~LmcM@hUI#F^ZcCvtVPRW}?^t2Y<33yKmV{!1b$NL2C zcu_!XRG6^N+5FZ>!i+5ud}+_kG^Uw16bHPe(VK;V4wo-B0^Ep_IPVb zr%8n8JTI__Ytss40q;C+%5;;6x@uj11vxvA^A3^2A$3U)GG~MbT>1#{U!J?{hWAC` zXl%<-oDLeA$;EH_q*gyeAr`jruMKFjdlcv=F|U@b5&!Wp-zLlWl~lLVo}5 zgl+etA6tD3X~4gA>zzf|0pcAd-tE|{f%W!fdE9=W%kw;OPZae<8XcKiy_+b{yucbV zm3p2d{Kk2)dJ1n8lcUk_#z-0t;f3Jk!7CERx?sBS^5AvCnVG?9Q?|D@t$(Ln5Li5jLpGvkN0HZ5?ATo0HcPZU zlrp_QSPNmdac%Hoyx8ueldjNZk_oTqQwo*pB;HS)c=7&TiHw(GCn|&ajln`XDIKMR z(x7eB(2P;@1A4Asj-1qzzR15havmlT;~ed{Gi9labI92`qSsU40$R>HX>7{bUH zaf>lzS(U-i!r2*L`|Cj#yh-r35H3fEvjE+&*UMGK)4^0} zpL*h?%LbrQYq9cWDAPbIzYhN3r5Wsul<6RO)GX?Y zhz*mYh4UD^N_hHv(b&Uy{|f2b{S2&IM|i(6K=I}Uyo+S;FI=wks~QyiJ}Dn6Use>X zyd#*cbv&C1&VHVawnZ_$_LFzap^AEkU1!4Od;?FrK6FX@Z?E!U>~-T0<7`9Tqf7fDKaY;V zG5>YY8eOHYN8EtHim)gkvg8^0q&xZ|)1tBxjpy3WqlJBoMHcE$v2ksqMJ*0wBP-<^ z`d2m2MY)a}SBlMgR3RRXbPlr~wFt$N{PRh(mo&#SO&Vu?K+hTR;GOkG$ET_EU7a}p zqJZGNP4eH=7x@g=atQBHct_wps5ypr0ABvR&NvKT%5fClDR|FFJl#h0`CX!qJDE?> zMvJiBjzUJOJs;;RtK2oP3tf9O>RSAk`<(FtaZ-*DyfD0CkDoxQV{>2RF|I{Fopjo7VN?(|ma;4g&=VcBi}4?_s)N}} zv_3VF>>x7EAmblWxS_u1S(m}D_V`vMR-&SS?uS6?IY1!k##ynWPj6BKm&h+^Xh7p_UDv2<76E{Boz%7cB8 zKO#zwY|az#UVO;$3pKu|tdaTQ&>p4HT z&*SY3KH*swJm^^vJnUh)%TpRW?kQ(M{SFDNPKW`BI{lx#T6VF=k(1XTJ565L>8;ok zCgxFXEen(f^VbIpmuPE%tTxWW$lCdEUt~Q#j=^$K|2c*B=k@$*VQ|aay`N23wD|$w z_fms9-d+~m{r2V1BBEA7o4Bub?v3tdT~B_zBk`YPXZl%9)VE=t;@HA+7682uGl_>4 zZxTxbA(FKrBma{;?-v=`S3~u^O~#L&7f>~@cN0h6!T2AEQz3mM)`ss(dpbCJ{xdl7 zCuD-U-d

~iE^>`}p5tV(O_bnuEY|Sp2cRTA|+Ao$`iMGc3!t{8-M&3C(LfQ@e$0yyd zG&U@7Y-i0!&v`4oxWEaAI^EazBkS}RoOw2~#V#L)H|dLgkp`~i(BnV69q@|#w=sPw zy6$z*!)VrT*$Zz^It8crA5ZR9+^T1!T2O8IL z{XmZuUOYr+fS4C(N7I+l2TJG@M3wRB6lp8}rZ4glNlPa28d3i2VztRUJCCzbqGWE0VZduiv#Z?Q6a2C!fObhAO&X*;Ph9VJ;r>ulnb6Y zA&V|7s(SAu`vnwNx^OuiNpyc3GXDC7S0gN6@nFm>zRJ98FZ?Xts|pLBf__l+&spz_ z`50Qi@dLdHS4RYoGsvk&&U!~qyiM`m5yi4Z){o-xxbY_1fpl~;eMnnp!`lz<=fWX! zVjI3ZSjco+ysdaczJSMaWlMsUrNP?y!TPFTAtLHIw;?n8tJu7#9ntl~fbNp@(fDV# z;>*1waW^gtU`Z2pBGK;`$>YS=oOwL=lQ>_2mwJfz_oVH#ug#inrL5^XOS-e7OS!sF zPkI;j;2V9BJ0!kt4?R}K)=KqQsoP@_L!!5w^1vG4bCv|MNG|X8tv>9`^N`ighpKZG z$Jp8Z#N9{S8Bu)nv+c!#k6!nUJwuTt^v4szfKiuzCGQaKdD59n>h?pH<1cETo*5Zq z@FH#0qC>Fh=aWLLvyt|P$dNwzu;` zyGYN$3W!_w9p2aQkgx6!y5BOfaQbbmKS;m5R`MO(A8_wTz5`h&j`l_VPqYpL`c}-J zE5X(DJtNNv;SK0qcv0ZS`8@L4p6-jRl(MnrGssSvHs99YLY3*}t`~LK?%$cR%lEL? z`#}FFh#Sk9&tg*BG2Th#+Sm?vp1xjpUS1W^V^KZvwh^yI;(?L#tY7-9wpro(zW?r`PioU#x|Ai95J53nkeUpf8g)gKa^`Tu6ZAlPARr2g9^&tjI|Or&^ECsXJ*1i_X>&IMBJZByJ;Ob zZ@YPG5;j|zo(Jzl*0~=tuatZ_q#x{qcNQMgTz$xxdJpFJ8_|@bcj$ zk|XsU#RIIee~hJprTr6mKf5vkzW{!10)7qr`T=|?XB+$$_xCE&jTKWhMA%9Jr4JmJTeGYj6NxVTcz0(klG zmNI6$a`16Cy8HQh&fG_X0mnGouhhLe1e*}K*0KSy#6#RPlV`Ak>!S;%& z(CvAa@XmjV)sH0FCXAxuq+- zfiC+Q!n0q9l||&7gEt9Yyqr>z154*Czi&95 zfPW+W7ZdRF;J-Y8FZxgp{~Y{XBG}-!)otGv!rFcjtAoVf46g;=dt>p#Zv00HI}sOO za5w<(_yFEfc*o$yx8o^zC*eICldJViZVNci629e^eUT;7KlGT)m=%2oPWzmNz5qR@ z-^9L5Tnjzc=1pXs=CpZ_#f*=O#OE_})4Onzc&CPiOqt$k{c9qA<-g*KhyV_$OE0{= z@TA@3$mf*bi#!2ufsdQS<;wPT;rKA8jy3#ZR()caGAGyHv~sBi8t=4F6&q_==_hE-z(+MhqpP7R|Bsc-VS*4 zobt!72gRQAN7p?1g0)M6_3sYWvi{VATQK`IyW?H9&%H8aQniqov|^tHqG>vcP!2jnyx{e&f6&qJ5=Bj{k3-UJ8t5#A^}x#2Y_?8|^2>=JK(%UuT`Q(sx}7fH3tL z;NC9Oe$pXi9sMouJxLuoq&<(rJMlYy(?>T-`#=Tl1e)^*5TAz2b`()bm(>&rHCGHav7pxy< z>BXG~(_q{EW)8h|;KX4!(K|_-_s71-tf;>n(}P$aan>v=y+2A=okamzOC9`*R7Jr1 ze8L1vd19D9c(z1&#O|bIWB>oevnHo)`@fHjJzNN|&a9qRr+1*$=#r!@B(400Y#-Ng z>vX2yNc+3*oJ7}_ikM>=JG_~+kCIl8SF9%tn)@?Z^xofpawMsLKvvRc<@adkNdIxk zn|A2Grfud{tmtO3P{M;yQ*5!fXGvH8DrUOs=Qt+&&Z*j2-oA1?n~%` zp3^(;=TQAcJVJBqyzV&#Xyc=F|~nJj(Czj&nVr&$olTG2&XoO*vj7em=j~`>yYvb}PLhD=hn*M{Y#_<5@@=15Qq~nl0kHTw$S0@bZbLe?EYlq%q{rU)v znnloy#M?_e8UN$TrpN5HuEioqWM)jo&m`{RXk2YeiQ5&eM?GN$#Cx82^-jO}pu86w z|BkrEZoaJXi=FxjT@%YNz@#q@+?%k=@|2~JJob^tsSy$V{%HR;*6S&bspWw#4ZcXb z9SZ}C^)jx!`GTauu587Yhd9%V>9ouY^OyWBKhVkID6s&i^y;vIp?a!7G4wwG&Tl`KalX2j1Pnqs)Ww(CyEAef`?H zM6U&wk#;9(DB_BH-_BpA#4!2LkrIq|0k*wVwuI)|*i{B}2gBsbdbpT`e5 z>hb-XhX?(Od8)A%TEv5Y?^l3?mrDjf!Vsk-Y7J2<-KalI*xHK&-d*Ygjdtf6=Ddr;8@%HHq!-rryr%-es90^S#bS?lz}cu@;uFBrRJ zCf7^SSCErBCKCB})XyAp>_Z29A4Qs`F>PiXruV|`IsQ+=g(M*sJ1K(c)yAYFj&E&BT`>+ z0Yu(Q$U8SK5*e4mjqand`s(M2x{o@(XQA&qiR)|T!J^{@Ga3ITus<8uatN;y-Whm* zsX6BPp8OuWeqto@p{UOr%QyDkmoqOcg_!LH1qX4qH0kTz~36pH~?f-KxUr*&cYwyH|5=uR?B6A zj|PdMm$9ah@G#+Dbi(7FeLw0>F(qCL@m?X`ZzP^BLv%d&jyoO*e!Gcx?6yecCW*(f znR7q9lkoOQp>(?q=&LbXB|p#lA5XA$X|R4?u%#&2SrY7(-&L)EzaepZ@+wq^%r+6i z0|``##xcIK`>xSgoTiug{re&*5QmI!`S2$38~7u_;3u*28(HU>|AV>%qQ<39KcoAr z{I32earN^l%D+q2Ci<_p)cbzt3AQW=c2-HL>v?k4&xpMzAnkYnIc0Ou-~M9&?YKQf zKTDxM$QWRB-_$`K2-TAIMbZ}V8~v*OY5V)z-zKr?OOz5VSd5cT4=!xh=lMi1siBFn^%=)O$X)Bct3DRkEHQp|I%PU4138OI!(Gic629ej_=5D;IB(g3R$ z{W$U-qV(yb$UDUz0blQ5FO7-zrRgxfD@0!W$cX7(4vUcoEi^zm^SSgn)MqijiFa&H zKim2nD#H>A$Y9*~)t6&vWq_)uEajvIzH&jE>XaE9PYmtnogvM><*_0^1RIk;mGCyg5al3(xakmjzc}y+qoqcSp=RhoqICs4#h0 zpbKmSd6#grScY`-o||AK`)O=>PbBg+u9f$1G!}wK0sO2w_JI)ovS9jVNF}@)cs&Wm z*a2f5b3)%~bS}ZdXNgoO!6;Z7@J13Q(CfN4lK)A`zmYvhq)gzw)4PhQlm)sOuf&GF zO!ywciyZsotX=8fXy`c)Kke};UoeZGPeogUbb`aAdHA1e*@uE_<>hUL)#ms4CGacP zMa**`ohSCsT^p43aC8oJUJ&T!nq*v;1=hLN!|3=9WQ=NwMBjH1eD}gjh4+}`$021n z2yYL(8euqVhN5T3;lBX?XC7`a0Xr!lWuRVLQ+yM}E|}$ziopE10#yXFc>ca#n^x?I zDVxS=bTRXT^{gw1Jn9s0r*V1pZ(>lDEHYp)GbWU2p=u(!?2EGdu1I9QgK^^bd>wzM z(yXaq_6K;<*y#Pn5MraSRngYahb@(M}5wd z!R1yHr_+s-<UwPCMo(wMEZ{n2eI7OamWoy3b_k7*s|B&DJ6VKmzx%o(n z|53m1Ybh06pZ5EIIYRxx@BiTl^~8t_uK#Os2fL4|&zbBLZ6F z@ogT@y>)(m@4eptsS#?2ha^vW{LhW>9rO5)jbOs$|4)zSpx6J?5x#GE{U=BG{>khA zh1c_8pa0)R_&(|Lzc9jg#OMFfNYBeY|0^SW|Ksz&IKubw6#pkvJikrxe{H1i70Ni$ z_n3boah~)0Py0PvQvL5wReMsM(zSg^@LuSd)97cbf_DE-pV}$K_>RYa$me^`CcWGLm{+ycESE}?=ujh|mf1g+F^0_JTuOE?ekam^-QLk#2M%^lD4|)9G_WCHz7refod;F)o zoltA&(|^FD&0^&7$)1}(>G7ZNqIdppdDZu&wEyY3_2*vCt6u+K z_|zj#F0{Wc-+qthQO_Db*Bks>0_q`&{}h-6d?!5q&jx(I_V`bZ^6c~azZdX*$?N}0 z!1t`T9?nB4{$B-rA5HOpW0db$ivO1Z-@obWzZl{FZNRr{g#S0hACX4re~<9L8u0av z@c$v;+dHxc&XcMBzamwtf9ojUzokCyf%QLWcBN#CI^M79cS{>g z^GvMu@A6XHSERN?`Mk&fNw4qQ9{*v`7sm5mKfk|u$?4ViXX$i%J)Rw&TtYYhKJ}#x z&%reRC$9E=E6xA0t9}2J=7;lf9C3uf7G0>1toOXRsN4; z_#VB=|3HTC8&?VE`&aqDoZ&y6{#7qGzrWi5KUe!sX88Xx!}pVG{Qq*T`o%T==dM++ zT;tz=o!WKn?3b<$JaV1?qt~ggT}K(DKA!uilk(iJc6?B`@wIaZ_@YPJhJO58ulk9H zM%DdrrKe(*|A7>A=VhPKyU)_oQ+(g@_f>GX^c8@$4G2zMj zzk9QGi&VWsla-H^YZ0&rSOhEr76FTZMZh9p5wHkY1S|p;0gHe|z#?D~un1TLECLn* zi-1MIB481)2v`Ix0u}*_fJML}U=gqgSOhEr76FTZMZh9p5wHkY1S|p;0gHe|z#?D~ zun1TLECLn*i-1MIB481)2v`Ix0&flk3YD5OyMR6LMsvO+R;B_rX)Aa;r)=QHA=}^; zT&piHi+?qgwTLl9`K@Z4s~tTnqy9*zIzLnyzHGk~^_+tKw|=#mKqPxO{eCSdZ*DX;sd3 z1-7jM+g2SNcT%{4%FY2g9eznM#4N3Lk8siZy(^g@~%ir##?yIUJ%KD=BO3Wm4WZ3#QV^ z#-nrN2jDgizv&iy4cWswi|{NbJPW&%C49%PVjD)4g-&MSi@g<(@l+}iK2q25alV*G zmG`q(JNGBq zfGxHOTMcSeLtm+(ugKi*jUL(eYga?IuzjPVY(x?y1bS4 zUz6=Z?EY&Pub?IDzb1QXEMuR8W$bex*LSjq$SP;Qm5Y~nVJRfvi{4=A!bICx7Jv&xUy>4)t8!Gf zlC6^NWNV>SN#0&4^L&MQ9bws|k^P@0sflWWx~lQa&vn^(!cQ4`p&YGT~pR z96@-Oa{tHG`LxL*4A(q}B6J4_VEnXaqIZkxho3C7zs3odYx%;3lg|}4q zkMw?ZZ6wH;BwKlH2iQ)|xuS_j8`fxO1>DIVBde0U&xqY$akyL1%CiW( zaRl7`72mj|KaYgB%KnOf9`xRLuGu1jvBd7LXt1>VE531^I-dlsZ%%|NhuZxWV~8#1 z((bPq!{cJF?EZ=uiS8|%82H&)Xb&eYLj;tACZ&Nq!h0yf(nf(<{JNqnNNE#c* zB481)2v`Ix0u}*_fJML}U=gqgSOhEr76FTZMZh9p5wHkY1S|p;0gHe|z#?D~un1TL zECLn*i-1MIB481)2v`Ix0u}*_fJML}U=gqgSOhEr76FTZMZh9p5wHkY1S|p;0gHe| zz#?D~un1TLE@K2dYR>Eer3yxKz9UwT0)EF{!0*`$_+7gkZ{sW&hTpYoVVB^a{06^> zIu!|}4n@?Zh&mNHb>vnRu@_;{O_!iBNzB6Tub4z|t!RtDWrBdazv9)D_fBlyswCU$ zvBQkZTV;Pmh8T4xFBUNq-`!tv9R7pdUvV&oc7Mgem|P6U?yq<;XkB>R%XNRn zfi*03_FLSyCO9xi-*@gX`ywU`Ou)SH-DdyBF%F&L(0LAB?$GrPeXm15?9eYc^l68l za_CDAebu2?zsKa0<i#K5{^=pgfBI8zto+}rKY#fvKX2skc4*<}E-t@wxki4dDKY+?2aUY+0~aUP z#p}+7^Oyhh*Dg+O=-W`HB;rxB z$7{+>AM>3%XZCl!(}_Ra`@8PD%i!DT&;iA=w-y15fJML}U=gqgSOhEr76FTZMZh9p z5wHkY1S|p;0gHe|z#?D~un1TLECLn*i-1MIB481)2v`Ix0u}*_fJML}U=gqgSOhEr z76FTZMZh9p5wHkY1S|p;0gHe|z#?D~un1TLECLn*i-1MIBJfs2Abnm@;asKWvLD^t zxcyz{vhUVhHbI@so^Nuefo#q+Mro?e04~ zFy3(8m#ph(6lmpzY@c}Tue$5z_3l{WNoJ)1Jfe#^-`BwwjxE4tE( zuE=f~v#EEo_jHzgrH<=q)Ae90`#;U5?y}!>GLKU7l{&5m*Y(s>_Jf-Z-tl`}CnJB! zSL(Q)`mHCwk&-W%7dZAO8F`9K$ye&Qo_yBRzOsMiY-mA}?SkYhbsVmvNZqW)sL*hU zyX11_sZ2Fi-J-4_=N5E+7H2Y#yM|eKF(c%7HEx)tUOI6lYNDE;ZoPCF4s%YWYKof7 zF1%^TZNXm7O7eKrrbpc2tHgYjqq5a)!zb_(OIo1v)KrywiE|yk?8=na7vc^t*KJr)ZO-@Q(_g>!%1i_VQKgdoL?> zJ?WpqXF8fBzsc-Ur_>FS55C&bB>ROjO?--fN97_3hg+W{h`uaD%6`es_;^25$JMjy zIrS`h^(=aI9G!X&`W*W9EIM`^{&C@R{VZW8(6=9;Z(~XSEV_0)$@(T9-LvT0@g(b; ze3#%^bnUp+H;@?q19ei(=+95pN%bT3WA!8S>PP6+Nq9eo{+I|qLdQ5CRyL|Bp-C`q}4Z&82&@_r5PQX?#cG#cyc{C43Ih3 zDV5EKW^$pqM98^@d-&PH=Q@Y5yx(4>ru~+5q|bR5e9mMX?)Z~0`Mi^SIFotIkbD@t zvtW5 zVs0u)Q;Ge1D;}GvR6IVLsq1FyDmZPX@|&Y}-K)w|^fH2mVKX@0%a!1GFY)e`d%+c) z?*+%+P4}t$xWAA4`?!}wCIPZ$EbEH0#wTl9GB1<4jXZa_m_xedy_E6ZB)5y%%~{GV zE1*KDl%^(Qud}x3)lY&XJlhG+*R)#ySE|}cUo4g9C>~+tRi_(y)#*lF@wMi@_*!!x zFws;X)m#KpO?V*H4G(E~fz&LAn*0N)CjWqmt^(;!dMCetlV2d+NuO@g`&IqTB1qPp zt~BzhD~-J3<>tP4xw#LN znfQS+6F*R9!UJV)c)gY%C^Pv7%1r)&GLwIx(n(+Gq<8WQIQa!Co%EF^y%zQ+_?I15 zhWXBQNxD)c^ruqv-W;iVUd=z$G_{|phbNCoF6t;neyPZJ`YR$vq^51z5-((8)E>lh zm13Ay?WCQ?c`1$sWKvR~ROS%n5s2EU$Fyi&l3Oa#u9AHG6zt&TaNt_0cG`Oyr#&tl z0r3gsXhOlZsqO0h>Mzw6Fx-OPKLGE6(Gr@j`=wmT5$m5<&_~ny^-~F_^YW+v`4aWp z2ax}O$dBss`TONW%J2YVvK(*Y>>%y*OVlrSs1K+u(l3YT2U3g<>M=c97b#`(jtA94 zY76}`)4^k4PE0LS2kkap48|omcB)-!OWx3SOJM1sy{9L+UyAq++GzR^?Q{vC7}hLu z*gY!}xUn7%) z(l51rx)eFSwesLIE~=CEo*^B_9v6(j)VP>?)JN4v)W_6rFx-vaKSIBJBnji?BglV5 zX(nIkE`AE%PCPC6$coXW28LPBR^V~{^7%Y z_n3NI?Pk23GK8JDS;|9M^M@$!aF=JV`h?n@M|p-Ar*4t*(BAn;?w7LMcsFIpAEF$? zUGHSe15$l7)6VIx~RwP(YhpvG>oh-sxPU1^h>WiP)=}6g4ad6 z-F}Jso>ND0e&XegG?+MWl zLQGV~po?R4`w#E@at!jvh%i6j_xmU@RVV*9Dj1j5bKg6=goW^R!7v6 z>YM7@>Rajv^*us8kI;rksMry7_{raU)RWnYcY3*}&PS3|&q0f14ruR5{C&-oWPe|C z_Xe}1SMSg_a~s;SSp+Ns76FTZMZh9p5wHkY1S|p;0gHe|z#?D~un1TLECLn*i-1MI zB481)2v`Ix0u}*_fJML}U=gqgSOhEr76FTZMZh9p5wHkY1S|p;0gHe|z#?D~un1TL zECLn*i-1MIB481)2v`Ix0u}*_z%U?SzprV(uQ?2Alxz|9`g8fL$* z*&kK=ea-%OTs`y!!U^L>%ZO@Qzs@ z>Sg0(4%u(Dp1RdvMs?B!AMo$b@qH05WoQMeUXt;e(d@z&SW0l!z?@-c}?idGwP^%N_|&7 z#W?X4bvO#|yU_3Ea!;Eag@07|Tt7wFv6rt>-+NgpX|AX61&$`kACP`2hrs$2e#gi9duEMD80;g)$h$&>FxG@(mBRL9k`>N)i+*U!?p$I+?hpwFRi z&!SYv;U5=1*Uu7m0)6`d`XsB5X0GeR@Q4FAbyz~O^gd~ zrtd>!rkipN{4eZw#_4ICm*R+i9|9YY=y)5vudr8$CdSJrLDp--y(-EnDIvWybZpiTJD!IDYGuMCu@HdR%yXy5YXwp+2Ct6eu-u z2!A#x<)I$aqjeeX67-knejh@)bS< z_g{6c4}#%A^!_W+F(Oqz#)WzLM;tE7|QnneKm*V&unH-dUImEm< zjqpzT^B&d(=nON7TpEZmxHu z_m9voAJKL>o$fb$IC>bOa(9z9{}S~}_xli;L-d0& zQXcA&AFa#9pnvgkA5)L3-So@MA?(D(OH6Kxn-PCEZJ8g}p2^7ZU6K!alK&PNF9o9u z`98$e#4AS^mRu(KAoX&OCdzzR9Z^rJZ>n#rZ>b~np(FIOBedZW?9LJF&y&CRs3)_P zl4d=E4joBSJqJ1cZXpNIEwS%Iq{n?9!h7yqA2B29PA7g1Wv#(R)lesSXXA|?*&Uc* zIb3S)?0<`ZMZh9p5wHkY1S|p;0gHe|z#?D~un1TLECLn*i-1MIB481)2v`Ix0u}*_ zfJML}U=gqgSOhEr76FTZMZh9p5wHkY1S|p;0gHe|z#?D~un1TLECLn*i-1MIB481) z2v`Ix0u}*_fJML}U=et$B9K0J&g_E0m6QGGWiR{!XCDXoNqfOC{H}d)PRZdozn&i~ z+|#1>6_>raWq)hgBf5pX2U?u{K4kxjmL%;tFt{*poFjV;6jA;np|n*I^(vxX@kbGL zE4qy86km4tdOdYpPu-+lS8`qJ=%pJz+*H2PATrm3<$AD{4dGUje=TP+56M^RxSlp$ z&n6hM`P@p%P&=Sahr0}tuhelpy0RW!k^M1NQtw*MWFGGKFjmo?tH4(F&0k5~YdMp7 zlu}=*<0^1nMIB|o`<38bD;tj_@sNC_j;pBOD)N$j>Q{n!tz&ounqJ z3GDtifpKU8AnaDY_ptkArMOfR7&C_2xAKiv#NC%m z+?@%GRmt9uQub4uz&JeA{J#cQ^y)G6>Twk56VOkf zZ;#Q~kHddl_*_3m*vHYgN6|NNPafmn<4N*UTzv~kKIq%yN%q5J-@?bxx5ty@XS($v zoBx%E__gEFxAExEcrhZ*F%JDHM8C4Q&mugF@GQc!XooD?Jd1GARr$V1mc&CJ--^e0 zDix2TxcIoH+nvubocb_~5=dMwU`UCB3;s_DPg z^xx{Jo%H!fj7*L8`SVGVeevZRyURH*#c>CjROhqbZ<71}rKroFBM+Kde;0YVT-f7+ z5pcgRA_>a*^3M{rKvjTY1$w`fKD1QpqwJR+JGfyOdHvrPS&ICnB0ttI2Yp{8*BOH) z*Idf5)VY`MNXYlDmtUfOvPdmf6$L}@!!6%Ck#BG>?`OxP)X6!@)IwE}PkG|-iO)%3 zxgUJx8*7*1=vA9kMIPme`c?gNmG7^}cgmMX+q!@FaNWuG5?0{DEl<+CW4OwBp>lHL zB9=JUrL=izKRp}1@lvuVMQ2Lsm!;9R8vGrD+#%XozAqx*onJmgxKo8;BgIl)=?9l6 zzhNu*n?#T}K`YRwVe=5>NKURv zmP$XlO-)u)$YwGPJDE103~w@RI|VAo+c+oFKc-x!<3^_ntGiVfwdhu1bREdo=8#b`y!wBoI4kxgvtB9$iYrCW!d6T zGP8$8z#?D~un1TLECLn*i-1MIB481)2v`Ix0u}*_fJML}U=gqgSOhEr76FTZMZh9p z5wHkY1S|p;0gHe|z#?D~un1TLECLn*i-1MIB481)2v`Ix0u}*_fJML}U=gqgSOhEr z76FTZMZh9p5wHlnl@UmvS5!Dxsk!|Aes0`e3Um2w{#^DQnCt92AV0&Odx`eE7!J7m zZTJ;0(6d7CvnG4v$-Yjq_m%9&C40%pA^VTYK0uetA>S9Nr~LIoX{&nbRZqR@owk(y z#_FkC{bf|AMA)}dw^r&V?K+!l_q#WV;tmJT{k}*mShj+#>^nM}{N28U0=G9u)e?^>gOCT(_M-ZS74k=Dnx!w7&EV`F4e7G zR^3?VyYZaq!o8PaUq;iq@vQ5@{VutW>u!X72j>mEaz-i9{p!Y=)#cK<<>*3*&RaLu z&xkivkLpz?RWHU>FUD05#?(pJlNfKk7-K!S z-y`>N-HWi-Fy3Crcw2__y%=jfE{``6dGEzo>v4I!$uR)E7;8NoZy*tWC;KYVE*3pT z(Lij&m}-K*72~H3eH%o05dI*-g9s0zAA)ip;WAdG`$hXbi19cXT{{{T&PQ}K9c|Bc zG`>AF&%CN8sqcIX(Rpk|TH)A=c&*|WuHe`Tj&~hsQ*H3K!QTeIIC)o;_cqzv%RXE7 zjIwVLtz~&H9*GlO%U0C2)#ZM<@XohrTq6A-?|pP*N1!mQ=uPIj8uO_d^Qlj>JGx#s z=9>IeF(Nk{z3yn|n8|rF`%t%Hd=lX{qmb${rE)^+Q~y%2G^l-8cZ$v0(?2x+zAebI zx>Tu4u?|iIC+9Zp!+0vjhi>=;obxT3Fu?9r_d^Z(0o4J99T@iqaqpmh9>rI$`ylc^ zDEWuR@<1K^@N@sdl>tkr-F$}olp}vjZ^YRB$T69hdVNYn ziIb}gIlrp~{k>Ku4&AT`gr9HmsQMI6(EYSJ1crw&?hj*L9(Lh*c^LU0mi+tX<$&{` zR);+gM7#g6@dwbd+mW_3LG$u)^@KWvdAT~YM)gO#Sn7jzl!n^UKRn*P&*0qILwH`U zjNPuKIrdKm*=INLwh^wP#UEk@osk_@@vAF z+KyA&wxO^ZjQ<++c?~$$VC-)*JY^WvV18_i@}8B5dXA=y=T)aVp$7Chgg|A>g~8?Me(>|7>pD9^X(-*-IU zqCby#`*^-ZY@+Q5=J^)U8S#9J=xi9`9sx*hh8)kg2%!jF@O+C9iu1bQ`4;DeO`mxs zDS5ud;QV;L#o%0=yFA~*ArW6&6qemH=9=eQ^g-eI7JV$v=ZfcBoDVgnc)mq!Zam*2 zHXojE5u49wLV3Q$_&eX?xO2XRI+t{=LaB2&ZX#*nqv_817EXWf#916WaSq8&oY}E6 z4rk2-?y}Fd2p-`177k-t5+DH*AOR8}0TLhq5+DH*AOR8}0TLhq5+DH*AOR8}0TLhq z5+DH*AOR8}0TLhq5+DH*AOR8}0TLhq5+DH*AOR8}0TLhq5+DH*AOR8}0TLhq5+DH* znA8Nk8`f9i@7gP}@tN1x(hB??dj<2xcAZ%QzM}ore21!2b!bx^ z+E#}))}c*xXnWm7cBSUS)GbUv1>;nNXbm)?{*7YMu12)05$$R;eJOgYjc8lr1ZvY@ zXvX4v3(*>F2Fqr!mFse_EyKr6C+AG~P(U;Kv>AOU*X5`~89r{h4Jg;qR&}!+=1l^l zA+TO8QHxbTiEjHItat0o^Jz4B#!7ojtibaK+n{pPGPP7CBkdlnCF@*XPvU((M3u@@ zxoWvek@{mzTIce*blZ6_j+MkYUnEuPk9B<=K5n`@XkD}Nq2Q)FVN-Ee!w|TL9ljX-_d3ERdL1; z%5JulgXd&d*xof17>5g|J#oltLS`Z7Lo{J5y`g$kuR5uEaovl~?ZKEj340Rbtrvr; z2lspAKCXKa_8P|9>lkm+{k<4#JuZ(o$-Wnb^|(CV7Dzc5YdsuqAQ68Tc|L@c(1d4v zD>}FheH(;72!9Y`EQqldL_Y-OKEh?JijH;=<1mQvI2m0#8kMN?A>zqTx}z2S(&}=* zIPWlCB_m1R+b~$PwF~xQ?`Zq;j4d>_RNGqptyHZ^UnLtIxT+L8zuHVYzuHVYzp5*u99g3hU8$Iv*m(jHgI4a(f@v&|-WN;X>y_U=0||O~=iBSkH^`Nrc;i zLaH(4a_niDh$2T-hIG?DbXswg{v1{2lQ^;L3B(P3K7=1jXc|80$@uLUj}bq%{%QE6 z4|oMYpnlBY%ZIq~6J0-d5PftI9diqC$8m4t=s z0GGa;^C1eN>}NBiK4?cts4Xs4#AN%hdPH?#UKUJ{c_}*d`_bPeF3-y;QV#m4BuYQI z+bi+Uy~t$QgmM3jxgO8wL!_aOEtr#Q6ErWK^C1eNyf>#yeK052CTLzhhw_feyfo{S z>9TQaEa8JWxz^=*Ic@>4VkAHUlZwD_&WD(Z7T4gJu`SATV>|oLA|72 zRGoOXb>ex`i9Jsz_Jf^xcRcZ~N1Z5CO143rSlc^YYUhAWe-vcRM6eZaAao=^0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{ z0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2J zlb^sa&xa6Mw~2H<#8BrZi0tEJI5#1hIzYz|=U~Wr9~0>uj0^32h{?b3u!STrastlz z3L?rl5zmKk&Q}oqnTdElgmb=vKHmcRJrnJG2uKT!>U;%}2Ta8I3L^WLi1QUhPm1R& z0D?)rQd zj^`d8dwqKMk-GNq%VSZ#&Rg$3eB8;I6pr4#JX^;??>=0AU)pw$*+*!db?gTct#_Ye z_8?Lhara=)G9H~ip8);mw%)z$yQp{HHv%w62b?p}7dr6j8`$q2M?W3M{`PoiZ26K? zQvHHvCzBE3ESU?S5n@S#zgNvN`1oXHXg3^`2^^1>fMjLH-@9DE$0(m2)f#G z>`EeawVx`|TMKo)x<2U~&Y?etg)V8~qrS6er5|0?&o;W*jcxMQPe%eIKmsH{0wh2J zBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZr zKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH%=?Qo%t|%`X*vc|!a+E=vqYRo2;zSRs zY=US_NPVOI)%;Mp(jrANk#wa+Cwx6b5!Q=EU#&-WVG3gS^6qftS(iTj9K}kEx1}0sWqx_wAqYVdR=ooOIE4^ zm9HvQKAxTVSl`=h zcm_n%=ZqIX(G$$avn5>rFkX2}K2Ce$ndd~xOLXCKG2U`9hH}I9Wy>*sf*4Vhwo`=53L%-)CT(mL~r1B&l#^YpkxoA{4pIo%nak=1-8=7ZYhbyEFm+-TteiV(>?M&5oKPRzNL=b}i;_ZD^hJrTEi3I>OVG+QUEm zmcEvAAR3Ui9-lrhB7rdVm%dXnEWVMc)0=jZp6IY zh=NPq-LfCNZ@1W14cNPq-LfCNZ@1W14c zNPq-LfCNZ@1W14cNPq-LfCNZ@1W14cNPq-LfCNZ@1W14cNPq-LfCNZ@1W14cNPq-L zfCNZ@1W14cNPq+qN5H#bePzYK;wqpaPyu~}3Zsv(08uLXX_*X6GoJ2(c^d1Nx7oQ)QmaNjKLv#DCKCk z+nWDXDA&z)G4IJmV1vq0%b;IrSYA~k>VI3D>;Ia1L%ohXdoTfB!#e%i z8BubJpDQ$3y=80<#%Iq6=9mnJlZf9tf;8t-dtDCd*6Z^8IiI>Q&F~4dBWgRwN;~?o z9i7^aaosMHQ|@Cg(jMBMYaOnT{&zd}My-g`ittv%YZX88X+=J*$mgyDZK@6aHu&4% zZ$rMaSC&1U>>*`eC7D_Hhz7psdCM6`GHj(JnN^}?7EK3xKEhg&XRE0zyskJ~eN5^k zJ5aGwL$P+jL+O8eRi%l)#n_;>Bh_gG2c0k)51lE$CJli?(~>5P@lEEs8bhxd^QlkM zG`gNC=GurKOoQl|4$%LWGZF@KGI#f(ZpHW{!fi$&)nzz01AGQ^K&AGfuEkO6J6M|0 z+>_Z|T?+lm1hs!Ob(OTDL%9!-iUkziun9Q&-%VKl?^XA!`_u!f0}MOR?*}m!59-H4 zeD%K%BL9Pue`qWZ)a92mN*pI==N!Z{S)4pu_akjdg2v^8>LJx3^Dzs>NJ=GI`(x-GP?b+`3@aP(_E=N6wk=TqnKpiEl$xaaIy(XKtGu2t9R z3hYGvcA}m;(FXbLe6;S&o%S!&UB-?!Kc*)E5+DH*AOR8}0TLhq5+DH*AOR8}0TLhq z5+DH*AOR8}0TLhq5+DH*AOR8}0TLhq5+DH*AOR8}0TLhq5+DH*AOR8}0TLhq5+DH* zAOR8}0TLhq5+DH*80Q2sH)#FZ3jD2oMVOXAq<*dZx&1`auZ^bbsyub74u7j(hriXY z!{6%H;cxZp(Dpi`w~>c-P9$B|p>%phKV&lK^g8;r(yxiquSHQI{aVoxON4%{=;lfr z9sODnfl7pat&}Tmbo6UQ-z*XOwNkFMaWCfNUd&0+M=QsCEW^i5w-Mz^8~0)j*o!ql zbnVKq{*{HTfo_y9*(($99*0Vbo6)QlwHEJarAdZdovOG z$G2+L&-gWSlUkz+)y474Fu^%(R+p+vR8fLUjbCwFl-J|&#JN-BSG^%~+NzR0Ngkgk zapV6FBJ>qEca`#cQavdi(QliG`q?$g@}zsxqP||m4U|h66(Zjz>@#0gU8-BXth%ue z>&E`C3-?}zeHl}`8+*bo-0zb6xb8;Scg{>xubfe8F4A{n&(!78zRA%Q7JcMy?A5wl z-WSStw;NwwF711r_Mn&x(uv;aO?bC?L-nX$byD?WT=imHi7xy}*pnDD$6K+KgRyqX z&%~?hbvmzVGaQXc@UiFpp&RWplYh~il4V%CvVKE<7pHh#hPpd;< zcnIVEFy`f9Js!{d{H#Hrmxq!6VaY!Cd}`-FL3E|&VB9i^eR*x_z{e@1;)9m2d^9kEV)!tjxo!`o5U(un%HRi7u- z=hUG~QJ;wY#3zh@sniGkUF!0@l%E@KN13G&^>C}*Zs!Z6+TDbH{(}0F`l9-Cbp#BL zVB9~2zJ1DtdHEFbe@gNXjpc#!(i`@>u7%C(Q)b-dqqcV-?PUp?mtR(2QAaQ@z4D?I z=AJh5vHz&r@xMP)I@;$q$Z z@qJz{M*fQ>fB6wdyMgo43WebeXNha}ZSsF+-HADQd4lF;o@a$8P>wo8%*!Qa-6)j$ zU`}41pm~|^Dewd?LwzFV71`AdiRMrA2Gf?Xk`q0-CTMY;@A+^d7nz9j z;Y1cJ5$D5+%pT8&0|b|xysw0x4y2T07(cO&ls-bV46J@^*N#HR# zKPlSz6oWAv%X`vI`_O5{QTlT%>o%Utmi?=^q0dk9A?|sdpOh0e?+UO^C8@%%e+b8{0Q)Th>>x- zb!5?pjLq{QhD6ja0?&u&ha>JDo(~asr2R7F`4IhZD4q||pGUlXJRc%9(RKufpP$hV zz4dmZrOfjojBqy?d6kSLvG$9iSJ{xfDq!yC8Cz&cu^4sB--w6-s{CGZu#xQBV>`}z?A)<9C&xeRcW_b5` zKE&`iMaJU!5RpXs`yW&fsg5$7$H4O;`hyv!kLN=S6I4XBBID=z5D{RE_gUCuGB4%e z!$BO+hZqD(*e#w95e9>oBtQZao&e8>Q0m0H9(4jQ+vDYYh~mM|hnRNutPHnvp)t1; zKLhQ=OWaPJv$iwJ8Hu6D!?&cbcA?J$xs3JH(^36KB@kN^pg011!)36KB@ zkN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg z011!)36KB@kN^pg011!)36Q`>cmE8_5X?TJDqe}mr$NybL8_}lzO{B3?C z{x-kS=wONLV_*#;p3*eEzX%2BEKdue^qs`%JzansF|aSOgYXA2u!89HAo?LF_Yp4IwsRyL<1mQvI2m0#8Wqk*^zI!O zsdukbO=vi^gHtOa3ddIPY8Ah51;~XEWq?vT9r+kz{?RyKo5hCwya8I^qBXS#&|3=B*%vWTQ;!p4B2+yP-%6!W}qT28$KHds~oIb!l{+@A#DzpPbOuY9GFe<$`Y51ctA7-UZDC;UN0xAm-J<&{!U1USgeaT#m#y^Fp4j`;oRJLG#kl zyU&Rz?;f*Xm*@O`w4)@{7N^$k*oW04ssr;fC!)N2qO2S4)MEI#PDRxH=)V$|=cVks z_G8SHgpHfw*K+*DEHYJ^D0=s@|82n>SsO7=+#>7f-RFe%4*g4#_oNogk+l)?q<^gV z`JO{o$K-h#r9Sa1DLy&LyGje@%rg89ei^hi%8Xuv=nIrh5UmMmO|-w7?-)W?TI4$>lCHGq zgs+Dv!g{gjtM%x!_0otiw;oyw>s``I2rI_b%WKfKYtT07*K5(9-T1iasz0#5Swy9- z0n2N^R<5rF!`&`(lyXIQZl`IVTwe(Ve zs#smBE*UD?xDBsXMbPyv9Jlows$#n4c$TcxI^dNmAJ5KwtnUSQwp7Aa7Qv4-UvxS} zTdM%q`3PG9{p`v!N{PN)KAr&uEbP8R$PLXiE%7O`i`wOa({fx1$K__Pv>Y6l1K4tKT$W=Zx@1t4T8_Fd zce!75t5MeZ>SvF%`N`^t3`y!|j}+V_i(eSlo~y&I`(N7n+5PXGzpoaPsuuINHndI- z)afmii8qLog`ojy>+wm1yAFlamMT>mwq7No+{sdg=qfj$FYBZ9=VWPTyxZaEXG^{{ zP`2NuHmeQwLYbJA(kR&|xyQKnQ;l>Myi#~Q$?K0)(#i@H+nz&cTsp!Pc) z&ew`gZv*>FHLN%}S78;#=IRMLJ_Bl(TCA3!6-(7F ztlhiN&RtkrccHDjuvRR7*P|8}DkbNo?LwP(xztX#e(zbY)~U(&eNLTA z57YmC;Oy_tp(5whwWc~d!E`6a(@wCLf0G-nYy7aig)206wD~bT36KB@kN^pg011!) z36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@ zkN^pg011!)36KB@kN^pg011!)36KB@kia-6khEcaWrb1|&-?3NV@7XJi zK7z;vRK(%$+7m^ip8!%=p+o6^i)`RT)BkQn-!-Cd8qrsc=(9%jU8Cts(Y0uV7DS^< zdJkb}UA=5Z+nUif>DO{xJG%646)HO1l6Ny$HiNAQWR;_Q(ZqMtNx9O-X7p(@`cU-0 z%TWi><9E|Jdgsj;E6o@yqT^AHcDt?l@93So*|zbR_g?hxUi7c%qm_es89r{hjTl#= zxi!(<29=|hLE}br%JyI#Sci|B?v^-bUIoS9T&-Li=Zq7SUA5NDUXh^E;$O^0s6efP z`u9Y2o3#4+#S^vqTGRR_%-J_okLpz?RWH`TUOZ=d@LW9!d$I_AJnMRJzen!lx)))u zL4W=AGfK@x%X{&B>Tzj5)^OVRsm$9QYU z7-~0rs3!PZF@D<6w?Tvl;SVA_i0~l#At?6|E?TS7{i4$z#CV*Ht{sgE=hKe1wxg|W z;Lwi7w}&YDpiQ;G-v)mh{B6ir_O+6W>_cSV zBhPTjP_%&MJ!K?r0V1~|&sLZFMYkGdIr{5TS8VL6ZEN*6w4#-a zM5U_CCafyO_B;7RwRW^nc?07413F*JpJ%LHzU8;e9}r*1>Z^Zbc(Q6-B2h$dQk+*+ z8oR~Vpt1GFHX6G}+bWM;VQ1Z`HGFCfpIXDG7U#H#t2OnnHTAFc+x4$C^{?^-B$}%7 z*zK$G*x^+kJAGA}2~RWOX(l|)gr}JB6ce6e!c$Cmh6&Fw;Ta}8!wyH$W8&;uDAj~{ zwaL_=I#a1?%%?t0+30$*m}~OtI3hQQo@~nS)MS;Kjgt1EZpHW{!fi$&)n!WMgx072 zrDADN`>^g5|S-hx=%fzI>4|4 zB;cmF>?O;>j#nlLCHTfmgQW8=tSh~qJwxQi<^$mexxl) z(7b$5J)}BhUSiz}clVfiD%IGJc9ewL5*{o5*AJ^lR0rl|j^W{ya8HEaxj)ucuF zm$*DHCHwv8qmqbz8te9-Z~4xNYBymHKB_*Y9#fxIhtSAF7;uMi@30H=@-Xs0Ecu7V za_o62XF44=<1T=P-j1}TG9eP+9#>DOLztIxw$xy5F>csuS()L_0gthn;9xC)S@6&|g1Mh;zx% zhEBA()1`Jg?_KdmCHtP6Q0JX!)7v=H#EP;12rs*~Pe0vz4u=|wYPxsfCz2igbSG}y z_0tbv*98}BwXIVQEeVhS36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!) z36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36Q`f zCE(dGEd6vy08A+T^qr`1EM0Mtv6~FK;?YKBrK(eP&}pcHMnxU;9O|S4!<^`lP9&Z9 zvCvN!?ZmOrPam=HU0A>Jk_09*0Y^Vw=Ey|WPZyn=Jy@I9xvZacYn%szqn|GNs(bKU zS%;6C?zT8*4hbXG1m>@*F4e7GR^8Ay>c+FN3-?}zeYpsJw5bdCyW~EuyAk#s=y$(z zMk!pXZs-VgxvYOASi7OY)D=bVEM8bT*f1%Pl>pc(vc{eEcXNT%TIX8;O3m z=$u|?`rX1v+(7;An$U0>seZTQCrVnfr<1+^X!W~AFL*5UyS)mVdN{9EoD&-`ep~-J zQolO{Ovf7fD^fpu=oE}G841X9Qry_DQJoozPcf;euz0l7L@XKRSzWUvFau{5{J7Qjjjk_Fl zuA|>A=QE6nez$DY!Y$WYX`(Yom5ecpf}s zu8)D^F^t3Gq2FHPcizP}FyD?N|KpN>Xl(hCQ&M9o>zj(f$o{tlY1iVD2=^=sIaUT8 z`w)x%rOJC!3)-r6YC(Um#fNTW1csyEE$2*3 zRQ>KI{1!D_{chPlCsM!r_CEdW%ySUWK8J-TY2l~R&Yl$|ZTZ+P-ul^ryX0*jznvHz zZMzhHlK=^j011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@ zkN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg00~T50{-FYXN%r) z#RSoskiN42dVY{z^9VEuuBZl;JHB7%v3Yt0ii&3MkP9orwC`j{djSpN4kTMAOf%Qh6#@ zE!P^f6H!0g(f=0xuszt%taEu!b7!0ZIz$buT)%2W!_!*po%@V^HXOxm{buaY2dR*3< zm+X5{SdZDqyM#k6kaDmu>j~2fjb~XS)w_;o+2bKE>dnXQg?0po>+!c^&b4FiiHp>m zhuXZzlxlZAdh<@&cvz|8M9`bBHI1!RG7^=l60v=4ZGUa1Enr!jX+y8dvi((Aw%@X& zDa&tPSbjU)@;l)HouB2;Gq%v!Qrp_mm6d7IoANAEo|PFe@$B@}yVp3z{LAje@uxR0 zTGoR(xjhzo^U?HkMZa_(_726eK}~?$f-%8^m zbEHF!lQS3`y?L!)jL`Pbbd>$9oJ%nldh^lF$#8?gX!4YEG7_OT zuXX>?M_2 zWIiN70%J{JIOjmfd6*Z%IS{f9O5`~Z(fa=WLC%NpF8tKJXV3l~N!&XhqNUCLKU^x? zZ5yqAyiWooKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2J zBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH%NeGzpAtGB- z0iCuA=;2fteL2xZok-_H40UdT$lOeZa}%Pf0}OEvhR6<0q;oKw^C3jnyBuS(%#2HT zU2)YoFF~Y1n=ucXp(7`1o#mJhW%#)1oO2qS^C3i+DpBV{h-Q5=CPp&`hv-k0qupir zxaq3E+0Fc!_v9kroUb6mG7;xP?2R)%=X`}ZQh%%^Zl4cvOPuTPoUb6Vnu$0c;?_9V zf1_HhR;iULQT4wq&h>u{O8u`RPtoFk4eRu4XXFH-__;!p)mz5OIRHH)c-D%%?@7e( z9YLD&sl6@-b(6CQ=q4_Kc2s@1diRKW-g@_Km@l$dmOY*9A!T1BnTd|1Xs?P6u4ui= zuodxNnN=bTEPJBCoSY*!5%li8s!~_qt3(l7+7{GyfatNl8~qC$bi!ynqNilYL?lpX zDlNL&o6L1JCPy{a+l{jM($246Kk4);d_o2 zp|J3~_S_u{z59X?i~jXNQ^rK^e)R--9_sS|0I66&(G8nGNbepS*w}jaeOdO+Pxtih z^TOtVXuCUl_gdE+V>01-_fggft-p`3k|^PQ)Z%mXuzEywlq!`sLFT1C4*+wr#N~M@ z`>y?yNbg=o%W(92Mb|cw`n`wy^lOvOErMdLECvfdnSSXHHwIWY3ne=N#$7(X`*H)@JRR;}~CJ`n7VM2>n{o%^k7u6Y54s0v7@SN559)NFwxW0ux*De&Lvz#gAVBgmjw)cx?Sx$T6ndd~xOLXtU z^;xCvP1u*UV*IqBZ-ej$;SXY91<~n2^g~eYBV4rVMCUq)aTvsSoQ$p=jSA<}jv8)n0jRpSzgN}bwa0-L1K3QfD3Ft5gweywO@4(3F6aZL1UvGxq+L<@T# z)}3Or_6!y$p7%tZy1G=U0`%8Ja9EnvK73KXc4WO3(yzsH@_hAc@eK6gSs4160e*Qb z%2&VpPR$OYpAO(}O>%y4&)*+*zSU9=<7`n5SB zc6P1qiL!2l*Lf_iwZ1R<&u#r$IXhr7>DLyS&T2xxK4Y$rf#WfZ!{ebnZT$4!zkzlB zIPyO(`G>}qFF7UEA3Eb9*7%V#99oceEk22G&!UiHWlH6QSoAMd-jiC;j z?>S_6OrDof>J#tsMw_3Ux6y+BUW*Ui$OsHaS6cM+6R9gbvKGXS-Gpb`^Qu#wP%o&L z)QhSUbEp&RP$$-iPVAREF~(24>rp2Pl|Hwr6Jw||^j;l1?~#T^zHk1u(a*kKT_3KW zoqG1H(O`NZauUV*1M#a5MGX(*VmwJ*Pw0E zuh*hIyYX?;iH^01N?ik%*MO~DUkir2UFJyrY&UzAc~5i#8&s)Ut4bzpGpbavx>Q{< zVe4P5ilFOTIAQCrYmR5hN>!lpRi(VJP+Y{2+u=bbP8R z$PLXi*@3B$HefC|EyoSvxZKQ<<$$#u9G8RRvK%KDcdY33E=OILyWB6j)hNrWWF(1| z5h2zt*sB7@FC$6r7aCit?MT0p)e)T$^|MDxZgR!9N0Hs8tD`o})&q?iJi>rl4DDLX z-`dbRIZ&s!$mRJq!YVWRc@hvk&<6B(Jw9~9C*bI3ONtsO+iz2w)ebP+fqAnX&!g>n zeq{Fh`3oLAM*P@{rQwr4U`vKT{g}bmp!(U{k^gqdKi0g&^Vo5v65l+N<*bSZ)Tur} z^LDGcO6@39sucAd%!zJr131-(?K1|87q5F;)Rk&SDe4nq7q6V%$wzh>4XA6q%k`E0 zMFYl6eb~5hr$vd$wJ5BZYID62b6{h?aTZ-aJ1qIIE;k_GjhJT}G0r!J`pTCyT>Wej z&u_rqxjwYN9#*mE9jOW_H_ANd$K$-SyWkSaqTPV;RBzVR3l6|&8jN{zv09~8Bacuc%!gry~yIgALfXzi5+c*|ky&Ka1{+T+5&BNWOgm>X#>+J7D``bPJ@4^my z3)f}rShSsGk^l*i011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!) z36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg00|_HK!>vR zzssN#P!^`e5~=?!dUq2^|2vv4_IlGs(J7!V_Q=QC2BV8T@{~+L0wmxTf%R&gx?EkR zh1{;iTD}_}H(j{iRXoaZbiGBF>RPPPyThJE@yI_ikIKj!qx6ezTDXp_WEX(Wj_A`a zg%*#9s>ag!6&>aaP3JckV^nl}!*zZ|^`<6FL`dR<>-;W9{Qf$>OVv_vUJ5OzrA7x$ z@(@8o(H<1NKhc^LeJ9cG7S6+QON~B~=x|R2onK1^Aly-7Ei?a*8f#_R0Y{CsvW?$Z zD;p3cy|GrnPI%N<%Lq^(HP$LL;l^5}#&4{Z7qIg))+)@i{l;3Qg|^>VM{hV;HHwIp za)!WB9SePzZSptPDlIkXZEG2QB6K?EU*~MOMN)G~65c8=vq}3N)w-9qp zmh2I^;pqIX3zgkJYpolLy4B;82)7G`1k0l9cgnhw2)#_Ft=CC?Fm%?rq~GS06E7=k zZUe>>b$&-i)Y173U>?+{YUuoK92Yvj>+EGxH%7)_xX$lN%t<*%BN5Kg`CW&-)nHDZ z`zx^@kn=kd;T)acbuRB)t&J*<=M?N;G?>KU1OhE!}6L9nqMb|D7`iRAGZjk7?h3g~cLf5Dg+B1Xc zBTCVE(2U6w-9)2vC3-#=nm(d%5a;M4iWZ`ykEm5+(p9?XC&oh`QS^XB>u|VE^bwb$ zY)LmB^bxI0Tgd3Bu>LofM=#OQ9dvXE?a)3QLdQ>gVG$?{Ywp$NdMk$7 zR_L51Rv$5}A~7zt9wF9=`Y@fg7|}-^bR}}wD*A}_^c#?$*8js=Uyn~B+!hqFwG{P9 zkPh8w+a&8v1L~S6JUwp(=iD@<&f(g-@Dr(S>mwE#eZ($fbtU*k0wh2J zBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBtQZr zKmsH{0wh2JBtQZrKmsH{0wh2JBtQZrKmsH{0wh2JBrtgicq*`EHkWW{Tq6 zAV=R(bb=D0?^qe<`iq=ixW1!gAHcJ7Fnz~7JX^!{9YxDY^m;EeeMixA6#Yg=-%*%3 z`i^ofPU6Hv-%)hoM2k&0566kVqd3uo91r@AUKNn)V1DNrTWD;lwpN6mqh;p*QDd!4 zJHk<8t!(2rc7R@Fz)pD7SS!!?jkOAm-&o5CTOBpl$_wav9W~Y}wCjD;SgX{o|50Nd z-APA>Qub%!LVA_iraWV<(o#FzSW7E$N_@LrmNM~;wfy!*_NcLz--H`$Wg5S+R(8P7 z-&iZ#)ZbVu+tlA!E8En^SSw)S8*Am6_{Lg=Ccd${urc_uYh@RFwJG1xc}uLmV@F4L z^VdbuOVqk;3DgVRg-QiQ-w|u}U{32zBCI}2_+V*9bMHDN7G1k_W_=n>UWrJn^)E5? z>hYl)J^@GHF@SkcqpH<5wNdQ=!yOp=+i`EZUam5=46>6eJlOvEv2>>4lkO~`POt=O zF*|(u5LdQZ{oHoszg_YVjb&eoKRsez>T>O5G6uIBJx4h|VI|TQ;FAcqRb8caU|y~> z^Ftu+sVw01W14cNPq-LfCNZ@1W14cNPq-LfCNZ@1W14cNPq-L zfCNZ@1W14cNPq-LfCNZ@1W14cNPq-LfCNZ@1W14cNPq-LfCNZ@1W14cNPq-LfCNZ@ z1W14cNMQUB7^c3X=r>FzeMixGqQ2wEhavSHN6w5XNWg6Zjy|FY_#{Ffu{h2R5;3B1 zeZ*X77*#@hW-xt3DLPyqQT(FkbD`-YO1s55`iP>1C~7e^fT>ku(p9?XC&oh`QS^XB z>u|VE^bwb$Y)LmB^bxI0Tgd3Bu>Lp~qsBVAgN_cN9jep-5iKWx_JSZ# z7}m`$`J`soro9T^j+_}&kbv6+)~j{ua&?)~`iNM| zce|`JQxxY0Ir@&G6O;&j$I3X@Uu5*c^&KVq0G^$L={x4(*&43zC|XXU*L$JqJBps8 z=r=n0j>62*ca&>!5+@$|j-m@ET5Q63I8O8(#fc{5c+hwBs(@4n^E=PjLSsv{wTzCV zqvvRu`G3?{E7Oi})L1Lq_>CQ)7a6b<9yQj=Gk#;OLgP2qGQw6zjkWRux?V?(wF>Qe zA2rr0wd;S>SVwo#(V=v7CqsIb*`_>Wt*JP;u~ufn)t@*#*D$2T`Rlbt4;Zi z&Rb&j9XmS0o4+oKUZU1*!+S}h^a6LGQbEyo#F{;r(|VH$)JeNe>Vu)P&a6*^)oDE4 z)B2Z~diD6w4WEFc?-;;5s8Q8wo7$*$fZ+~|{q4B7T`yOe{q!A0nhuJ@SUS`2Nq3ge zP@xEv?V)`65LdQZ{oHoszg_YVjdfp&KRsez>T>O5G6uIBJx4h|VI|TQ;FAcqRb8ca zU|y~>pNO*>pPw@x{kqv{ibkyJDItW011!)36KB@kN^pg011!)36KB@kN^pg011!) z36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@ zkN^pg011!)35*{C!_;>a{f5b;?cY$eA$(3Ajzb(MJ>kpG4>*7RR|k zB1ROhkC+P$qe^Jc45p7LMThGnieL16E;M~aX}35>A5pXrMJ=WVFtut-x=I)Q#CYf< ziXMl38Q zcNOYWBlStpx-=BFZ9_zm=Y9kFxjsSqkwa8x%!1b%eZ+I>ocCOXQs*$Ek`_LC&)KuT zN1e`v>a`Q=|4yu9JHcyb9M<|nMi;S>`iLRMydVJ*AOR8}0TLhq5+DH*AOR8}0TLhq z5+DH*AOR8}0TLhq5+DH*AOR8}0TLhq5+DH*AOR8}0TLhq5+DH*AOR8}0TLhq5+DH* zAOR8}0TLhq5+DH*Ac09uz`J36CH}6x0=fhhVOj_k_&fFr{5^Yx(KVS52o-VoyY@t} zj3#{1q3To}+EjpEjcp zMK`4!btuEfO(*3_8=Em!nlV;H|Dzo3c3Trw%9S?mMSt!EThRk5N88Krann_yT+!6q z3$A<7PSJlY2k)}5HPDUnrM<#-FWR>kWl0^%!Mscs9v7XID{b71a`vKsMgFZEw#?;q zLCTdj#>;I`Ick|&szkqM55~+om)C(?;#F~zPnF73xlk+=ow7X`@9SJ%Pi~EK{i{`h z%2zAmoNMB;6Wy$vFlOFRJ*rooRK1voy_o+!=!cWACyU_6n$Uy$J#rt{y$E~l%ry1- z8KveReJ|!rk4y8$(OaA=}9$ZZg-^7=P6m zQyVe9Y-j7V;kl1Tu)iNN+>^)Sh}=fxzftlJ?HPP2{`8KH@JtG#jNh4vv=3>E@kxZ+ zj6$l*lq!fa&ZP9?udEmUv z(d9}mO65p=GcTsWzaME!5;QL#R1c{R%*&i8<;if{k9L%V+9EY}&poUjQ5~3A`vIv$K)L8dbaOw}s*(w^UJVNcm~B@zN;E2KF#c;WCu(r722i&dp7Q9d!82@I zl;_y6${B-5djE+!??ivSt*%s4L?Cz!To7gU({n|Af?yp)-K35(oJ8X_7`7gbK{ZEQ z1g@?@6qM|& zZNL29EY2Bz&hl1j!p&n*|BfN?e*1@W`^6qJyJbhm{)l;g$!{Oxerdu@wN#p^m@^HX z@?>8X?wn0{-c@$L*tJxu%cOT6OU`c{@}4N}ZL{fj?mxKLzHj9BRWQf)%kLTDobsJz z&58Hl=j`@@yT0`YDn6X{Po-+2dv1g1`H=6Q| z4H#Q!Y^AY5V;hZaF}B0lL&hF4_L#9<#-1|vw6SN5RZXURV*|z(8e3^>(AY*}Ta4{6 z_K>khj6G&-m$9deJ#Fk6W7SQjd}9N~78+Y=Y|z+7V_S^vF!qqKM~ppYY?ra8j6H4a z8DrJWrhH=q#uge|X>8EgMq^uy?J)L`u}6$OW^9+Sr;I&q>=|R#2Tb|K28=B(AY*}Ta4{6_K>khjJ0ze z`)_}6@bwMru6DA_+E@MSI%k7d-^elcSa<*Mz_oV1r?0bZF*3}hgxE%KRQJEGq=Z1f83;h(b!ib@~gZvcKWwW{GS;6PDJ{~A<{op zG(`Uok^VOk5fI=aB7J3#U}mX zDCy4(k-j2Iy&Zm;AC6uBEkmTQ93p+KNq?QOH%H{x@kg=Czum-di%93x|Hu&O?~jts zN#8X@`okvuXN>(qM1H4-NdMO+{x>7iIpwRnVz7Y`w9K#_ln;#n`)y?J)L1V-FeY zq<`G_j~M$EW1lhhMPt8X?CZup?fmo`-e*6T?l$%jV;#Od*W2N582bZb z|K8Zs#{R-eRm1?v($O>DNCu_N&HTX8t{K zb5+&lfxK&O_|U!&ekibJ&FV{57p_|KA?;oBk)op2g_o`{w-x@c5@jl@OG!Im7xrya zX6_yK#jlghjR><6ey^HeWd0>gIX|iXiSuuIgU0`2gA>2j77y2OtEIp^OPBjVfr@pEjn?fSQr+wm_q@fVo>h=Nzy^?T{#PWoe;?DQXr zQl1^Z=`Wr5g+V)hZ*oM%jMt9;^B0`>YL^}V=E#4e?HB)_e&fV%F|RV|O|6omYt1@n8Lv6W@7dh#mh2&pGj(SA^K{&%EWtFEptJU>orb%XNw;@e%W>>zO$u|9e?YsPJCwzA3Ofd4?FP#X3Jk3 zlh2pG;>2$>|4+nk2doVC4ST*f_JrcM+8HOu%zx86PW+ZOJK{Sr^MA{i?5scLmE-d< z;~!h-#8>7O;kB6YPnA0HPYo;nnX8@n&MQQ0{%3D-;ybSlvE%>xUMK!(^NJ9={xd%B z#CKi^V&^~ac_+T}3J^Q~tT&zb&XzxR{EPmt6W`h5$Bv)nOELXhXkG~(i`idanD4|t zW#Zo#Gk(&gPJHLc=>LitKm9$S`1jc3b6d>uT)5MTf9y}}h~G{bya0Q?6y4#(?|9gb z{~z|hAP-1n$N#U#L-C)m<2T04f9f+%{L`Pe<2S^Nf9pvne&v_!_&qWA8)g5;iJ$pZ zJAQZSfU4^ocKy{KocO1owc}UB++QA;nQF#^^S>m1D`x!Md?)^C?1aQ+EzxGcmtCKK zxY>!Xerm^8GX_M}H|+Q&p9sbOH#`1q&i{iJk<5<&S3h*(w@kHn^Xq3uL^NJI{;gB} zroCMOJN`dK*&oiq&OTXr^k%f;H^^kM^FQnVZA1Y{&*6XDOL}vTY|PXBsb9i|yRsO! zvVBVStc$*dFTHtP^dj!cRnnqgpcmzZ!@sD-TxH^aV%XRw{T(6z=qFhgvIHfbcE7!9z6Ou2R_4ji9=aSFmGk+o1 zS6~JvubU+cL()&BtSvL7_@r-0O|P`e{b$@req2{8>1+6(t&^Xauj5=T@t?G>cSt@* z=IQ<1?x{V$=T5*8lxeBLQTg6Qb5dp{%MeXcizQ?1!_^W&=2J-) zlBLY{{U6-Uz8Y{cQ`0l|A>8)_vQC|1=_j90{{BC8>NH8{S4rPP!%{PR^8aBZtw-+u zNOsjQc9tF5L z7uUob58kAz~oFQXn_MNz~rW{3l{A0M% z{a+|oYfhoAhvh0g;JXafPtQ!MMYQy!q-ljP{-l4gZ~hV{cQ5KX#q!Mhk&F@dd)kn&|0AF8f%5NMOLx4 zms)RXTWtMQ+Y;+n+OD;JtL${js*|tcSEMvmVp-3acDTn|E4;^$LpiPFruS z*Y`JA+qA8+8nmspnRDJ+pH7XZns|1 zHfUX`;2kZVcnr^r6qsL?af?oZPs>!b%VB5)*owIZ9T5-M(bH^ zH(76JyV?4=wmYnu+6JxP!RCJx(`EXmsW+m3HeJ7~NKJolQr70_|1f1y3+|{b|4V|e zn=-2vzM{Vq&xfYWQY+fgbJI(v=9i&&W>ieQ5)<&sD{$?fvD;b)kMABtopIe%d4Q;` z5;Eg`nWebyL_XieXIfx7{@-{Ve96CH+%?MIaQzqoKXU@rCGTJh{_{X6dcXXyS_ zzefQxZk&1xa7YHzu*%HFXIc)jRCA@UTW&#=T-;kF_oXQN{%v0Z>I&T3>fHC_hXPyX zqo1!szz0HsA3!#C$`8JUzyk=lHxziWq`dUkh;s0=s7f)spF!XkLlJb=I>LQF!Qv+o zUPR!lp$IyMxgE&nPuJt-+xYyW6F5yT<8wcY+41rJg<0`i1jxR?1}Ax`n*Rj28K2Fp zL5pRsc;+H}k;Ks?wtX6f&N!BujG)UA-*agwNX`BjaC&F#%zO{-;i7t;+}K_uDT4mb zfw?r@BR5sx=!0e)}7iOwmz=y zC#+$XRJ?Y`&p|~+b6BJ zwf&ssn#0|k6L$W`vvP!ZNFr_pzT+zpK1G5D;a-{;GOkXR=&2! ztWDZJW8JLnv(^LJK4(3x?bofBwEc$lwzl82exvR4Rt8>ayt7VNmumZhwN={}t-acI zS`TaclJytb{*CoRZNFum(YD)~o+atOZLQMwJJvRBU$ORS`>OSEZNF>%wYELhtJ?Nj z?`V6{O2uDMcxU~sm851H^xrKUsZT#y=h%+ z>^5!RvTiZ!g=~)PloWFzRZ&$T&L%G zGIY8Xo(!EX-;*Kfyt9j~X>-MvSl8gMSG=>=S}kI;?zX<7ZHM(!ZSS|L@Jp^Y>mjRA z+dsA1wEd`cSlf?Tf3EGvt(UYtZ2eN(N3A6M6^u9QQ`UTKpRm?y`x&cN+s|5eYWq3s zQEiV{U)T1iC87e}tS?$W)b>l(JKFxafwmv9{%T2MK$AR{9-zq{OApYj z9?R~?w=KH^|IxBL@aLA@asOo59ruo9cjzxI>A?3iHGf!T{m}Og%98ZbM$ZiAOI@9X zXJ~5D9car%YyAI+`x#H7hAQJHct&|L{#hROYPKY*y%~2dDqbLQyej_{R5zp4vT$=} z#^u@nf#xfJCVbZ<{TZ@ckZr#U-GgWg=GyN+PoN45=GpH&vfo@V-+s^eE?6wgw%?al z;EBC(?yMJ)Tap)q7tXWai@t$87tXieg?@!Niwd&k2fd^hkk6u(a~H_q^vo(WUe7uP`cUidd*;@q4i{~nOE6ZZqDGar-d_aOhp=`)_f^=#RN?fT$ts&q-J zUtS)3m*d8gH1n$SPsn*my7nabk|o5_9>4Er$a~2Y?U~|B1+*nowI|buAGXz!4DFfa z6Wy*Q_RCwg@9)r-C7C+pBHs#h#**pU6YwQTv{_SxN}lg`Qt0eyvN11Ivt@gj{SA=K zTx$7ckLdd(!k1=Fk?Jeo-=JTX&Ypb&9>1F3yIrYeTQX&fnK}h&mhG7KO=KfmNsqKt zf2q{xk#bq>G`Vw^1j(23OG&BkR3NBE2Yph4=l^Lg2W`mXF(?Yk*Ap=HbN^i26aQfFZ^ z;n82>Q-0ar*8LiD#V^|zzidYftVSqU&`N#bSXbYSYDmSa}2lSqc3zi6H6AN zlr@N-`>vgX?1wyZ*N%|#Ul@D2Q+&Ev{~}@f%Pt~U5`O?K%B}J02(o$7=}gs*fK*sr&!fVX`ySVJcPB|MGsLG08sBuAa`< zuu7H&Jno(HdvvO>l3k?T6Ly4@ebP;{e0mVb*3u)R!3LJ{d8vDq-3worFg;3iKZ;lR z%khe2aS-7W+54eyjau#%PRW&3Jt zM@q>C?Ywe3E7^?M5$p^OqM5mW>z#6!X|8O3!@^Tqv2f(wZ}*05h&?i|ZO*#aQ||(_yj^x08iB)?S5Dza->;rX$HNU1y+De~)bQeyUT*p1rR`JqA_k z5y|^DU0K=7_Z4fxdnNtTI+^V8Bh#mRQ22k_W_U^>XomVqSJ0k5!YuW>7(lsQx`Oh0 z&{vd7`4JYZ+*XfXsi$D8ZHLK~^2>sg(j{r{_GBExSde##un4LDPZIzAbcrXg7hzS@ z8KnG1!oTL3{%hnW?;U+<&H8dq2HG>8c_oM-FC>u>Qg1~-?gP5!@}d$}g0xYk9Frbj zY)^T4gVEDQrQCt>mFu%_%L|R2ubweFUFx#}FIQ(LFFKL=re24d=auQ(@&Ys<+``J4 z*Q{^Li;*3!S6#baPsx}OLoYz z?d}URfcSt%%UL;u62SMf$#sC*=zJ=Vs-bj_J9={<+!jTZ<>% ziYxSQ!kNC0pt>unwI|#6AgZupqxJ-RUyuwoX-}R{e$rd9S$hh7mq-R%w5QbfHh`_T zQhO?W_eq+q+Ox%1C7!GF@B2aDX7SW$&wG6G?`kWyYtPlbpGek0?Wy(MF43;mo}IpX zBzk`E$UATz((_c-bz@AP(>jTy4$ zm^7QT2mjpg1mfgxPX4-`X1nhQ3YXU?JI#)nGEPjIp!OimQ;3uQp5$L4O>R9pGrtgz z1Eld^jIRc%nf!v_k=F+OrBdcdDZA|r)ouxsFXg`;-@CJ_F$wdp$FF0sdI1PUNNoV; z{G0Vkd|2+vW<;fa5MTMt`Y|CtMVPxEm%F#>g;jo-u zBO7zwW`X))?^OA1#h%$Kr(-{r|Em22n3pM@9*_Lg;<-awm-?!-<-?k_{P1E|SALIG zscWPu$2D5{Ev7HX&N=mqQrOq^BTIgxi40HakizEJ&5<8(bOe=}hinTT(p8tAa_pzI zEPRI2o9O+59l8wpMWAm-q*6X5mA%2YP=>1fN)YzOpZcVP-M&mluKaLd3VTxqZLePU zQK^S96|86U;FaH%?7J!1$ikXs6Ox~q%lZo?`3=fM z{xB$89($6>Pg3UgVvIHGtbO|*oZB9`QhxcxE9Hww=S}h0c=3~yeIeuCxpHHNeGq}_nya=Wj; z-up|WUYaVidgZj4xc(W!Gk%N&Dx)5A!;^6dy2G3CI&?Bq`|Wtd99o`RsIDq)AuyeteihxhC{aR2yU&sXr7c9 zxTxhuwQ|8!`S-$Q7k&6fcou3;p6_N%?3IhOXQl5eXy3|!_7tk6$Y0M9J@Kb2U^D+?d;~mVZ8NQ_mPW_hf zf3F@$cfxNEcHMzOafW)|4M=}|Cz8u!>k)|}7i#{4=&MzW=Kl({Et!sH%>Sx{NjvQb zDZPlb`qTEW0^gP}dzLN&aO*zrjISZfpUZ7o*FE}5k5<17yT%?YrmN;oo&PYp_u`zX z|AUBrsa46w4S1QJu@p%JjmqkgN%c+7lyAXGgi9nyO4465RB9KXuYOWDaC^Tnm0Af7 z-s^SHUI_|o_WS<>`FZB*ArSe0-Fu!aMIG0!208t2c6fu4AEwpXw~^)|Y0gggHsP~O zP|dqY`sM!<_8xFj7Rmc~_xsMwPM+BuSat`N%r3CxB`iynoDmce7IuMEauN)H*{|t9 zJx)(VOlOW~ju=pkV2)?NGkbzLp8lVwy5HGZ?(YAa&!^t4s;;iCj&HwjRlnOM-XlTqw$-LA-eqkk24A5e+;ZQ1dPblka10SMbxy!*KhN-`t`zynG9hr@_k? za@QJxsc3D#p02Ag(so-z+16Jhn_tgxPGqXH2`|}SvZ)hLvE=6&qOWC&hTN0AbA`#U ztq%45YJ@`W|Jh`!JqelyWeBC(OQ9im`yoQhGK5BYLN^>D^mK;MF-FLkA94?*Z90%4 z^rx0WKct0{wmoV1oh^m_ofaCLA@pWTp;#~5)ycCngnn-+l#>>^E<>mSgCpJUA-51;Ttq>=YDjS4LPG=0)8!>=SE#~NUx9;3jHWmEyI$%0JH1` zJKfoQ8<4{`N@$vu{R{Y92C#AscmU=OYE(CO7>zEF@^`1p_b{%D{M}OcnOFX$D4PL* zp%<-mvb&TMa{oxzCfCcq9_8h}W(8N1_#}f+YC&6!+d+-%)Lo_QRAWXvTM4Z^%rm1Y zu>$havJb$7`)EcFE1foDcG`@=?5F8zZIvisI$S!uFL81||ei2f3#!^|<5#dpm0`)i)76yl1cx zLwlh`+V4YD{R2R#yUp8jWES^88h(B~CFI7^#MF@MvxMy|FT0~W%U{pOLvrqdD^0p`#fzG(A0+7 zrX8xSv86UI-BBLqX^Ta&Ds4@D+7gkgJZ*EKX%4j=cc`{twdrl!r(U|FJj~OUjC}2BqZ45zwVisXwgD}* zdFhVwFi%@{WJr~5w=<#XbZYz4q1ujbsm)7wl!tlRaw6w>+8Bg&3AJ5%sJ81{YV*<^ z1TYls?PuuIz^eVMIa;Ucav^KfddFhVAdm2>`Y2>{wu=6`?2-U*p4$XW-I!>P0O0rq#BklgHUS4s>ao;Q^z)L5J_l) zH>dpuJn#&~KD+&+VRQf>)^0~z(J&yjx@qa!1*zG~SFCATzHIdzmRiM9sk>-LK`K?h zuD)qW{rn}3DJz4Jme{}@H7We6s^%}RU)7N6)~y>!{#L_s!|a5VwN1;GSEg34U4>dS zt~+jZH39@;bvtS)Syi=q!?Fd$(m!D|E~#I!y0Ibk*j>Y`)-)|`OdZ#>W^rm&WBrm8 zNg7tYqdW6dRV`h*U~OjUQoL=yhQ@VG3mQ{vHmqnwmOeXrnJf!eHLhISxNN}&FCQ(o zS(?+DmZe4?k8Hzt3^mzSEb!z>7KQPfiJ=XUFm8$QyeC--`6GmC4A~P)Ps7OnxGq6eJ(U9JlLu2?a3!@Bj z!f}uPI0XJLNEDePA-*}-A7*uGH54;&Y){~0frO64g%HM^#BbcV2r>lJpMZCG1Q#Nz z1J8{R^L604k!`?&9e8epSW*?4b0gz}9ZCBdSk8i?KE!!4CHP_?l^2;qB}EyBNA;SHIDAGI)5v~y;rFj}6JV1y} zx&U|8@IWDYXr6`$4-%rkeh>P?gN3NmJPi@96JoUHX^8MpAtviM*3$4WA!g~<@5FRa7uh2XV5gsGN8qL!X;jxhvs<2-3G(>np4qJY+=4puV z!~{F*6nzoRnH1z!=v2+q5aB6_ULelWJPi>(B320nTQpBYgl88HM#{ySry;^e74zi6 zPR-L0;W=W?b(*Ik!bgWVa&FT+4H2Fjz8=KAnx`Sc^Tf7Ynx`Sc^Mm7|z@CPPWEF2f zK@+Jn+%=x!X$XHF2tU~&b{DO(1KS@3p5kc;e}7^;4dEXKOazbe1amR3fOjM#unae> z=$5$P`(RRZtKb-L3`6u?fk6|?%IC3t3C)Wad{$hB(v&SY+0in;yfrD*a$pgTZzPufX@!3=zj5V!Vsj?@; zLP$yKpP)Q@q7ZrdA`I~CNwKdXR-`BQ0x`LS$0brK(GIIlGJ9C^29SC_1hR(*WFi=K zBMO)hRDK>$@liN?q)R*eyrgCq0^7wT+L%4XrMpb+S%6b@cUuPZ6!z;n8OVKcYsKo4iOpe@6$=4vIKj@AeoujO{(j6h3+eJ$E>1U89 zx2q6A%`$VVL@cWJj0e#zvK4t^(g?ZLF)B-T|9BEME=HN#y&5~JUIA*>Zui@vy0;LH zt3uDf*pHDzMuJv8nv~nurQN=a&KSvFcRG637Id+!}opnEGuj z!xmT3mD7b_b1Emg{O~m8I8pX81Zk4bQK4_3eF;}7uB1bhk6Mw;f=Vuc&c%V;LD_Gy z1Zkzg`NUOpDjGJo*3{C8vdXzb@~8*i4*ti`+&W21`l71_gBqI0Y(>5rj=tRC(o(qZ zggytCU`zM2J$x)ScZ9nheBY%oCoh%A!VL6Baq0X$N^cLul?!X(ZUYMk48bh<9a*>3 z=3kL~4YNbjXOMrTjC+`muFStW#x@D+8_*N^*ThML^%7*t|C>yLsNMzR^RKnj;{^=S z{Oe>!wQKUm8ZWOUHy_jM*W$#DtrgSxln}ukrOR4P^ z5o@Oz3zC1Q??~JeI_WQ&a*q_+Umt<7oPS@K6&i8S{4wF-v#C$jN_Fh)^DNdeR{Mn* zC*umu7xDQohQ`9S^}2?{%R+3{&(P|B__iVCtk|lx%T)eH(OM8YbpXRE|I3huRoCe= zsqLHWTcPbXeHSbDVv^&Y`pWV86+nvH2r(Smx}mZ?u}SWcebM zKT`W-$~+2A&UdKaXx)mQ<9W3M)-7mIlO&pUaqWOb4fEAheG2+;MQzR}7;`hV+|$Iha=&=Uzl%UQ?^=OE|A_pCRpI_Pi<=TTkVC5JR(|OY3^z z{)M=7=6Klz#LO&GW@aUB#HdLX)Fk;}q+emS0d0sYeG1y4V4#erpuV6Fh(UQXkdl-t z6bzOs6e&N|`lzO$))o9L!Aq&7WCyx587vr;EI@bYUKpvR>sb&Sf&x(2l>$@(*{t+GDAwKVG;Tw7;_F=ETI{J559m7{CtWJNh*vc5v<+<|@a zxzw0DLH?vbElSSnh7^^x1(nrVF9CP53W2*>6_E91RRH(f42^*knBfVuk;>BOL!Gq| zLQYl=ig2^aQFC9`AIy-IhxQ6&odAB8>JdEYQsj$arsi*qvN=_3^$L~0DaxhOr%Kjg zMD@@(L-szz^aZdze{FFdRs6yQ-ywszm41V(bMWQL5cCtQaEEx>=%3=W+}~qEmr(#z7*l6i8tVnEDT4!5)^{W^wi(R4AblfJtj zh#9#%ktuw6Bynle1s5|seuI!p{VsXR ze1cm%pt5gde+bXz8e#X1Bf#`=loSqh**UVb7q`(TgP-*vY^zg=OVPHI zi+U#?2T!`as3y+syV8wp%>iLPesKL=yFU?0og8SGMN;ww}t zSu`Y>hgOnXXi=SXfa+8QPSG$Sf_0s~N8v@o1KgA8(Vh6HRy0DW)EMQXlA@9BUMLic ziw@Jhk$d16T$ENN|3rboB)G@36h0kT+&mqC;0msi@^oM+Cn-+{pg47KIw?dGIU1zv z{!l(@MKViDm7-hx+kl1GEVp@5c!uD}E;`EP@Ch8KpAVkq#i!P^c89y9pw z*kYC>4gM@;at(e3WeNmGq;y|OFr(GJkUlQhqVnA+xU;`}*QJCJpGQGU*@ z+=ICJlywOdlP%3s+Zl!A|4r+@9!pAbIeYO04l8qy*Q1#xEuMP?^yW>_N2WPlUSpe; znl@WWwlr6lTOgP!G<|p;*>u0T#FYOspcRD>aOO!L-^28JrhkuQ_e)~37|(hWLiz!% z^|ufi!rSeGns(QXN5Vro#>KlXAJu+XCpmV8)UQyFm~S{7(FP5wuht?z?^y`q_pz?a+DN-x{Ri)z2B-lx&vjDN=tLX3TapTd7R|Q{`-%UbE2-f0f4TVNK|6ZP(kw7&Pq;U_f1}vx#@djfF26+uaD;x0^lMM9_TO z+;zU%p`+YXHGx_LnEifxcpypu~mh^DH;|V4f~P%IY3?$R?cJ08;X(G zpVa{J_|{`BK6is5a0+OCW+k%Es^n7lB+Oxn>u^}X|AZ-ni{g8R?_Q;6sIt~J;pen4 zn*v4__pvElALGj`;SG^>Y%x2KuCqe~^|~1oYL=e7+Z1+mx?W-I0;OI@n1TN!Y<&#S zt{)oWNS)6*yaW0TK%U0%n4=@ydi((TEAl#^VU9MuLTmx?B{!A#B;@K1kK4iyfTJqf zWB+E0*A8Zto}-IDMCM>EQjUPgOhB+Fh+}{(2B^phHp2@QO3`zSMw7;wbBj&jZAMit z#b7Ac2cI^zO7YHupWa?nYAcsAoyLR4s{nZ)!N5*h-c{cP`d0GTk(H(+e+7MjJa%M1 z(~$$8R#ykW=?gR85hkpmWS?;|sO<`0&R1sE;TWmibUd;s&_28{dytHfya-l7f75f1qv@-KfcB0pJk(aF` zH`Q?zY$R3W8_T~E{0!2{i{I2{-mq?#=e3c4KE`lqUsUq++jblA zN6a6zNwTeNlQX1E`k)@&0cFoy$s4U=+_59?SzZ>_wa1(J#lKoUclnXHwUiG5pJoV^ zTRtBeihE=d<1+|#*jy|Q_20w3$+j9b+8C?1^ZqIQH(zX>4m&3TM%>gMLBCd7cY=81 zcGN2PGT1ATz7!CA3dAWuHj{V&#Q8wZ1;kIbIhS>0H%xbee|X!p`qhvdXGfj(5Dano z>CKJ8~|-S;)~;$C}9Pc_%&u>Dw)#&c)2^9j>RH<&*dX%k?n^xg#NJ%0CypM@ED09hu< zZma`XZ2=8yRwz9)hYw@U*2$5lttvjl4S^E04|j&sk*12r?luK%?ufsQeKC0SD9s1@ zEjAa5ke}XOIs#K*$O_Acq~)^-3wZprF3F5Fu%Hh>m7a)UdqAm3PkE!s z*Y4v01$^@BB@ccLAm@?A2f*I){KqJ~wSa|#k45%=;me@T-MVvQ*-ch|KG?YFkf(~D zwoIv2pRriZ+#YOIZWp@oHt+VR;9aM%+Y}}Z;Qm(iITH1AJ9B@+fotSCXUKK7a<^mO z=&$4*i8Dv!{8h4$cUv`I`MV|PD;Qm`dPMl_IeMw87Kfqgdl9PRtJ#LKxIHN3)0nSD zlP>h5t$=gl7QTRn0De7i)i(~Kd?l30>)_=n(HB!L%seIf0~BKNl-NAKLV%8Z(@OaqUdS*^=k!*55-*gG+?`%659EvZsP6sWkm<#k+%e9tgj#8RYqxFM)gt7{1@;y8zmUq9)uU zaTmaC5y#3^daA1O*|9>Q|0aMU`$;FDBl@ui&j$44%i7}ri|M8mhi4R{jFEV|Fk^a1 zBwi&(5+m^r{r4*SF-s&I&V8|P0MsW;R9>}-YRereEcyO%!o(LPOuSse#LFd2jGcUo z+1EZF&k!n+@hxUwhr-!pWrWT7I+e}`OG4#*T?(3r-xqL@8xWip7v(qLi{GmwW&srIHe*lr=2*BuI%;${HRR3f0P}8&SXn1oI8X zABj@R8tKvwx#TlS$$f`Ov@vUn*eg*=!8SS7aTR2=5ePPma)QebPg9N)WV8{|SR|s2 z0-r(OWGIkvWTTCc{0rDQCfX=8DEncSz-Xh;;C$jL$Y`Tbt!W=8$ohqbk?| zC`#we!Y>!r!Y_|E@-6Bd6Kxc^B6)uR7GH@e5V=yuFU-eE61h6YHZjpgk!#{4Otewt zZ!(xov{B?*JIonv6uC}Dwuv^1Tp#-bbIC*-MQ(^CuomOEFfW`jUtccAuPs58%1^tVWN#9PYPk8jc~r4c}%oXj4q&HGb zv{B^WGDr4AOteu!FeBQC#J-4$HX4B(Z$xdh(NHwU#g$PTZ8QT(J1e6$+K3N|yQ-o# z+KAMis;G@N;)Bt?s;G@N;s=Z0sEXQXqc944zkAe18@-I-b+BJAPR|IUjbwr{+Nd{u zun|NX$&_KVQS>{Ea6}vZ0p0UzJDF&szu^wFxVDptHo6VOirVNW7;}g=qV4Nzqc+;; z1q>iW8zm*$DBM1|pF@?=M&S;5@4*HWZ4~Yp;<&caM&V8_M|6&fHVSu17NH^%Z4~Yr zC9Y%+hAZQpNMK%5D{=4sKw6@W!c{I`9!j)Pv`g!eka5T2Qp)kN0En4cq|D4pO0-e5 zCV34K#bF;E(1y5il|~23crwvO(Ls4NNHNhy(ZN!MBIQ!8L>onG4bEtzXl*IAH{KcNcjSbU)h3>Cyr1W$SjvSEz)$i^tmQei~xL^ega1o>3XI*b%Ve5?sZ zF`Fc6C$hG97;qJ4)J|lxZ#;-#kWo94lY>LqIy%UxoygV*59%Olr;kMKM4EJx8NIk2 zDa?!8kp}VNcKFDLd+%Woc3EtI)uApsW&)Jv>=xR_?L;n0a$Rsw!li_(m$ag4lf0FS zg2e4aZp-F9*u?EbZWqGD?L_Vn!o=-F{w_pRwJCb_TjpilPUMZSi}_*Vb|P;HVd8co z@5pFMsuBvAzB4O7GZ!#!rwbCixE)D~NZd|aR4WJx#O;jtBoMdbNg!^AqX80(+t~n# zh>hFfu0%y7ZYKzKFd}g~ETstQ5Vv!wrw(yDo;vg*QK)0w&cl?jaXaiZ=$5!0@-c>4 z8rK79VHZjfx5FDu#K!Hs!YtBxh}&Uz1S2+XheT8bI3#%!5(Sv{q{}_puS&QcH&1Bg zGEIcIxY~XVuvNIC_T^p@aXSIli_54r%ca(&#O=hoB)Ou>G7#&UPh5rhY!|DH@q?cx zZYNeHH(e9A6YHMy4pL0qPOMsPUnz;(iS?AbTszq;#d_tly-nOstWSs^)H88Av3|iY zw!$WECpJJ*>Xds7%62)ca!lM#d|Z-iuvilxFJZVQZYMr5!ge%qJMqcUZ}602;&$Rw zgfMYC@u@lghFi_V?Zl^xX(nzbJ|ow`2E9j+aXayua+mCp7i8Q{e3nrC^MZ`qi60?U zU0z4tGvc$ezl1`>?YMjim(REz_eNm-xJ`*5aEB*G+`GUDybl98AN#WluACnj;ggGCR7$k%_ACnj?M4g7KtI(ShI@LVYdoLl zV_ZHzyJX7)9IcW$1}2}X^LakTeSsLy$GC3*6G0AH5zJLCyEZBDPx0Q#8VoR*KJl73 zpB|LNKg9=x`Fv>NpW*{$D{kVS;)B9JA;rc&#Rt1TQk%p-#fK!%hBk?Rir2|NR;?KS z6dxu;u&x#3pW?#<+$HMKtr-6lA0d<%{}dnTj)aaJ6YCT|O!M=5@@!&p^K1e_o=uYS zY+@-VDbFULxZEJtDL`{LgQVs*)(Oemz{+Q=llv2}0Gl8O(^I5utP{=&amvYUI(ztN zq=r^uUx&jLn87;q0zG@7TX1zl^dtI=WX^~sl-vXk4w&PrLk@B|p#hXsZFk{Md_AYr z$&mB&qFff;mfv}cpU9L;(9}P)AmxuwXGoxu@M|NPE=#ov1>~SP_1>;QaoxGRI z&9{a4S8q?DcO}m8KIV#`Azi@0>!EGB71oU?K|kR98M@;yA)yKqT>-g};q`~LGL-T12t@5m766MeI|@vYs~LcHkd3~`9! zh0+YF?j@e49xY^5yBxIiHEdNcVWTM;wLcuAS!(|`)_yT8=jU%@>(sRzfE;BP0P^Vf zx-QIiyb0uWfUc`oEl@YGPoDtwFgXpY*QguGc^}kUfYuChSqKQZY9x0s`|CCA1}!Z=VVCz^xvg=;Ps-F;t&~#V$!;7{J~^?Hw8a5akB*sQ8^K; zBlwY@L4UI`Dx?Gsq!*AbP5DIh3<;49P1){m|AQ@*Q@*mt zUQ;yt?<-V|BiM}geb(bBJ?CXcpXo`eXk13F<{Y~+``XKaxy+~C!22kNhDcZDAn*?O z;ALn8j5d84h*}8%m>OZdi&XHq>qpUr4WtaIeumOdvATs%A$tM!+_Flwa4C{F76^MSW;XCi{l5~ivdzxJ1K4@$fW>` zu=ec#vw&}=2%DmVw8S+auK>u9=p-$|@S8iyV#{=vmg$bU(HS5ubTx_%x%0dg;iTt` zK^z6&p#ct^#rHOk1!p5tXK~`zZL_)JP?pZYl*(^1^i4LY-tuS$S2A;`cxFIv059i* z2yrNCYbOgWg6@{NTMW(r%xwm#>2_9Bx;4*V7 z6p6)j!~pNcmKnx7NS*EP&E(*xx5tNrJr->`3=p3LVgrz+B={Eh4j?y>SOnr9KwbrO zTMZ(JnWg~Uc+_SnkQ%^n7P8Y8l15T23O`Jf4`8V%z68>L28iNYfiOT%%6|&Tqa2 zrKCS(pIthD&hj%FSth{NWkva^nLjH$ISZ;{%Cp#{vK!$O?)Z zA4rT*6Yzmd0xPx|rTIFR{E5lN9}??`ts?v(hcj8>*#rI%7^-5{AHu$#8BB0rKI%bS zpq0*#&Sb=Ppfor?8i=0))&62}aCCl`g2o$?;GiA#10|kK{{uX zk>L!9WjI3;Ly*|fIz#>n+|Lu+@P)htT=^N>3SS7z2&Swrq%BgCer|)|3n7u`=i7Do zLRfNc`^v4$9F!6-YxR5$bJR!v0&@Af-Aq7uJj9K6b z@gqxjc1@^FfB`L0Ijn&m7K0l9Z!&^ck z=x34emQXC}=W%U#OSm4yqzT|Hp|a!<<1Glb!0|y`wXzNrHYN@aS_cX# z$7y99D73=osJtv>I2j;T3{f#^g&r2vCG9{t0Lrw|;C$k$m35#{3resK6zT~&t*iru zX-Quz>p)?)BHt0#fx?!8110Yda0#~b1luFVV&OnJ5B%7rFb58lQmg_Ao{Q?$2L%oQ z5|Rtc2=RehB^YpAd0ZO~6n+Cg-_PUPaG?AEqR7wV+Hjyytjy2j+Hj!!3?k*{acwwI zNVN6yxHcRp6l>?_acwwImSZ*Pel)994ppY2h z=W%T~P)LmS^SCw~C?v-FJHjY9Q2qsCvY*Gb;XolV%g^K5aG;Qw=jU;4I8c~pu|LLY zzYyb8T;Z2DnJ?nsisD6upU1V~Kq0Z&&*R!~pxg-Jtdw=2Oarmg&v;ijPzs`W#_;pF zHXJDQj^5_yacwwIS|MeZpU1V~K;g96!w>D^xb{fA1ADH*9@i$ZuhckDx+2FLt*rxv z&2e#MYwJK6gruF7t*rxPJXKe`P_EojE4wN})r#GrvA2S(2DZ01@ zg}vXswRNEQFn|vBJJNHYu$wd;D6>5W3OPPHP+D6D3jeLsyxP&mfpP%E;@Z*1f$}qm z6}7Fc1BJG)uWfA|D0iWI;6UkU9Vj_4$#4B9NtmGg+@ZmL!eJd$F^a)|!U5eS?LQgK zOgya({|Rv=QxN`>StKy6sg<})ta6ng9b6G-9K-cAl{ z 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

64a~B|f3ug% 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 z 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 z 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

~>Twnl3BNk+v&O`xx6;c+W85~ucC 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

mgphFZrlU>t7#VNXc@ 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 HTl4<`JTJDT 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 deleted file mode 100644 index 0af4178..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/main.cpp +++ /dev/null @@ -1,190 +0,0 @@ -#include -#include -#include - -#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 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 deleted file mode 100644 index f59ddbd..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/error.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "error.h" -#include - -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 deleted file mode 100644 index 80d5682..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/error.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef ERROR_H -#define ERROR_H - -#include - -#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 deleted file mode 100644 index 32a23b6..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/sim.cpp +++ /dev/null @@ -1,282 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#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 gdbFromUartBuffer; -std::vector 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 deleted file mode 100644 index d980f26..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/sim/sim.h +++ /dev/null @@ -1,43 +0,0 @@ -#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 deleted file mode 100644 index 8a3b2fb..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/fifo_declare.h +++ /dev/null @@ -1,189 +0,0 @@ -/* - fido_declare.h - Copyright (C) 2003-2012 Michel Pollet - - 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 - -#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 deleted file mode 100644 index a283fef..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/uart_pty.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - uart_pty.c - - Copyright 2008, 2009 Michel Pollet - - 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef __APPLE__ -#include -#elif defined (__FreeBSD__) -#include -#include -#include -#include -#else -#include -#endif - -#include "uart_pty.h" -#include -#include -#include - -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] = "8avr = 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 deleted file mode 100644 index 482de7d..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/parts/uart_pty.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - uart_pty.h - - Copyright 2012 Michel Pollet - - 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 . - */ - - -#ifndef __UART_PTY_H___ -#define __UART_PTY_H___ - -#include -#include -#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 deleted file mode 100644 index 289a45d..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/semaphore.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef SEMAPHORE_H -#define SEMAPHORE_H - -#include -#include - -class Semaphore { - public: - Semaphore (int count_ = 0) : count(count_) { - } - - inline void notify () { - std::unique_lock lock(mtx); - count++; - //notify the waiting thread - cv.notify_one(); - } - inline void wait () { - std::unique_lock 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 deleted file mode 100644 index ba63390..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/simavr.cpp +++ /dev/null @@ -1,749 +0,0 @@ -#include "simavr.h" -#include "../sim/error.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - - -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 deleted file mode 100644 index e1455b7..0000000 --- a/examples/simuc/dpkg/htl-simuc_version_arch/usr/share/htl-simuc/simuc/src/simavr/simavr.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef SIMAVR_H -#define SIMAVR_H - -#include "semaphore.h" -#include "parts/uart_pty.h" - -#include -#include -#include - -#include -#include -#include - -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 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