From: Manfred Steiner Date: Tue, 3 Sep 2024 09:10:13 +0000 (+0200) Subject: V0.1 (merge mit w-2024-07-16/daecee1 X-Git-Url: https://git.htl-mechatronik.at/public/?a=commitdiff_plain;h=refs%2Fheads%2Fmaster-sx;p=sx%2Fsimavr.git V0.1 (merge mit w-2024-07-16/daecee1 --- diff --git a/examples/simuc/.vscode/c_cpp_properties.json b/examples/simuc/.vscode/c_cpp_properties.json index ba80ed4..e6ad2ab 100644 --- a/examples/simuc/.vscode/c_cpp_properties.json +++ b/examples/simuc/.vscode/c_cpp_properties.json @@ -7,7 +7,7 @@ "compilerPath": "/usr/bin/gcc", "cStandard": "c11", "cppStandard": "c++17", - "intelliSenseMode": "clang-x64" + "intelliSenseMode": "linux-gcc-x64" } ], "version": 4 diff --git a/examples/simuc/.vscode/launch.json b/examples/simuc/.vscode/launch.json index 4c40c7b..b6d3ec2 100644 --- a/examples/simuc/.vscode/launch.json +++ b/examples/simuc/.vscode/launch.json @@ -9,7 +9,8 @@ "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/dist/simuc", - "args": [], + //"args": [ "--board", "sure", "/work/4ahme/sx-la1/g2/turnus3/2_timer/dist/atmega16.elf"], + "args": [ "--pc", "0xe000", "--port", "1234", "--board", "nano-644", "/home/steiner/Private/work/nano-644/software/gdb-stub/dist/gdb-stub_atmega644p.elf" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], diff --git a/examples/simuc/.vscode/settings.json b/examples/simuc/.vscode/settings.json index 4c1291f..a2774e8 100644 --- a/examples/simuc/.vscode/settings.json +++ b/examples/simuc/.vscode/settings.json @@ -1,99 +1,6 @@ { - "files.associations": { - "cstdio": "cpp", - "array": "cpp", - "atomic": "cpp", - "bit": "cpp", - "*.tcc": "cpp", - "cctype": "cpp", - "chrono": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "compare": "cpp", - "concepts": "cpp", - "condition_variable": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdlib": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "deque": "cpp", - "list": "cpp", - "map": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "vector": "cpp", - "exception": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "memory_resource": "cpp", - "numeric": "cpp", - "random": "cpp", - "ratio": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "future": "cpp", - "initializer_list": "cpp", - "iomanip": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "istream": "cpp", - "limits": "cpp", - "mutex": "cpp", - "new": "cpp", - "numbers": "cpp", - "ostream": "cpp", - "semaphore": "cpp", - "sstream": "cpp", - "stdexcept": "cpp", - "stop_token": "cpp", - "streambuf": "cpp", - "thread": "cpp", - "cinttypes": "cpp", - "typeinfo": "cpp", - "variant": "cpp", - "iom324.h": "c", - "sim_megax4.h": "c", - "sim_core_declare.h": "c", - "iom328p.h": "c", - "iom16.h": "c", - "sim_avr.h": "c" - }, - "cSpell.words": [ - "aref", - "atmega", - "avcc", - "avrsim", - "ddra", - "ddrb", - "eeprom", - "eesize", - "evws", - "fusesize", - "ioend", - "lfcrlf", - "lockbits", - "megaavr", - "microcontroller", - "Microcontrollers", - "millis", - "mmcu", - "picocom", - "porta", - "PORTB", - "ramend", - "simavr", - "simuc", - "slavename", - "SRAM", - "sreg", - "UART" + "cSpell.words": [], + "cSpell.ignorePaths": [ + "**/*.json", "**/*.c", "**/*.h", "**/*.cpp", "**/*.hpp", "**/Makefile" ] } \ No newline at end of file diff --git a/examples/simuc/src/main.cpp b/examples/simuc/src/main.cpp index 19cefa8..4e31b09 100644 --- a/examples/simuc/src/main.cpp +++ b/examples/simuc/src/main.cpp @@ -8,7 +8,7 @@ #include "simavr/simavr.h" void printVersion () { - printf("simuc V0.0.7 (%s,%s)\n", __DATE__, __TIME__); + printf("simuc V0.1 (%s,%s)\n", __DATE__, __TIME__); } void printHelp () { @@ -16,7 +16,7 @@ void printHelp () { printf("usage: simuc [options] elf-file [elf-file ...]\n\n"); printf(" available options (you can use file .simucinit instead):\n"); printf(" --port ... listining port for gdb (default 1234)\n"); - printf(" --board ... set board (arduino, sure, evws1)\n"); + printf(" --board ... set board (arduino, nano-644, nano-1284, sure, evws1)\n"); printf(" --nosync do not sync elapsed µC-time with real time\n"); printf(" --mmcu ... set target device type\n"); printf(" --frequency ... set target frequency in Hz\n"); @@ -31,6 +31,59 @@ void printHelp () { printf(" simuc --board arduino a.out\n\n"); } +void printAvailableCommands (struct StartParameters ¶ms) { + printf("----------------------------------------------------------------------\n"); + printf("available commands:\n"); + printf(" h (help)\n"); + printf(" b (break), n (stepi), c (continue), s (stack), r (reset), p (power), q (quit)\n"); + if (params.board == BoardNano644 || params.board == BoardNano1284) { + printf(" 1 (SW2 not pressed), 2 (SW2 pressed)\n"); + } else if (params.board == BoardSure) { + printf(" 1 (SW1 not pressed), 2 (SW1 pressed), 3 (SW2 not pressed), 4 (SW2 pressed)\n"); + } + printf("----------------------------------------------------------------------\n"); +} + +EnumSimAvrCommand parseSimAvrCommand (struct StartParameters& params, char c) { + switch (c) { + case 'h': return CommandHelp; + case 'b': return CommandBreak; + case 'n': return CommandStepi; + case 'c': return CommandContinue; + case 's': return CommandStack; + case 'r': return CommandReset; + case 'p': return CommandPower; + case 'q': return CommandPower; + case '1': { + switch (params.board) { + case BoardSure: return CommandSW1Released; + case BoardNano644: case BoardNano1284: return CommandSW2Released; + default: break; + } + } + case '2': { + switch (params.board) { + case BoardSure: return CommandSW1Pressed; + case BoardNano644: case BoardNano1284: return CommandSW2Pressed; + default: break; + } + } + case '3': { + switch (params.board) { + case BoardSure: return CommandSW2Released; + default: break; + } + } + case '4': { + switch (params.board) { + case BoardSure: return CommandSW2Pressed; + default: break; + } + } + default: return ReadyForNewCommand; + } +} + struct SimUcInit { int argc; char *argv[]; @@ -114,6 +167,23 @@ int main (int argc, char **argv) { params.vcc = 5000; params.avcc = 5000; params.aref = 2500; + + } else if (strcmp("nano-644", argv[i]) == 0) { + params.board = BoardNano644; + params.mmcu = "atmega644p"; + params.frequency = 12000000; + params.vcc = 3300; + params.avcc = 3300; + params.aref = 1100; + + } else if (strcmp("nano-1284", argv[i]) == 0) { + params.board = BoardNano1284; + params.mmcu = "atmega1284p"; + params.frequency = 12000000; + params.vcc = 3300; + params.avcc = 3300; + params.aref = 1100; + } else if (strcmp("sure", argv[i]) == 0) { params.board = BoardSure; params.mmcu = "atmega16"; @@ -206,67 +276,39 @@ int main (int argc, char **argv) { return 1; } printf("----------------------------------------------------------------------\n"); - printf("available commands:\n"); - printf(" b (break), c (continue), s (stack), r (reset), p (power), q (quit)\n"); - printf("----------------------------------------------------------------------\n"); - printf("init done - press key to start\n"); - char c = getchar(); - if (c != '\n') { - getchar(); // remove line feed from stdin - } + printf("init done\n"); + printAvailableCommands(params); + printf("start simulator with command b (break)\n"); + printf("ready for avr-gdb -> (gdb) target remote :%d\n", params.gdbPort); printf("----------------------------------------------------------------------\n"); - - switch (c) { - case 'b': start(CommandBreak, NULL); break; - case 's': start(CommandStack, NULL); break; - case 'r': start(CommandReset, NULL); break; - case 'p': start(CommandPower, NULL); break; - case 'q': return 0; - default: start(ReadyForNewCommand, NULL); break; - } - - // int cnt = 0; + + EnumSimAvrCommand cmd = CommandBreak; + start(CommandBreak, NULL); + EnumSimAvrCommand lastCmd = cmd; + char *line = NULL; size_t size = 0; int quit = 0; while (!quit) { - // 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[] = { "quit", "break", "continue", "stack", "reset", "power" }; 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; - } + EnumSimAvrCommand cmd = ReadyForNewCommand; + if (strnlen(line, size) == 1) { // Enter pressed + switch (lastCmd) { + case CommandStepi: cmd = CommandStepi; break; + default: cmd = CommandStatus; + } + } else if (strnlen(line, size) == 2) { + cmd = parseSimAvrCommand(params, line[0]); + lastCmd = cmd; + if (cmd == CommandHelp) { + printAvailableCommands(params); + continue; } } - // printf("foundCnt=%d foundIndex=%d command=%s\n", foundCnt, foundIndex, foundIndex >= 0 ? commands[foundIndex] : ""); - if (foundCnt == 1 || length == 0) { - EnumSimAvrCommand cmd = (EnumSimAvrCommand)(foundCnt > 0 ? foundIndex + 2 : 1); + + if (cmd != ReadyForNewCommand) { struct SimAvrStatus status = getStatus(); if (cmd == CommandStatus && status.state == StateStopped) { // ignore status command, because status was already printed @@ -286,10 +328,8 @@ int main (int argc, char **argv) { } } 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("invalid command, valid commands are for status and:\n"); + printAvailableCommands(params); printf("\n"); continue; } @@ -299,15 +339,7 @@ int main (int argc, char **argv) { } } - } - // while (1) { - // struct SimAvrEvent ev = waitForEvent(); - // printf("event %s (%d) received\n", eventText((EnumSimEvent)ev.event), ev.event); - // if (ev.event == EventShutdown) { - // break; - // } - // } if (simUcInit != NULL) { for (int i = 0; i < simUcInit->argc; i++) { diff --git a/examples/simuc/src/sim/sim.cpp b/examples/simuc/src/sim/sim.cpp index c1ec1e3..9eee696 100644 --- a/examples/simuc/src/sim/sim.cpp +++ b/examples/simuc/src/sim/sim.cpp @@ -99,8 +99,16 @@ const char * lastError () { std::vector gdbFromUartBuffer; std::vector gdbToUartBuffer; +unsigned long gdbUartOutByteCount = 0; +unsigned long gdbUartInByteCount = 0; __attribute__((unused)) static void fromGdbUart (uint8_t b) { + printf("\n\r(%lu) gdb-uart OUT -> %02X", gdbUartOutByteCount++, b); + if (b > 32 && b < 127) { + printf(" %c\n", b); + } else { + printf("\n"); + } static int cnt = 0; if (b == '$') { cnt = 1; @@ -112,7 +120,7 @@ __attribute__((unused)) static void fromGdbUart (uint8_t b) { gdbFromUartBuffer.push_back(b); if (cnt <= -3 || (cnt == 0 && b == '+')) { - printf("\n\rgdb-uart OUT -> "); + printf("\n\r(%lu) gdb-uart OUT -> ", gdbUartOutByteCount); for (uint8_t c : gdbFromUartBuffer) { putchar(c); } @@ -122,6 +130,13 @@ __attribute__((unused)) static void fromGdbUart (uint8_t b) { } __attribute__((unused)) static void toGdbUart (uint8_t b) { + printf("\n\r(%lu) gdb-uart IN <-- %02X", gdbUartInByteCount++, b); + if (b > 32 && b < 127) { + printf(" %c\n", b); + } else { + printf("\n"); + } + static int cnt = 0; if (b == '$') { cnt = 1; @@ -133,7 +148,7 @@ __attribute__((unused)) static void toGdbUart (uint8_t b) { gdbToUartBuffer.push_back(b); if (cnt <= -3 || (cnt == 0 && b == '+')) { - printf("\n\rgdb-uart IN <-- "); + printf("\n\r(%lu) gdb-uart IN <-- ", gdbUartInByteCount); for (uint8_t c : gdbToUartBuffer) { putchar(c); } @@ -159,7 +174,10 @@ void init (struct StartParameters *param) { // simavr.registerIoWrite(PORTB, handleWritePortB); simavr.setUartPtyEnabled(0, true); int uartCnt = 1; - if (strcmp(simavr.getTargetDeviceName(), "atmega324p") == 0) { + if (strcmp(simavr.getTargetDeviceName(), "atmega16") == 0) { + // simavr.setUartPtyHook(0, fromGdbUart, toGdbUart); + } + if (strcmp(simavr.getTargetDeviceName(), "atmega324p") == 0 || strcmp(simavr.getTargetDeviceName(), "atmega644p") == 0) { simavr.setUartPtyEnabled(1, true); simavr.setUartPtyHook(1, fromGdbUart, toGdbUart); uartCnt = 2; diff --git a/examples/simuc/src/simavr/simavr.cpp b/examples/simuc/src/simavr/simavr.cpp index 9c974b5..94c3717 100644 --- a/examples/simuc/src/simavr/simavr.cpp +++ b/examples/simuc/src/simavr/simavr.cpp @@ -17,6 +17,14 @@ #include #include #include +#include + +typedef struct { + avr_t * avr; + int burst_count; // Current instruction burst size + int listen; // listen socket + int s; // current gdb connection +} Gdb; SimAvr::SimAvr () { @@ -175,6 +183,19 @@ void SimAvr::load (struct StartParameters *params) { avr->gdb_port = params->gdbPort > 0 ? params->gdbPort : 1234; avr_gdb_init(avr); + switch (params->board) { + case BoardSure: { + // SW1 and SW2 have external pullup resistors + avr_ioport_external_t io_ext = { 'C', 0xc0, 0xc0 }; // PC6 ... SW2, PC7...SW1 + avr_ioctl(avr, AVR_IOCTL_IOPORT_SET_EXTERNAL('C'), &io_ext); + break; + } + default: break; + + } + + + pthread_mutex_unlock(&lock); } catch (std::exception& e) { @@ -476,8 +497,14 @@ void SimAvr::printCyclesAndElapsedTime () { 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); + uint16_t seconds = time % 60; time = time / 60; + uint16_t minutes = time % 60; time = time / 60; + uint32_t hours = (uint32_t)time; // time has after divisions max. 23 Bit + if (hours == 0) { + printf("cycle %010" PRIu64 " = %2dmin %2ds %03dms %03dµs %03dns", avr->cycle, minutes, seconds, millis, micros, nanos); + } else { + printf("cycle %010" PRIu64 " = %dhrs %2dmin %2ds %03dms %03dµs %03dns", avr->cycle, hours, minutes, seconds, millis, micros, nanos); + } } bool SimAvr::sprintfLedStatus (char *s, size_t size, bool onlyOnChange) { @@ -492,37 +519,168 @@ bool SimAvr::sprintfLedStatus (char *s, size_t size, bool onlyOnChange) { int8_t nextLedL = -1; if (ddrb & 0x20) { nextLedL = portb & 0x20 ? 1 : 0; + } else { + nextLedL = -1; } if (!onlyOnChange || nextLedL != ledL) { + char c; + switch (nextLedL) { + case -1: c = '-'; break; + case 0: c = '.'; break; + case 1: c = 'X'; break; + default: c = '?'; break; + } ledL = nextLedL; - snprintf(s, size, "LED L = %c", ledL == 1 ? 'X' : '.'); + snprintf(s, size, "LED L = %c", c); + rv = true; + } + break; + } + case BoardNano644: case BoardNano1284: { + static int8_t led[3] = { -1, -1, -1 }; // pin floating + static int8_t sw2 = -1; + static uint8_t mask[3] = { 0x04, 0x08, 0x10 }; // Bitmask for LED Red, Yellow, Green + int nextLed[3] = { -1, -1, -1 }; + int nextSw2 = -1; + char cLed[3]; + uint8_t pinc = avr->data[0x26]; + uint8_t ddrc = avr->data[0x27]; + uint8_t portc = avr->data[0x28]; + int change = 0; + for (int i = 0; i < 3; i++) { + if (ddrc & mask[i]) { + nextLed[i] = portc & mask[i] ? 1 : 0; + } else { + nextLed[i] = -1; + } + if (!onlyOnChange || nextLed[i] != led[i]) { + change++; + } + } + + if ((ddrc & 0x20) == 0 && ((portc & 0x20) == 0x20)) { + nextSw2 = (pinc & 0x20) == 0 ? 1 : 0; // 1 == pressed + } else { + nextSw2 = -1; + } + if (!onlyOnChange || nextSw2 != sw2) { + change++; + } + + int l = 0; + if (change) { rv = true; + switch (nextSw2) { + case 0: l += snprintf(&s[l], size - l, "SW2 ."); break; + case 1: l += snprintf(&s[l], size - l, "SW2 X"); break; + default: l += snprintf(&s[l], size - l, "SW2 ?"); break; + } + l += snprintf(&s[l], size - l, " LED RGB = "); + for (int i = 0; i < 3; i++) { + switch (nextLed[i]) { + case -1: cLed[i] = '-'; break; + case 0: cLed[i] = '.'; break; + case 1: cLed[i] = 'X'; break; + default: cLed[i] = '?'; break; + } + l += snprintf(&s[l], size - l, "%c", cLed[i]); + } + + for (int i = 0; i < 3; i++) { + if (nextLed[i] != led[i]) { + led[i] = nextLed[i]; + switch (i) { + case 0: l += snprintf(&s[l], size - l, " -> Red = %c", cLed[i]); break; + case 1: l += snprintf(&s[l], size - l, " -> Yellow = %c", cLed[i]); break; + case 2: l += snprintf(&s[l], size - l, " -> Green = %c", cLed[i]); break; + } + } + } + if (nextSw2 != sw2) { + l += snprintf(&s[l], size - l, " SW2 %s", nextSw2 ? "pressed" : "not pressed"); + sw2 = nextSw2; + } } break; } + case BoardSure: { static int8_t led[4] = { -1, -1, -1, -1 }; // pin floating + static uint8_t mask[4] = { 0x08, 0x04, 0x02, 0x01 }; // Bitmask for LED PA3, PA2, PA1, PA0 + static int8_t sw[2] = { -1, -1 }; + static uint8_t swMask[2] = { 0x80, 0x40 }; + int nextLed[4] = { -1, -1, -1, -1 }; + int nextSw[2] = { -1, -1 }; + char cLed[4]; uint8_t ddra = avr->data[0x3a]; uint8_t porta = avr->data[0x3b]; + uint8_t ddrc = avr->data[0x34]; + uint8_t pinc = avr->data[0x33]; int change = 0; for (int i = 0; i < 4; i++) { - int8_t nextLed = -1; - if (ddra & (1 << i)) { - nextLed = porta & (1 << i) ? 0 : 1; // port output + if (ddra & mask[i]) { + nextLed[i] = porta & mask[i] ? 1 : 0; } else { - nextLed = 0; // port input _> led is off + nextLed[i] = -1; } - if (nextLed != led[i]) { - change = 1; - led[i] = nextLed; + if (!onlyOnChange || nextLed[i] != led[i]) { + change++; + rv = true; } } - if (!onlyOnChange || change) { - int n = snprintf(s, size, "LED PA[3210] ="); - for (int i = 3; i >= 0; i--) { - n += snprintf(s + n, size - n, " %c", led[i] == 1 ? 'X' : '.'); + + for (int i = 0; i < 2; i++) { + if ((ddrc & swMask[i]) == 0) { + nextSw[i] = (pinc & swMask[i]) == 0 ? 1 : 0; + } else { + nextSw[i] = -1; + } + if (!onlyOnChange || nextSw[i] != sw[i]) { + change++; + rv = true; + } + } + + int l = 0; + if (change) { + char c[2]; + for (int i = 0; i < 2; i++){ + switch (nextSw[i]) { + case 0: c[i] = '.';break; + case 1: c[i] = 'X'; break; + default: c[i] = '?'; break; + } + } + l += snprintf(&s[l], size - l, "SW1:2 = %c%c", c[0], c[1]); + + l += snprintf(&s[l], size - l, " LED PA3:0 = "); + for (int i = 0; i < 4; i++) { + switch (nextLed[i]) { + case -1: cLed[i] = '-'; break; + case 0: cLed[i] = '.'; break; + case 1: cLed[i] = 'X'; break; + default: cLed[i] = '?'; break; + } + l += snprintf(&s[l], size - l, "%c", cLed[i]); + } + for (int i = 0; i < 4; i++) { + if (nextLed[i] != led[i]) { + led[i] = nextLed[i]; + switch (i) { + case 0: l += snprintf(&s[l], l, " -> PA3 = %c", cLed[i]); break; + case 1: l += snprintf(&s[l], l, " -> PA2 = %c", cLed[i]); break; + case 2: l += snprintf(&s[l], l, " -> PA1 = %c", cLed[i]); break; + case 3: l += snprintf(&s[l], l, " -> PA0 = %c", cLed[i]); break; + } + + } + } + for (int i = 0; i < 2; i++) { + if (sw[i] != nextSw[i]) { + sw[i] = nextSw[i]; + l += snprintf(&s[l], size - l, " SW%d %s", i + 1, nextSw[i] ? "pressed" : "not pressed"); + } } - rv = true; } break; } @@ -569,7 +727,7 @@ void SimAvr::avrRun () { long cnt = 0; int lastAvrState = -1; _avr_sp_set(avr, 0); - char led[80]; + char led[120]; while (1) { try { if (sprintfLedStatus(led, sizeof(led), true)) { @@ -641,6 +799,22 @@ void SimAvr::avrRun () { lastAvrState = avr->state; } + if (avr->gdb != NULL) { + static int session = -1; + void *p = (void *)avr->gdb; + Gdb *pg = (Gdb *)p; + if (pg->s != session) { + if (pg->s == -1) { + printf("\navr-gdb disconnected%s\n\n", avr->state == cpu_Stopped ? "" : " (CPU stopped)"); + + } else { + printf("\navr-gdb connected%s\n\n", avr->state == cpu_Stopped ? "" : " (CPU stopped)"); + } + session = pg->s; + avr->state = cpu_Stopped; + } + } + if (cnt <= 0) { // usleep(10000); if (pthread_mutex_lock(&lock)) { @@ -760,6 +934,14 @@ void SimAvr::avrRun () { nextCommand = ReadyForNewCommand; break; } + case CommandStepi: { + if (avr->state != cpu_Step) { + avr->state = cpu_Step; + updateState = true; + } + nextCommand = ReadyForNewCommand; + break; + } case CommandContinue: { if (avr->state == cpu_Stopped) { avr->state = cpu_Running; @@ -817,6 +999,63 @@ void SimAvr::avrRun () { break; } + case CommandSW1Released: { + if (startParameters->board == BoardSure) { + uint8_t ddrc = avr->data[0x34]; // Atmega16 + if ((ddrc & 0x80) == 0) { + avr_raise_irq(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 7), 0x80); + } + } + nextCommand = ReadyForNewCommand; + break; + } + + case CommandSW1Pressed: { + if (startParameters->board == BoardSure) { + uint8_t ddrc = avr->data[0x34]; // Atmega16 + if ( (ddrc & 0x80) == 0) { + avr_raise_irq(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 7), 0x00); + } + } + nextCommand = ReadyForNewCommand; + break; + } + + case CommandSW2Released: { + if (startParameters->board == BoardNano644) { + uint8_t ddrc = avr->data[0x27]; // Atmega644P + uint8_t portc = avr->data[0x28]; // Atmega644P + if ( (ddrc & 0x20) == 0 && (portc & 0x20) == 0x20) { // internal pullup needed + avr_raise_irq(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 5), 0x20); + } + } else if (startParameters->board == BoardSure) { + uint8_t ddrc = avr->data[0x34]; // Atmega16 + if ( (ddrc & 0x40) == 0) { + avr_raise_irq(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 6), 0x40); + } + } + nextCommand = ReadyForNewCommand; + break; + } + + case CommandSW2Pressed: { + if (startParameters->board == BoardNano644 || startParameters->board == BoardNano1284) { + uint8_t ddrc = avr->data[0x27]; // Atmega644P + uint8_t portc = avr->data[0x28]; // Atmega644P + if ( (ddrc & 0x20) == 0 && (portc & 0x20) == 0x20) { // internal pullup needed + avr_raise_irq(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 5), 0x00); + } + } else if (startParameters->board == BoardSure) { + uint8_t ddrc = avr->data[0x34]; // Atmega16 + if ( (ddrc & 0x80) == 0) { // external pullup on board + avr_raise_irq(avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('C'), 6), 0); + } + + } + nextCommand = ReadyForNewCommand; + break; + } + default: { nextCommand = ReadyForNewCommand; break; diff --git a/examples/simuc/src/simavr/simavr.h b/examples/simuc/src/simavr/simavr.h index 39b58c9..4298ee7 100644 --- a/examples/simuc/src/simavr/simavr.h +++ b/examples/simuc/src/simavr/simavr.h @@ -15,6 +15,8 @@ typedef enum { BoardUnknown = 0, BoardNano, + BoardNano644, + BoardNano1284, BoardSure, BoardEWS1 } EnumStartParameterBoard; @@ -57,13 +59,19 @@ typedef enum { typedef enum { ReadyForNewCommand = 0, + CommandHelp, CommandStatus, CommandQuit, CommandBreak, + CommandStepi, CommandContinue, CommandStack, CommandReset, - CommandPower + CommandPower, + CommandSW1Released, + CommandSW1Pressed, + CommandSW2Released, + CommandSW2Pressed, } EnumSimAvrCommand; struct SimAvrStatus { @@ -116,7 +124,7 @@ public: private: elf_firmware_t *firmware = NULL; - avr_t *avr = NULL;; + avr_t *avr = NULL; StartParameters *startParameters = NULL;; pthread_mutex_t lock; std::list events;