HEAD commit b6ab40e12fb94e39ad5b2b2da8417edeec9d9dae master-sx
receivedTue, 3. Sep 2024, 11:10:17 (by user sx)
Tue, 3 Sep 2024 09:10:17 +0000 (11:10 +0200)
authorManfred Steiner <sx@htl-kaindorf.at>
Tue, 3 Sep 2024 09:10:13 +0000 (11:10 +0200)
committerManfred Steiner <sx@htl-kaindorf.at>
Tue, 3 Sep 2024 09:10:13 +0000 (11:10 +0200)
7 files changed:
examples/simuc/.vscode/c_cpp_properties.json
examples/simuc/.vscode/launch.json
examples/simuc/.vscode/settings.json
examples/simuc/src/main.cpp
examples/simuc/src/sim/sim.cpp
examples/simuc/src/simavr/simavr.cpp
examples/simuc/src/simavr/simavr.h

index ba80ed41e973906967100d1c13adee4c2eb69a7d..e6ad2abacb13469a79f32c1720e8978ff868a2bb 100644 (file)
@@ -7,7 +7,7 @@
       "compilerPath": "/usr/bin/gcc",
       "cStandard": "c11",
       "cppStandard": "c++17",
-      "intelliSenseMode": "clang-x64"
+      "intelliSenseMode": "linux-gcc-x64"
     }
   ],
   "version": 4
index 4c40c7b04869fba69971bb7af3171ad204886949..b6d3ec25fc10ae88749dfadfc5d486e75e435afb 100644 (file)
@@ -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": [],
index 4c1291f55dec43d8e2ffc89de9d93aecbbd05565..a2774e887c580decd81cd706fb18d0706d29ce44 100644 (file)
@@ -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
index 19cefa85650fc79d4c791be7cf4876e63de77113..4e31b09c35ade0089af7fabede3a4166a32cd88b 100644 (file)
@@ -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 &params) {
+    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 <Enter> 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 <Enter> 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++) {
index c1ec1e3d17bd814acc9ab2750eaf8274bf81060d..9eee696affa47dc8c230b0e1b2e8b941b9102abe 100644 (file)
@@ -99,8 +99,16 @@ const char * lastError () {
 
 std::vector<uint8_t> gdbFromUartBuffer;
 std::vector<uint8_t> 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;
index 9c974b5b4660d1cba382aeab9c36beda1954caaa..94c371735df00e5f50fa1cb033acf54dc5110ea7 100644 (file)
 #include <simavr/sim_avr.h>
 #include <simavr/sim_core.h>
 #include <simavr/avr_uart.h>
+#include <simavr/avr_ioport.h>
+
+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;
index 39b58c94087561ee1ab883e1865248ba5341e303..4298ee7f459fe3e3a79aa062a5ec9013e97ab7ae 100644 (file)
@@ -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<struct SimAvrEvent *> events;