diff --git a/JumperlessNano/.vscode/settings.json b/JumperlessNano/.vscode/settings.json index 92bf88e..559225f 100644 --- a/JumperlessNano/.vscode/settings.json +++ b/JumperlessNano/.vscode/settings.json @@ -8,8 +8,10 @@ "vector": "cpp", "string_view": "cpp", "initializer_list": "cpp", - "ranges": "cpp" + "ranges": "cpp", + "cstring": "cpp" }, - "cortex-debug.registerUseNaturalFormat": false + "cortex-debug.registerUseNaturalFormat": false, + "C_Cpp.errorSquiggles": "disabled" } \ No newline at end of file diff --git a/JumperlessNano/data/nodeFile.txt b/JumperlessNano/data/nodeFile.txt index ebaf930..b3bff3c 100644 --- a/JumperlessNano/data/nodeFile.txt +++ b/JumperlessNano/data/nodeFile.txt @@ -1,22 +1,32 @@ bridges { 1-2, -3-4, -5-6, -7-8, +30-4, +50-60, +17-38, 9-10, -11-12, -12-13, -2-3, -10-11, +16-12, +D13-D1, +D0-1, +A1-5, +D13-A7, +AREF-A1, +20-33, +10-41, +D10-D11, +D11-D12, 1-11, -0-7, +D2-33, +D9,18, +D5-44, +A2-33, } -special functions +special functions //these are connected first so DNIs will be applied to all the nets { -1-GND, +19-GND, 11-SUPPLY_5V, +D10-SUPPLY_3V3, 6-I_P, I_P-I_N, } diff --git a/JumperlessNano/platformio.ini b/JumperlessNano/platformio.ini index 207c843..6e5caea 100644 --- a/JumperlessNano/platformio.ini +++ b/JumperlessNano/platformio.ini @@ -17,5 +17,5 @@ board_build.filesystem_size = 0.5m [env:pico] board = pico lib_deps = - bblanchon/ArduinoJson@^6.21.2 - bblanchon/StreamUtils@^1.7.3 + powerbroker2/SafeString@^4.1.27 + adafruit/Adafruit NeoPixel@^1.11.0 diff --git a/JumperlessNano/src/FileParsing.cpp b/JumperlessNano/src/FileParsing.cpp new file mode 100644 index 0000000..98643ba --- /dev/null +++ b/JumperlessNano/src/FileParsing.cpp @@ -0,0 +1,257 @@ +#include "FileParsing.h" +#include +#include "LittleFS.h" +#include "MatrixStateRP2040.h" +#include "SafeString.h" +#include "NetManager.h" + +static bool debugFP; +static bool debugFPtime; + +createSafeString(nodeFileString, 1200); +createSafeString(bridgeString, 800); +createSafeString(specialFunctionsString, 400); + +File nodeFile; + +unsigned long timeToFP = 0; + + +void openNodeFile() +{ + timeToFP = millis(); + if(DEBUG_FILEPARSING == 1) debugFP = true; //yeah we're using runtime debug flags so it can be toggled from commands + else debugFP = false; + if(TIME_FILEPARSING == 1) debugFPtime = true; + else debugFPtime = false; + + nodeFile = LittleFS.open("nodeFile.txt", "r"); + if (!nodeFile) + { + if(debugFP)Serial.println("Failed to open nodeFile"); + return; + } + else + { + if(debugFP)Serial.println("\n\ropened nodeFile.txt\n\n\rloading bridges from file\n\r"); + } + + nodeFileString.read(nodeFile); + + nodeFile.close(); + splitStringToFields(); + // parseStringToBridges(); +} + +void splitStringToFields() +{ + int openBraceIndex = 0; + int closeBraceIndex = 0; + + if(debugFP)Serial.println("\n\rraw input file\n\r"); + if(debugFP)Serial.println(nodeFileString); + if(debugFP)Serial.println("\n\rsplitting and cleaning up string\n\r"); + if(debugFP)Serial.println("_"); + openBraceIndex = nodeFileString.indexOf("{"); + closeBraceIndex = nodeFileString.indexOf("}"); + nodeFileString.substring(bridgeString ,openBraceIndex + 1, closeBraceIndex); + bridgeString.trim(); + + if(debugFP)Serial.println(bridgeString); + + if(debugFP)Serial.println("^\n\r"); + + nodeFileString.remove(0, closeBraceIndex + 1); + nodeFileString.trim(); + + openBraceIndex = nodeFileString.indexOf("{"); + closeBraceIndex = nodeFileString.indexOf("}"); + nodeFileString.substring(specialFunctionsString, openBraceIndex + 1, closeBraceIndex); + specialFunctionsString.trim(); + if(debugFP)Serial.println("_"); + if(debugFP)Serial.println(specialFunctionsString); + if(debugFP)Serial.println("^\n\r"); + replaceSFNamesWithDefinedInts(); +} + +void replaceSFNamesWithDefinedInts(void) +{ + if(debugFP)Serial.println("replacing special function names with defined ints\n\r"); + specialFunctionsString.replace("GND", "100"); + specialFunctionsString.replace("SUPPLY_5V", "105"); + specialFunctionsString.replace("SUPPLY_3V3", "103"); + specialFunctionsString.replace("DAC0_5V", "106"); + specialFunctionsString.replace("DAC1_8V", "107"); + specialFunctionsString.replace("I_N", "109"); + specialFunctionsString.replace("I_P", "108"); + specialFunctionsString.replace("EMPTY_NET", "127"); + + if(debugFP)Serial.println(specialFunctionsString); + if(debugFP)Serial.println("\n\n\r"); + + replaceNanoNamesWithDefinedInts(); +} + +void replaceNanoNamesWithDefinedInts(void)//for dome reason Arduino's String wasn't replacing like 1 or 2 of the names, so I'm using SafeString now and it works +{ + if(debugFP)Serial.println("replacing special function names with defined ints\n\r"); + char nanoName[5]; + + + itoa(NANO_D10, nanoName, 10); + specialFunctionsString.replace("D10", nanoName); + bridgeString.replace("D10", nanoName); + itoa(NANO_D11, nanoName, 10); + specialFunctionsString.replace("D11", nanoName); + bridgeString.replace("D11", nanoName); + itoa(NANO_D12, nanoName, 10); + specialFunctionsString.replace("D12", nanoName); + bridgeString.replace("D12", nanoName); + itoa(NANO_D13, nanoName, 10); + specialFunctionsString.replace("D13", nanoName); + bridgeString.replace("D13", nanoName); + itoa(NANO_D0, nanoName, 10); + specialFunctionsString.replace("D0", nanoName); + bridgeString.replace("D0", nanoName); + itoa(NANO_D1, nanoName, 10); + specialFunctionsString.replace("D1", nanoName); + bridgeString.replace("D1", nanoName); + itoa(NANO_D2, nanoName, 10); + specialFunctionsString.replace("D2", nanoName); + bridgeString.replace("D2", nanoName); + itoa(NANO_D3, nanoName, 10); + specialFunctionsString.replace("D3", nanoName); + bridgeString.replace("D3", nanoName); + itoa(NANO_D4, nanoName, 10); + specialFunctionsString.replace("D4", nanoName); + bridgeString.replace("D4", nanoName); + itoa(NANO_D5, nanoName, 10); + specialFunctionsString.replace("D5", nanoName); + bridgeString.replace("D5", nanoName); + itoa(NANO_D6, nanoName, 10); + specialFunctionsString.replace("D6", nanoName); + bridgeString.replace("D6", nanoName); + itoa(NANO_D7, nanoName, 10); + specialFunctionsString.replace("D7", nanoName); + bridgeString.replace("D7", nanoName); + itoa(NANO_D8, nanoName, 10); + specialFunctionsString.replace("D8", nanoName); + bridgeString.replace("D8", nanoName); + itoa(NANO_D9, nanoName, 10); + specialFunctionsString.replace("D9", nanoName); + bridgeString.replace("D9", nanoName); + itoa(NANO_RESET, nanoName, 10); + specialFunctionsString.replace("RESET", nanoName); + bridgeString.replace("RESET", nanoName); + itoa(NANO_AREF, nanoName, 10); + specialFunctionsString.replace("AREF", nanoName); + bridgeString.replace("AREF", nanoName); + itoa(NANO_A0, nanoName, 10); + specialFunctionsString.replace("A0", nanoName); + bridgeString.replace("A0", nanoName); + itoa(NANO_A1, nanoName, 10); + specialFunctionsString.replace("A1", nanoName); + bridgeString.replace("A1", nanoName); + itoa(NANO_A2, nanoName, 10); + specialFunctionsString.replace("A2", nanoName); + bridgeString.replace("A2", nanoName); + itoa(NANO_A3, nanoName, 10); + specialFunctionsString.replace("A3", nanoName); + bridgeString.replace("A3", nanoName); + itoa(NANO_A4, nanoName, 10); + specialFunctionsString.replace("A4", nanoName); + bridgeString.replace("A4", nanoName); + itoa(NANO_A5, nanoName, 10); + specialFunctionsString.replace("A5", nanoName); + bridgeString.replace("A5", nanoName); + itoa(NANO_A6, nanoName, 10); + specialFunctionsString.replace("A6", nanoName); + bridgeString.replace("A6", nanoName); + itoa(NANO_A7, nanoName, 10); + specialFunctionsString.replace("A7", nanoName); + bridgeString.replace("A7", nanoName); + + + if(debugFP)Serial.println(bridgeString); + if(debugFP)Serial.println(specialFunctionsString); + if(debugFP)Serial.println("\n\n\r"); + + parseStringToBridges(); +} + +void parseStringToBridges(void) +{ + + int bridgeStringLength = bridgeString.length() - 1; + + int specialFunctionsStringLength = specialFunctionsString.length() - 1; + + int readLength = 0; + int readTotal = specialFunctionsStringLength; + + newBridgeLength = 0; + newBridgeIndex = 0; + + if(debugFP)Serial.println("parsing bridges into array\n\r"); + + for (int i = 0; i <= specialFunctionsStringLength; i += readLength) + { + + sscanf(specialFunctionsString.c_str(), "%i-%i,\n\r%n", &path[newBridgeIndex].node1, &path[newBridgeIndex].node2, &readLength); + specialFunctionsString.remove(0, readLength); + + readTotal -= readLength; + + // if(debugFP)Serial.print(newBridge[newBridgeIndex][0]); + // if(debugFP)Serial.print("-"); + // if(debugFP)Serial.println(newBridge[newBridgeIndex][1]); + + newBridgeLength++; + newBridgeIndex++; + + // delay(500); + } + + readTotal = bridgeStringLength; + + for (int i = 0; i <= bridgeStringLength; i += readLength) + { + + sscanf(bridgeString.c_str(), "%i-%i,\n\r%n", &path[newBridgeIndex].node1, &path[newBridgeIndex].node2, &readLength); + bridgeString.remove(0, readLength); + + readTotal -= readLength; + + // if(debugFP)Serial.print(newBridge[newBridgeIndex][0]); + // if(debugFP)Serial.print("-"); + // if(debugFP)Serial.println(newBridge[newBridgeIndex][1]); + + newBridgeLength++; + newBridgeIndex++; + + // delay(500); + } + newBridgeIndex = 0; + if(debugFP) for (int i = 0; i < newBridgeLength; i++) + { + Serial.print("["); + Serial.print(path[newBridgeIndex].node1); + Serial.print("-"); + Serial.print(path[newBridgeIndex].node2); + Serial.print("],"); + newBridgeIndex++; + } + if(debugFP)Serial.print("\n\rbridge pairs = "); + if(debugFP)Serial.println(newBridgeLength); + + nodeFileString.clear(); + + + // if(debugFP)Serial.println(nodeFileString); + timeToFP = millis() - timeToFP; + if(debugFP)Serial.print("\n\rtook "); + + if(debugFPtime)Serial.print(timeToFP); + if(debugFPtime)Serial.println("ms to open and parse file\n\r"); +} + diff --git a/JumperlessNano/src/FileParsing.h b/JumperlessNano/src/FileParsing.h new file mode 100644 index 0000000..7994b93 --- /dev/null +++ b/JumperlessNano/src/FileParsing.h @@ -0,0 +1,20 @@ +#ifndef FILEPARSING_H +#define FILEPARSING_H + + +//this just opens the file, takes out all the bullshit, and then populates the newBridge array + + +void openNodeFile(); + +void splitStringToFields(); + +void replaceSFNamesWithDefinedInts(); + +void replaceNanoNamesWithDefinedInts(); + +void parseStringToBridges(); + + + +#endif \ No newline at end of file diff --git a/JumperlessNano/src/JumperlessDefinesRP2040.h b/JumperlessNano/src/JumperlessDefinesRP2040.h index 6a8e719..5c0c620 100644 --- a/JumperlessNano/src/JumperlessDefinesRP2040.h +++ b/JumperlessNano/src/JumperlessDefinesRP2040.h @@ -1,5 +1,10 @@ +#define DEBUG_FILEPARSING 1 +#define TIME_FILEPARSING 1 +#define DEBUG_NETMANAGER 1 +#define TIME_NETMANAGER 1 + #define MAX_NETS 64 #define MAX_BRIDGES 255 #define MAX_NODES 64 @@ -54,7 +59,10 @@ #define ADC2_5V 28 #define ADC3_8V 29 - +#define T_RAIL_POS 31 +#define T_RAIL_NEG 0 +#define B_RAIL_POS 63 +#define B_RAIL_NEG 32 #define t1 1 diff --git a/JumperlessNano/src/LEDs.cpp b/JumperlessNano/src/LEDs.cpp new file mode 100644 index 0000000..05d51e8 --- /dev/null +++ b/JumperlessNano/src/LEDs.cpp @@ -0,0 +1,46 @@ +#include "LEDs.h" +#include + + +Adafruit_NeoPixel leds(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); + + +void initLEDs(void) +{ + + + + leds.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) + leds.show(); // Turn OFF all pixels ASAP + leds.setBrightness(BRIGHTNESS); + +} + +void colorWipe(uint32_t color, int wait) { + + + for(int i=0; i +#include "JumperlessDefinesRP2040.h" +#include "Adafruit_NeoPixel.h" + +#define LED_PIN 25 +#define LED_COUNT 80 +#define BRIGHTNESS 50 + + + + +extern Adafruit_NeoPixel leds; + + + + + + +const int bbPixelToNodesMap[62] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30, + 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61}; + +const int railsToPixelMap[4][5] = {{71,74,75,78,79},//top positive rail + {72,73,76,77,80},//top negative rail + {70,67,66,63,62},//bottom positive rail + {69,68,65,64,61}};//bottom negative rail + + +const int pixelsToRails[20] = {B_RAIL_NEG, B_RAIL_POS, B_RAIL_POS, B_RAIL_NEG, B_RAIL_NEG, B_RAIL_POS, B_RAIL_POS, B_RAIL_NEG, B_RAIL_NEG, B_RAIL_POS, + T_RAIL_POS, T_RAIL_NEG, T_RAIL_NEG, T_RAIL_POS, T_RAIL_POS, T_RAIL_NEG, T_RAIL_NEG, T_RAIL_POS, T_RAIL_POS, T_RAIL_NEG}; + +void initLEDs(void); + +void colorWipe(uint32_t color, int wait); +void rainbowy(int ,int, int wait); + +#endif \ No newline at end of file diff --git a/JumperlessNano/src/MatrixStateRP2040.cpp b/JumperlessNano/src/MatrixStateRP2040.cpp index 7aa447e..a38586a 100644 --- a/JumperlessNano/src/MatrixStateRP2040.cpp +++ b/JumperlessNano/src/MatrixStateRP2040.cpp @@ -17,8 +17,6 @@ struct netStruct net[MAX_NETS] = { //these are the special function nets that wi { 5 ,"DAC 1\t" ,{DAC1_8V} ,{{}} ,DAC1_8V ,{} ,{GND,SUPPLY_5V,SUPPLY_3V3,DAC0_5V} , 1}, { 6 ,"I Sense +" ,{CURRENT_SENSE_PLUS} ,{{}} ,CURRENT_SENSE_PLUS ,{} ,{CURRENT_SENSE_MINUS} , 2}, { 7 ,"I Sense -" ,{CURRENT_SENSE_MINUS} ,{{}} ,CURRENT_SENSE_MINUS ,{} ,{CURRENT_SENSE_PLUS} , 2}, - //{ 8 ,"Net 8" ,{4,2,9,30,40,22,3} ,{{}} ,-1 ,{} ,{} , 0}, - //{ 9 ,"Net 9" ,{5,7,33,23,21,8,14} ,{{}} ,-1 ,{} ,{} , 0}, }; char *netNameConstants[MAX_NETS] = {(char*)"Net 0",(char*)"Net 1",(char*)"Net 2",(char*)"Net 3",(char*)"Net 4",(char*)"Net 5",(char*)"Net 6",(char*)"Net 7",(char*)"Net 8",(char*)"Net 9",(char*)"Net 10",(char*)"Net 11",(char*)"Net 12",(char*)"Net 13",(char*)"Net 14",(char*)"Net 15",(char*)"Net 16",(char*)"Net 17",(char*)"Net 18",(char*)"Net 19",(char*)"Net 20",(char*)"Net 21",(char*)"Net 22",(char*)"Net 23",(char*)"Net 24",(char*)"Net 25",(char*)"Net 26",(char*)"Net 27",(char*)"Net 28",(char*)"Net 29",(char*)"Net 30",(char*)"Net 31",(char*)"Net 32",(char*)"Net 33",(char*)"Net 34",(char*)"Net 35",(char*)"Net 36",(char*)"Net 37",(char*)"Net 38",(char*)"Net 39",(char*)"Net 40",(char*)"Net 41",(char*)"Net 42",(char*)"Net 43",(char*)"Net 44",(char*)"Net 45",(char*)"Net 46",(char*)"Net 47",(char*)"Net 48",(char*)"Net 49",(char*)"Net 50",(char*)"Net 51",(char*)"Net 52",(char*)"Net 53",(char*)"Net 54",(char*)"Net 55",(char*)"Net 56",(char*)"Net 57",(char*)"Net 58",(char*)"Net 59",(char*)"Net 60",(char*)"Net 61",(char*)"Net 62"};//,{"Net 63",(char*)"Net 64",(char*)"Net 65",(char*)"Net 66",(char*)"Net 67",(char*)"Net 68",(char*)"Net 69",(char*)"Net 70",(char*)"Net 71",(char*)"Net 72",(char*)"Net 73",(char*)"Net 74",(char*)"Net 75",(char*)"Net 76",(char*)"Net 77",(char*)"Net 78",(char*)"Net 79",(char*)"Net 80",(char*)"Net 81",(char*)"Net 82",(char*)"Net 83",(char*)"Net 84",(char*)"Net 85",(char*)"Net 86",(char*)"Net 87",(char*)"Net 88",(char*)"Net 89",(char*)"Net 90",(char*)"Net 91",(char*)"Net 92",(char*)"Net 93",(char*)"Net 94",(char*)"Net 95",(char*)"Net 96",(char*)"Net 97",(char*)"Net 98",(char*)"Net 99",(char*)"Net 100",(char*)"Net 101",(char*)"Net 102",(char*)"Net 103",(char*)"Net 104",(char*)"Net 105",(char*)"Net 106",(char*)"Net 107",(char*)"Net 108",(char*)"Net 109",(char*)"Net 110",(char*)"Net 111",(char*)"Net 112",(char*)"Net 113",(char*)"Net 114",(char*)"Net 115",(char*)"Net 116",(char*)"Net 117",(char*)"Net 118",(char*)"Net 119",(char*)"Net 120",(char*)"Net 121",(char*)"Net 122",(char*)"Net 123",(char*)"Net 124",(char*)"Net 125",(char*)"Net 126",(char*)"Net 127"}}; @@ -100,34 +98,43 @@ struct chipStatus ch[12] = { enum nanoPinsToIndex { NANO_PIN_D0 , NANO_PIN_D1 , NANO_PIN_D2 , NANO_PIN_D3 , NANO_PIN_D4 , NANO_PIN_D5 , NANO_PIN_D6 , NANO_PIN_D7 , NANO_PIN_D8 , NANO_PIN_D9 , NANO_PIN_D10 , NANO_PIN_D11 , NANO_PIN_D12 , NANO_PIN_D13 , NANO_PIN_RST , NANO_PIN_REF , NANO_PIN_A0 , NANO_PIN_A1 , NANO_PIN_A2 , NANO_PIN_A3 , NANO_PIN_A4 , NANO_PIN_A5 , NANO_PIN_A6 , NANO_PIN_A7 }; -extern struct nanoStatus nano; -char same[12]; -const char* definesToChar (int defined) //converts the internally used #defined numbers into human readable strings -{ +struct nanoStatus nano = { //there's only one of these so ill declare and initalize together unlike above +//all these arrays should line up (both by index and visually) so one index will give you all this data -itoa(defined,same,10); -const char *defNanoToChar[26] = {"NANO_D0", "NANO_D1", "NANO_D2", "NANO_D3", "NANO_D4", "NANO_D5", "NANO_D6", "NANO_D7", "NANO_D8", "NANO_D9", "NANO_D10", "NANO_D11", "NANO_D12", "NANO_D13", "NANO_RESET", "NANO_AREF", "NANO_A0", "NANO_A1", "NANO_A2", "NANO_A3", "NANO_A4", "NANO_A5", "NANO_A6", "NANO_A7"}; -const char *defSpecialToChar[12] = {"GND","NOT_DEFINED","NOT_DEFINED","3V3","NOT_DEFINED","5V","DAC_0","DAC_1","I_POS","I_NEG"}; -const char *emptyNet[] = {"EMPTY_NET", "?"}; +// | | | | | | | | | | | | | | | | | | | | | | | | | + { " D0", " D1", " D2", " D3", " D4", " D5", " D6", " D7", " D8", " D9", "D10", "D11", "D12", "D13", "RST", "REF", " A0", " A1", " A2", " A3", " A4", " A5", " A6", " A7"},// String with readable name //padded to 3 chars (space comes before chars) +// | | | | | | | | | | | | | | | | | | | | | | | | | + { NANO_D0, NANO_D1, NANO_D2, NANO_D3, NANO_D4, NANO_D5, NANO_D6, NANO_D7, NANO_D8, NANO_D9, NANO_D10, NANO_D11, NANO_D12, NANO_D13, NANO_RESET, NANO_AREF, NANO_A0, NANO_A1, NANO_A2, NANO_A3, NANO_A4, NANO_A5, NANO_A6, NANO_A7},//Array index to internal arbitrary #defined number +// | | | | | | | | | | | | | | | | | | | | | | | | | + { 1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 1 },//Whether this pin has 1 or 2 connections to special function chips (OR maybe have it be a map like i = 2 j = 3 k = 4 l = 5 if there's 2 it's the product of them ij = 6 ik = 8 il = 10 jk = 12 jl = 15 kl = 20 we're trading minuscule amounts of CPU for RAM) +// | | | | | | | | | | | | | | | | | | | | | | | | | + { CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J },//Since there's no overlapping connections between Chip I and J, this holds which of those 2 chips has a connection at that index, if numConns is 1, you only need to check this one + { -1 , -1 , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , -1 , -1 , -1 , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_L , CHIP_L , -1 , -1 },//Since there's no overlapping connections between Chip K and L, this holds which of those 2 chips has a connection at that index, -1 for no connection +// | | | | | | | | | | | | | | | | | | | | | | | | | + { -1 , 1 , -1 , 3 , -1 , 5 , -1 , 7 , -1 , 9 , -1 , 8 , -1 , 10 , 11 , -1 , 0 , -1 , 2 , -1 , 4 , -1 , 6 , -1 },//holds which X pin is connected to the index on Chip I, -1 for none + { -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 },//-1 for not connected to that chip, 0 for available, >0 means it's connected and the netNumber is stored here +// | | | | | | | | | | | | | | | | | | | | | | | | | + { 0 , -1 , 2 , -1 , 4 , -1 , 6 , -1 , 8 , -1 , 9 , -1 , 10 , -1 , -1 , 11 , -1 , 1 , -1 , 3 , -1 , 5 , -1 , 7 },//holds which X pin is connected to the index on Chip J, -1 for none + { 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 },//-1 for not connected to that chip, 0 for available, >0 means it's connected and the netNumber is stored here +// | | | | | | | | | | | | | | | | | | | | | | | | | + { -1 , -1 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , -1 , -1 , -1 , 0 , 1 , 2 , 3 , -1 , -1 , -1 , -1 },//holds which X pin is connected to the index on Chip K, -1 for none + { -1 , -1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , -1 , -1 , -1 , -1 },//-1 for not connected to that chip, 0 for available, >0 means it's connected and the netNumber is stored here +// | | | | | | | | | | | | | | | | | | | | | | | | | + { -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , 12 , 13 , -1 , -1 },//holds which X pin is connected to the index on Chip L, -1 for none + { -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , 0 , 0 , -1 , -1 },//-1 for not connected to that chip, 0 for available, >0 means it's connected and the netNumber is stored here -if (defined >= 70 && defined <= 93) -{ -return defNanoToChar[defined-70]; -} else if (defined >= 100 && defined <= 110) - { - return defSpecialToChar[defined-100]; - } else if (defined == EMPTY_NET) - { - return emptyNet[0]; - }else { - //itoa(defined,same,10); - return " "; - } +// mapIJKL[] will tell you whethher there's a connection from that nano pin to the corresponding special function chip +// xMapIJKL[] will tell you the X pin that it's connected to on that sf chip +// xStatusIJKL[] says whether that x pin is being used (this should be the same as mt[8-10].xMap[] if theyre all stacked on top of each other) +// I haven't decided whether to make this just a flag, or store that signal's destination + {NANO_D0, NANO_D1, NANO_D2, NANO_D3, NANO_D4, NANO_D5, NANO_D6, NANO_D7, NANO_D8, NANO_D9, NANO_D10, NANO_D11, NANO_D12, NANO_D13, NANO_RESET, NANO_AREF, NANO_A0, NANO_A1, NANO_A2, NANO_A3, NANO_A4, NANO_A5, NANO_A6, NANO_A7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,GND,101,102,SUPPLY_3V3,104,SUPPLY_5V,DAC0_5V,DAC1_8V,CURRENT_SENSE_PLUS,CURRENT_SENSE_MINUS} +}; + +struct pathStruct path[MAX_BRIDGES]; // node1, node2, net, chip[3], x[3], y[3] -} /* struct nanoStatus nanoConnections = { //there's only one of these so ill declare and initalize together unlike above diff --git a/JumperlessNano/src/MatrixStateRP2040.h b/JumperlessNano/src/MatrixStateRP2040.h index 2670a43..349440a 100644 --- a/JumperlessNano/src/MatrixStateRP2040.h +++ b/JumperlessNano/src/MatrixStateRP2040.h @@ -2,16 +2,9 @@ #define MATRIXSTATE_H #include +#include "JumperlessDefinesRP2040.h" -/* - -int netIndex = 8; //either search for the next available empty net or keep an index? - -int8_t bridges[MAX_BRIDGES][3];//{{netNumber,node1,node2}, ...} //should bridges be stored inside or outside the net structs? - -*/ - struct netStruct{ uint8_t number; //nets are uint8_t, nodes are int8_t @@ -35,90 +28,79 @@ uint8_t priority = 0; //priority = 1 means it will move connections to take the extern struct netStruct net[MAX_NETS]; -//thanks Copilot for not making me type all this out - -//this needs to be here so the pointers have somewhere to point to when we name nets - extern char *netNameConstants[MAX_NETS]; + struct chipStatus{ int chipNumber; + char chipChar; + int8_t xStatus[16]; //store the bb row or nano conn this is eventually connected to so they can be stacked if conns are redundant + int8_t yStatus[8]; //store the row/nano it's connected to + const int8_t xMap[16]; + const int8_t yMap[8]; }; +extern struct chipStatus ch[12]; struct nanoStatus { //there's only one of these so ill declare and initalize together unlike above //all these arrays should line up (both by index and visually) so one index will give you all this data -// | | | | | | | | | | | | | | | | | | | | | | | | | -const char *pinNames[24]= { " D0", " D1", " D2", " D3", " D4", " D5", " D6", " D7", " D8", " D9", "D10", "D11", "D12", "D13", "RST", "REF", " A0", " A1", " A2", " A3", " A4", " A5", " A6", " A7"};// String with readable name //padded to 3 chars (space comes before chars) -// | | | | | | | | | | | | | | | | | | | | | | | | | -const int8_t pinMap[24] = { NANO_D0, NANO_D1, NANO_D2, NANO_D3, NANO_D4, NANO_D5, NANO_D6, NANO_D7, NANO_D8, NANO_D9, NANO_D10, NANO_D11, NANO_D12, NANO_D13, NANO_RESET, NANO_AREF, NANO_A0, NANO_A1, NANO_A2, NANO_A3, NANO_A4, NANO_A5, NANO_A6, NANO_A7};//Array index to internal arbitrary #defined number -// | | | | | | | | | | | | | | | | | | | | | | | | | -const int8_t numConns[24]= { 1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 1 };//Whether this pin has 1 or 2 connections to special function chips (OR maybe have it be a map like i = 2 j = 3 k = 4 l = 5 if there's 2 it's the product of them ij = 6 ik = 8 il = 10 jk = 12 jl = 15 kl = 20 we're trading minuscule amounts of CPU for RAM) -// | | | | | | | | | | | | | | | | | | | | | | | | | -const int8_t mapIJ[24] = { CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J };//Since there's no overlapping connections between Chip I and J, this holds which of those 2 chips has a connection at that index, if numConns is 1, you only need to check this one -const int8_t mapKL[24] = { -1 , -1 , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , -1 , -1 , -1 , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_L , CHIP_L , -1 , -1 };//Since there's no overlapping connections between Chip K and L, this holds which of those 2 chips has a connection at that index, -1 for no connection -// | | | | | | | | | | | | | | | | | | | | | | | | | -const int8_t xMapI[24] = { -1 , 1 , -1 , 3 , -1 , 5 , -1 , 7 , -1 , 9 , -1 , 8 , -1 , 10 , 11 , -1 , 0 , -1 , 2 , -1 , 4 , -1 , 6 , -1 };//holds which X pin is connected to the index on Chip I, -1 for none - int8_t xStatusI[24] = { -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 };//-1 for not connected to that chip, 0 for available, >0 means it's connected and the netNumber is stored here -// | | | | | | | | | | | | | | | | | | | | | | | | | -const int8_t xMapJ[24] = { 0 , -1 , 2 , -1 , 4 , -1 , 6 , -1 , 8 , -1 , 9 , -1 , 10 , -1 , -1 , 11 , -1 , 1 , -1 , 3 , -1 , 5 , -1 , 7 };//holds which X pin is connected to the index on Chip J, -1 for none - int8_t xStatusJ[24] = { 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 };//-1 for not connected to that chip, 0 for available, >0 means it's connected and the netNumber is stored here -// | | | | | | | | | | | | | | | | | | | | | | | | | -const int8_t xMapK[24] = { -1 , -1 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , -1 , -1 , -1 , 0 , 1 , 2 , 3 , -1 , -1 , -1 , -1 };//holds which X pin is connected to the index on Chip K, -1 for none - int8_t xStatusK[24] = { -1 , -1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , -1 , -1 , -1 , -1 };//-1 for not connected to that chip, 0 for available, >0 means it's connected and the netNumber is stored here -// | | | | | | | | | | | | | | | | | | | | | | | | | -const int8_t xMapL[24] = { -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , 12 , 13 , -1 , -1 };//holds which X pin is connected to the index on Chip L, -1 for none - int8_t xStatusL[24] = { -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , 0 , 0 , -1 , -1 };//-1 for not connected to that chip, 0 for available, >0 means it's connected and the netNumber is stored here +// | | | | | | | | | | | | | | | | | | | | | | | | | +const char *pinNames[24];//= { " D0", " D1", " D2", " D3", " D4", " D5", " D6", " D7", " D8", " D9", "D10", "D11", "D12", "D13", "RST", "REF", " A0", " A1", " A2", " A3", " A4", " A5", " A6", " A7"};// String with readable name //padded to 3 chars (space comes before chars) +// | | | | | | | | | | | | | | | | | | | | | | | | | +const int8_t pinMap[24];// = { NANO_D0, NANO_D1, NANO_D2, NANO_D3, NANO_D4, NANO_D5, NANO_D6, NANO_D7, NANO_D8, NANO_D9, NANO_D10, NANO_D11, NANO_D12, NANO_D13, NANO_RESET, NANO_AREF, NANO_A0, NANO_A1, NANO_A2, NANO_A3, NANO_A4, NANO_A5, NANO_A6, NANO_A7};//Array index to internal arbitrary #defined number +// | | | | | | | | | | | | | | | | | | | | | | | | | +const int8_t numConns[24];//= { 1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 1 };//Whether this pin has 1 or 2 connections to special function chips (OR maybe have it be a map like i = 2 j = 3 k = 4 l = 5 if there's 2 it's the product of them ij = 6 ik = 8 il = 10 jk = 12 jl = 15 kl = 20 we're trading minuscule amounts of CPU for RAM) +// | | | | | | | | | | | | | | | | | | | | | | | | | +const int8_t mapIJ[24];// = { CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J };//Since there's no overlapping connections between Chip I and J, this holds which of those 2 chips has a connection at that index, if numConns is 1, you only need to check this one +const int8_t mapKL[24];// = { -1 , -1 , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , -1 , -1 , -1 , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_L , CHIP_L , -1 , -1 };//Since there's no overlapping connections between Chip K and L, this holds which of those 2 chips has a connection at that index, -1 for no connection +// | | | | | | | | | | | | | | | | | | | | | | | | | +const int8_t xMapI[24];// = { -1 , 1 , -1 , 3 , -1 , 5 , -1 , 7 , -1 , 9 , -1 , 8 , -1 , 10 , 11 , -1 , 0 , -1 , 2 , -1 , 4 , -1 , 6 , -1 };//holds which X pin is connected to the index on Chip I, -1 for none + int8_t xStatusI[24];// = { -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 };//-1 for not connected to that chip, 0 for available, >0 means it's connected and the netNumber is stored here +// | | | | | | | | | | | | | | | | | | | | | | | | | +const int8_t xMapJ[24];// = { 0 , -1 , 2 , -1 , 4 , -1 , 6 , -1 , 8 , -1 , 9 , -1 , 10 , -1 , -1 , 11 , -1 , 1 , -1 , 3 , -1 , 5 , -1 , 7 };//holds which X pin is connected to the index on Chip J, -1 for none + int8_t xStatusJ[24];// = { 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 };//-1 for not connected to that chip, 0 for available, >0 means it's connected and the netNumber is stored here +// | | | | | | | | | | | | | | | | | | | | | | | | | +const int8_t xMapK[24];// = { -1 , -1 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , -1 , -1 , -1 , 0 , 1 , 2 , 3 , -1 , -1 , -1 , -1 };//holds which X pin is connected to the index on Chip K, -1 for none + int8_t xStatusK[24];// = { -1 , -1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , -1 , -1 , -1 , -1 };//-1 for not connected to that chip, 0 for available, >0 means it's connected and the netNumber is stored here +// | | | | | | | | | | | | | | | | | | | | | | | | | +const int8_t xMapL[24];// = { -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , 12 , 13 , -1 , -1 };//holds which X pin is connected to the index on Chip L, -1 for none + int8_t xStatusL[24];// = { -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , 0 , 0 , -1 , -1 };//-1 for not connected to that chip, 0 for available, >0 means it's connected and the netNumber is stored here // mapIJKL[] will tell you whethher there's a connection from that nano pin to the corresponding special function chip // xMapIJKL[] will tell you the X pin that it's connected to on that sf chip // xStatusIJKL[] says whether that x pin is being used (this should be the same as mt[8-10].xMap[] if theyre all stacked on top of each other) // I haven't decided whether to make this just a flag, or store that signal's destination -const int8_t reversePinMap[110] = {NANO_D0, NANO_D1, NANO_D2, NANO_D3, NANO_D4, NANO_D5, NANO_D6, NANO_D7, NANO_D8, NANO_D9, NANO_D10, NANO_D11, NANO_D12, NANO_D13, NANO_RESET, NANO_AREF, NANO_A0, NANO_A1, NANO_A2, NANO_A3, NANO_A4, NANO_A5, NANO_A6, NANO_A7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,GND,101,102,SUPPLY_3V3,104,SUPPLY_5V,DAC0_5V,DAC1_8V,CURRENT_SENSE_PLUS,CURRENT_SENSE_MINUS}; +const int8_t reversePinMap[110];// = {NANO_D0, NANO_D1, NANO_D2, NANO_D3, NANO_D4, NANO_D5, NANO_D6, NANO_D7, NANO_D8, NANO_D9, NANO_D10, NANO_D11, NANO_D12, NANO_D13, NANO_RESET, NANO_AREF, NANO_A0, NANO_A1, NANO_A2, NANO_A3, NANO_A4, NANO_A5, NANO_A6, NANO_A7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,GND,101,102,SUPPLY_3V3,104,SUPPLY_5V,DAC0_5V,DAC1_8V,CURRENT_SENSE_PLUS,CURRENT_SENSE_MINUS}; }; - - - +extern struct nanoStatus nano; //see the comments at the end for a more nicely formatted version that's not in struct initalizers - struct xy8_t { - uint8_t x : 4; - uint8_t y : 4; -}; - - struct pathStruct{ - int8_t node1 = 0; //these are the rows or nano header pins to connect - int8_t node2 = 0; - int pathNumber = 0; // this is just a number to refer to the path by + int node1; //these are the rows or nano header pins to connect + int node2; + int net; - uint8_t firstChip = 0xff; - uint8_t firstXY = 0b11101111; - //int8_t firstY = -1; - - uint8_t secondChip = 0xff; - - uint8_t secondXY = 0b00000000; - //int8_t secondY = -1; - - - int redundantConnection = 0; // if the paths are redundant (for lower resistance) this is the pathNumber of the other one(s) + int chip[3]; + int x[3]; + int y[3]; + int candidates[3][3]; }; -const char* definesToChar (int defined); +extern struct pathStruct path[MAX_BRIDGES]; //this is the array of paths + /* uint8_t connectionsMatrix[85][85]; diff --git a/JumperlessNano/src/NetManager.cpp b/JumperlessNano/src/NetManager.cpp index 3e8fd0b..b5989c9 100644 --- a/JumperlessNano/src/NetManager.cpp +++ b/JumperlessNano/src/NetManager.cpp @@ -2,202 +2,78 @@ #include "NetManager.h" #include -#include "LittleFS.h" #include "MatrixStateRP2040.h" +#include "SafeString.h" int8_t newNode1 = -1; int8_t newNode2 = -1; -int newBridge[MAX_BRIDGES][3]; // node1, node2, net -int newBridgeLength; - -int newBridgeIndex = 0; int foundNode1Net = 0; // netNumbers where that node is, a node can only be in 1 net (except current sense, we'll deal with that separately) int foundNode2Net = 0; // netNumbers where that node is, a node can only be in 1 net (except current sense, we'll deal with that separately) -// StaticJsonDocument <800> bridgeList; - -String nodeFileString; -String bridgeString; -String specialFunctionsString; - -File nodeFile; - -void openNodeFile() -{ - - nodeFile = LittleFS.open("nodeFile.txt", "r"); - if (!nodeFile) - { - Serial.println("Failed to open nodeFile"); - return; - } - else - { - Serial.println("\n\ropened nodeFile.txt\n\n\rloading bridges from file\n\r"); - } - - nodeFileString = nodeFile.readString(); - - nodeFile.close(); - splitStringToFields(); - // parseStringToBridges(); -} - -void splitStringToFields() -{ - int openBraceIndex = 0; - int closeBraceIndex = 0; - - Serial.println("\n\rraw input file\n\r"); - Serial.println(nodeFileString); - Serial.println("\n\rsplitting and cleaning up string\n\r"); - Serial.println("_"); - openBraceIndex = nodeFileString.indexOf("{"); - closeBraceIndex = nodeFileString.indexOf("}"); - bridgeString = nodeFileString.substring(openBraceIndex + 1, closeBraceIndex); - bridgeString.trim(); - - Serial.println(bridgeString); - - Serial.println("^\n\r"); - - nodeFileString.remove(0, closeBraceIndex + 1); - nodeFileString.trim(); - - openBraceIndex = nodeFileString.indexOf("{"); - closeBraceIndex = nodeFileString.indexOf("}"); - specialFunctionsString = nodeFileString.substring(openBraceIndex + 1, closeBraceIndex); - specialFunctionsString.trim(); - Serial.println("_"); - Serial.println(specialFunctionsString); - Serial.println("^\n\r"); - replaceSFNamesWithDefinedInts(); -} - -void replaceSFNamesWithDefinedInts(void) -{ - Serial.println("replacing special function names with defined ints\n\r"); - specialFunctionsString.replace("GND", "100"); - specialFunctionsString.replace("SUPPLY_5V", "105"); - specialFunctionsString.replace("SUPPLY_3V3", "103"); - specialFunctionsString.replace("DAC0_5V", "106"); - specialFunctionsString.replace("DAC1_8V", "107"); - specialFunctionsString.replace("I_N", "109"); - specialFunctionsString.replace("I_P", "108"); - - specialFunctionsString.replace("EMPTY_NET", "127"); - - Serial.println(specialFunctionsString); - Serial.println("\n\n\r"); - parseStringToBridges(); -} - -void parseStringToBridges(void) -{ - - int bridgeStringLength = bridgeString.length() - 1; - - int specialFunctionsStringLength = specialFunctionsString.length() - 1; - - int readLength = 0; - int readTotal = specialFunctionsStringLength; - - newBridgeLength = 0; - newBridgeIndex = 0; - - Serial.println("parsing bridges into array\n\r"); - - for (int i = 0; i <= specialFunctionsStringLength; i += readLength) - { - - sscanf(specialFunctionsString.c_str(), "%i-%i,\n\r%n", &newBridge[newBridgeIndex][0], &newBridge[newBridgeIndex][1], &readLength); - specialFunctionsString.remove(0, readLength); - - readTotal -= readLength; - - // Serial.print(newBridge[newBridgeIndex][0]); - // Serial.print("-"); - // Serial.println(newBridge[newBridgeIndex][1]); - - newBridgeLength++; - newBridgeIndex++; - - // delay(500); - } - - readTotal = bridgeStringLength; - - for (int i = 0; i <= bridgeStringLength; i += readLength) - { - - sscanf(bridgeString.c_str(), "%i-%i,\n\r%n", &newBridge[newBridgeIndex][0], &newBridge[newBridgeIndex][1], &readLength); - bridgeString.remove(0, readLength); - - readTotal -= readLength; - - // Serial.print(newBridge[newBridgeIndex][0]); - // Serial.print("-"); - // Serial.println(newBridge[newBridgeIndex][1]); - - newBridgeLength++; - newBridgeIndex++; - - // delay(500); - } - for (int i = 0; i < newBridgeLength; i++) - { - Serial.print("["); - Serial.print(newBridge[i][0]); - Serial.print("-"); - Serial.print(newBridge[i][1]); - Serial.print("],"); - } - Serial.print("\n\rbridge pairs = "); - Serial.println(newBridgeLength); - // Serial.println(nodeFileString); -} + //struct pathStruct path[MAX_BRIDGES]; // node1, node2, net, chip[3], x[3], y[3] + int newBridge[MAX_BRIDGES][3]; // node1, node2, net +int newBridgeLength = 0; +int newBridgeIndex = 0; +unsigned long timeToNM; +static bool debugNM; +static bool debugNMtime; void getNodesToConnect() // read in the nodes you'd like to connect { + timeToNM = millis(); + if (DEBUG_NETMANAGER == 1) + debugNM = true; + else + debugNM = false; + if (TIME_NETMANAGER == 1) + debugNMtime = true; + else + debugNMtime = false; - Serial.println("\n\n\rconnecting nodes into nets\n\r"); + if (debugNM) + Serial.println("\n\n\rconnecting nodes into nets\n\r"); + newBridgeIndex = 0; for (int i = 0; i < newBridgeLength; i++) { - newNode1 = newBridge[i][0]; + newNode1 = path[i].node1; - newNode2 = newBridge[i][1]; + newNode2 = path[i].node2; - newBridgeIndex++; - - printNodeOrName(newNode1); - Serial.print("-"); - printNodeOrName(newNode2); - Serial.print("\n\r"); + if (debugNM) + printNodeOrName(newNode1); + if (debugNM) + Serial.print("-"); + if (debugNM) + printNodeOrName(newNode2); + if (debugNM) + Serial.print("\n\r"); // do some error checking if (newNode1 == 0 || newNode2 == 0) { - // listNets(); - // return ; + path[i].net = -1; } else { searchExistingNets(newNode1, newNode2); } + //printBridgeArray(); - // if (i < 7) - // { + newBridgeIndex++; // don't increment this until after the search because we're gonna use it as an index to store the nets + // if (i < 7) + // { + if (debugNM) listSpecialNets(); - // } + // } + if (debugNM) listNets(); - - } - Serial.println("done"); + if (debugNM) + Serial.println("done"); } int searchExistingNets(int node1, int node2) // search through existing nets for all nodes that match either one of the new nodes (so it will be added to that net) @@ -227,10 +103,14 @@ int searchExistingNets(int node1, int node2) // search through existing nets for { if (i > 7) { - Serial.print("found Node "); - printNodeOrName(node1); - Serial.print(" in Net "); - Serial.println(i); + if (debugNM) + Serial.print("found Node "); + if (debugNM) + printNodeOrName(node1); + if (debugNM) + Serial.print(" in Net "); + if (debugNM) + Serial.println(i); } if (net[i].specialFunction > 0) @@ -247,10 +127,14 @@ int searchExistingNets(int node1, int node2) // search through existing nets for { if (i > 7) { - Serial.print("found Node "); - printNodeOrName(node2); - Serial.print(" in Net "); - Serial.println(i); + if (debugNM) + Serial.print("found Node "); + if (debugNM) + printNodeOrName(node2); + if (debugNM) + Serial.print(" in Net "); + if (debugNM) + Serial.println(i); } if (net[i].specialFunction > 0) @@ -266,38 +150,111 @@ int searchExistingNets(int node1, int node2) // search through existing nets for } } - if (foundNode1Net == foundNode2Net && foundNode1Net > 0) // if both nodes are in the same net, do nothing + if (foundNode1Net == foundNode2Net && foundNode1Net > 0) // if both nodes are in the same net, still add the bridge { addNodeToNet(foundNode1Net, node1); // note that they both connect to node1's net addNodeToNet(foundNode1Net, node2); addBridgeToNet(foundNode1Net, node1, node2); + path[newBridgeIndex].net = foundNode1Net; return 1; } else if ((foundNode1Net > 0 && foundNode2Net > 0) && (foundNode1Net != foundNode2Net)) // if both nodes are in different nets, combine them { - if (checkDoNotIntersectsByNet(foundNode1Net, foundNode2Net) == 1 ) + combineNets(foundNode1Net, foundNode2Net); + return 2; + } + else if (foundNode1Net > 0 && node2 > 0) // if node1 is in a net and node2 is not, add node2 to node1's net + { + if (checkDoNotIntersectsByNode(foundNode1Net, node2) == 1) { - int swap = 0; - if ( (foundNode2Net <= 7 && foundNode1Net <= 7)) + if (debugNM) + Serial.print("adding Node "); + if (debugNM) + printNodeOrName(node2); + if (debugNM) + Serial.print(" to Net "); + if (debugNM) + Serial.println(foundNode1Net); + + addNodeToNet(foundNode1Net, node2); + addBridgeToNet(foundNode1Net, node1, node2); + path[newBridgeIndex].net = foundNode1Net; + } + else + { + createNewNet(); + } + + return 3; + } + else if (foundNode2Net > 0 && node1 > 0) // if node2 is in a net and node1 is not, add node1 to node2's net + { + if (checkDoNotIntersectsByNode(foundNode2Net, node1) == 1) + { + if (debugNM) + Serial.print("adding Node "); + if (debugNM) + printNodeOrName(node1); + if (debugNM) + Serial.print(" to Net "); + if (debugNM) + Serial.println(foundNode2Net); + + addNodeToNet(foundNode2Net, node1); + addBridgeToNet(foundNode2Net, node1, node2); + path[newBridgeIndex].net = foundNode2Net; + } + else + { + createNewNet(); + } + return 4; + } + + else + { + + createNewNet(); // if neither node is in a net, create a new one + + return 0; + } +} + +void combineNets(int foundNode1Net, int foundNode2Net) +{ + + if (checkDoNotIntersectsByNet(foundNode1Net, foundNode2Net) == 1) + { + int swap = 0; + if ((foundNode2Net <= 7 && foundNode1Net <= 7)) + { + if (debugNM) + Serial.print("can't combine Special Nets, skipping\n\r"); // maybe have it add a bridge between them if it's allowed? + path[newBridgeIndex].net = -1; + } + else + { + + if (foundNode2Net <= 7) { - Serial.print("can't combine Special Nets, skipping\n\r"); //maybe have it add a bridge between them if it's allowed? - } else { + swap = foundNode1Net; + foundNode1Net = foundNode2Net; + foundNode2Net = swap; + } + addNodeToNet(foundNode1Net, newNode1); + addNodeToNet(foundNode1Net, newNode2); + addBridgeToNet(foundNode1Net, newNode1, newNode2); + path[newBridgeIndex].net = foundNode1Net; + if (debugNM) + Serial.print("combining Nets "); + if (debugNM) + Serial.print(foundNode1Net); + if (debugNM) + Serial.print(" and "); + if (debugNM) + Serial.println(foundNode2Net); - if (foundNode2Net <= 7) - { - swap = foundNode1Net; - foundNode1Net = foundNode2Net; - foundNode2Net = swap; - } - - Serial.print("combining Nets "); - Serial.print(foundNode1Net); - Serial.print(" and "); - Serial.println(foundNode2Net); - // Serial.println("before"); - // listNets(); - // Serial.println("after"); for (int i = 0; i < MAX_NODES; i++) { if (net[foundNode2Net].nodes[i] == 0) @@ -326,76 +283,35 @@ int searchExistingNets(int node1, int node2) // search through existing nets for addNodeToNet(foundNode1Net, net[foundNode2Net].doNotIntersectNodes[i]); } + for (int i = 0; i < newBridgeIndex; i++) // update the newBridge array to reflect the new net number + { + if (path[i].net == foundNode2Net) + { + if (debugNM) + Serial.print("updating path["); + if (debugNM) + Serial.print(i); + if (debugNM) + Serial.print("].net from "); + if (debugNM) + Serial.print(path[i].net); + if (debugNM) + Serial.print(" to "); + if (debugNM) + Serial.println(foundNode1Net); + + path[i].net = foundNode1Net; + } + } + if (debugNM) + printBridgeArray(); deleteNet(foundNode2Net); - } } - else - { - //createNewNet(); - } - - - return 2; - } - else if (foundNode1Net > 0 && node2 > 0) // if node1 is in a net and node2 is not, add node2 to node1's net - { - if (checkDoNotIntersectsByNode(foundNode1Net, node2) == 1) - { - Serial.print("adding Node "); - printNodeOrName(node2); - Serial.print(" to Net "); - Serial.println(foundNode1Net); - - addNodeToNet(foundNode1Net, node2); - addBridgeToNet(foundNode1Net, node1, node2); - } - else - { - createNewNet(); - } - - return 3; - } - else if (foundNode2Net > 0 && node1 > 0) // if node2 is in a net and node1 is not, add node1 to node2's net - { - if (checkDoNotIntersectsByNode(foundNode2Net, node1) == 1) - { - Serial.print("adding Node "); - printNodeOrName(node1); - Serial.print(" to Net "); - Serial.println(foundNode2Net); - - addNodeToNet(foundNode2Net, node1); - addBridgeToNet(foundNode2Net, node1, node2); - } - else - { - createNewNet(); - } - return 4; - } - - else - { - - createNewNet(); // if neither node is in a net, create a new one - - return 0; } } -int printNodeOrName(int node) // returns number of characters printed (for tabs) -{ - if (node >= 100) - { - return Serial.print(definesToChar(node)); - } - else - { - return Serial.print(node); - } -} + void deleteNet(int netNumber) // make sure to check special function nets and clear connections to it { @@ -411,13 +327,15 @@ int shiftNets(int deletedNet) // why in the ever-loving fuck does this work? the if (net[i].number != 0) { lastNet = i; - // Serial.print("last net = "); - // Serial.println(lastNet); + // if(debugNM) Serial.print("last net = "); + // if(debugNM) Serial.println(lastNet); break; } } - Serial.print("deleted Net "); - Serial.println(deletedNet); + if (debugNM) + Serial.print("deleted Net "); + if (debugNM) + Serial.println(deletedNet); for (int i = deletedNet; i < lastNet; i++) { @@ -459,103 +377,308 @@ int shiftNets(int deletedNet) // why in the ever-loving fuck does this work? the return lastNet; } -void checkCurrentSense(void) +void createNewNet() // add those nodes to a new net { - return; // I might deal with current sense in a different way because this is dumb + int newNetNumber = findFirstUnusedNetIndex(); + net[newNetNumber].number = newNetNumber; + + net[newNetNumber].name = netNameConstants[newNetNumber]; // dont need a function for this anymore + + net[newNetNumber].specialFunction = -1; + + addNodeToNet(newNetNumber, newNode1); + + addNodeToNet(newNetNumber, newNode2); + + addBridgeToNet(newNetNumber, newNode1, newNode2); + + path[newBridgeIndex].net = newNetNumber; } -void listNets(void) +void addBridgeToNet(uint8_t netToAddBridge, int8_t node1, int8_t node2) // just add those nodes to the net { - if (net[8].number == 0) - { - //Serial.print("No nets to list\n\r"); - //return; - } else { - Serial.print("\n\rIndex\tName\t\tNumber\t\tNodes\t\t\tBridges\t\t\t\tDo Not Intersects"); + int newBridgeIndex = findFirstUnusedBridgeIndex(netToAddBridge); + net[netToAddBridge].bridges[newBridgeIndex][0] = node1; + net[netToAddBridge].bridges[newBridgeIndex][1] = node2; +} - int tabs = 0; - for (int i = 8; i < MAX_NETS; i++) +void addNodeToNet(int netToAddNode, int node) +{ + int newNodeIndex = findFirstUnusedNodeIndex(netToAddNode); // using a function lets us add more error checking later and maybe shift the nodes down so they're left justified + for (int i = 0; i < MAX_NODES; i++) { - if (net[i].number == 0) // stops searching if it gets to an unallocated net + if (net[netToAddNode].nodes[i] == 0) { - // Serial.print("Done listing nets"); break; } - Serial.print("\n\r"); - Serial.print(i); - Serial.print("\t"); - Serial.print(net[i].name); - Serial.print("\t\t"); - Serial.print(net[i].number); - Serial.print("\t\t"); - - tabs = 0; - for (int j = 0; j < MAX_NODES; j++) + if (net[netToAddNode].nodes[i] == node) { + if (debugNM) + Serial.print("Node "); + if (debugNM) + printNodeOrName(node); + if (debugNM) + Serial.print(" is already in Net "); + if (debugNM) + Serial.print(netToAddNode); + if (debugNM) + Serial.print(", skipping\n\r"); + return; + } + } + + net[netToAddNode].nodes[newNodeIndex] = node; +} - tabs += printNodeOrName(net[i].nodes[j]); +int findFirstUnusedNetIndex() // search for a free net[] +{ + for (int i = 0; i < MAX_NETS; i++) + { + if (net[i].nodes[0] == 0) + { + if (debugNM) + Serial.print("found unused Net "); + if (debugNM) + Serial.println(i); - if (net[i].nodes[j + 1] == 0) + return i; + break; + } + } + return 0x7f; +} + +int findFirstUnusedBridgeIndex(int netNumber) +{ + for (int i = 0; i < MAX_BRIDGES; i++) + { + if (net[netNumber].bridges[i][0] == 0) + { + // if(debugNM) Serial.print("found unused bridge "); + // if(debugNM) Serial.println(i); + + return i; + break; + } + } + return 0x7f; +} + +int findFirstUnusedNodeIndex(int netNumber) // search for a free net[] +{ + for (int i = 0; i < MAX_NODES; i++) + { + if (net[netNumber].nodes[i] == 0) + { + // if(debugNM) Serial.printf("found unused node index net[%d]. node[%d]\n\r", netNumber, i); + // if(debugNM) Serial.println(i); + + return i; + break; + } + } + return 0x7f; +} + +int checkDoNotIntersectsByNet(int netToCheck1, int netToCheck2) // If you're searching DNIs by net, there won't be any valid ways to make a new net with both nodes, so its skipped +{ + + + for (int i = 0; i <= MAX_DNI; i++) + { + if (net[netToCheck1].doNotIntersectNodes[i] == 0) + { + break; + } + + for (int j = 0; j <= MAX_NODES; j++) + { // if(debugNM) Serial.print (net[netToCheck1].doNotIntersectNodes[i]); + // if(debugNM) Serial.print ("-"); + // if(debugNM) Serial.println (net[netToCheck2].nodes[j]); + + if (net[netToCheck2].nodes[j] == 0) { break; } - else - { - tabs += Serial.print(","); + if (net[netToCheck1].doNotIntersectNodes[i] == net[netToCheck2].nodes[j]) + { + if (debugNM) + Serial.print("Net "); + if (debugNM) + printNodeOrName(netToCheck2); + if (debugNM) + Serial.print(" can't be combined with Net "); + if (debugNM) + Serial.print(netToCheck1); + if (debugNM) + Serial.print(" due to Do Not Intersect rules, skipping\n\r"); + path[newBridgeIndex].net = -1; + return 0; + } } + // if(debugNM) Serial.println (" "); + } - for (int i = 0; i < 3 - (tabs / 8); i++) + for (int i = 0; i <= MAX_DNI; i++) + { + if (net[netToCheck2].doNotIntersectNodes[i] == 0) { - Serial.print("\t"); + break; } - Serial.print("{"); - - tabs = 0; - for (int j = 0; j < MAX_BRIDGES; j++) + for (int j = 0; j <= MAX_NODES; j++) { - - tabs += printNodeOrName(net[i].bridges[j][0]); - tabs += Serial.print("-"); - tabs += printNodeOrName(net[i].bridges[j][1]); - // Serial.print(","); - - if (net[i].bridges[j + 1][0] == 0) + if (net[netToCheck1].nodes[j] == 0) { break; } - else + + if (net[netToCheck2].doNotIntersectNodes[i] == net[netToCheck1].nodes[j]) { - - tabs += Serial.print(","); - } - } - tabs += Serial.print("}\t"); - - for (int i = 0; i < 3 - (tabs / 8); i++) - { - Serial.print("\t"); - } - - for (int j = 0; j < MAX_DNI; j++) - { - - tabs += printNodeOrName(net[i].doNotIntersectNodes[j]); - - if (net[i].doNotIntersectNodes[j + 1] == 0) - { - break; - } - else - { - - tabs += Serial.print(","); + if (debugNM) + Serial.print("Net "); + printNodeOrName(netToCheck2); + if (debugNM) + Serial.print(" can't be combined with Net "); + if (debugNM) + Serial.print(netToCheck1); + if (debugNM) + Serial.print(" due to Do Not Intersect rules, skipping\n\r"); + path[newBridgeIndex].net = -1; + return 0; } } } + + return 1; // return 1 if it's ok to connect these nets +} + +int checkDoNotIntersectsByNode(int netToCheck, int nodeToCheck) // make sure none of the nodes on the net violate doNotIntersect rules, exit and warn +{ + + for (int i = 0; i < MAX_DNI; i++) + { + if (net[netToCheck].doNotIntersectNodes[i] == 0) + { + break; + } + + if (net[netToCheck].doNotIntersectNodes[i] == nodeToCheck) + { + if (debugNM) + Serial.print("Node "); + if (debugNM) + printNodeOrName(nodeToCheck); + if (debugNM) + Serial.print(" is not allowed on Net "); + if (debugNM) + Serial.print(netToCheck); + if (debugNM) + Serial.print(" due to Do Not Intersect rules, a new net will be created\n\r"); + return 0; + } + } + + return 1; // return 1 if it's ok to connect these nets +} + +void listNets(void) // list nets doesnt care about debugNM, don't call it if you don't want it to print +{ + if (net[8].number == 0) + { + // if(debugNM) Serial.print("No nets to list\n\r"); + // return; + } + else + { + Serial.print("\n\rIndex\tName\t\tNumber\t\tNodes\t\t\tBridges\t\t\t\tDo Not Intersects"); + + int tabs = 0; + for (int i = 8; i < MAX_NETS; i++) + { + if (net[i].number == 0) // stops searching if it gets to an unallocated net + { + // Serial.print("Done listing nets"); + break; + } + + Serial.print("\n\r"); + Serial.print(i); + Serial.print("\t"); + Serial.print(net[i].name); + Serial.print("\t\t"); + Serial.print(net[i].number); + Serial.print("\t\t"); + + tabs = 0; + for (int j = 0; j < MAX_NODES; j++) + { + + tabs += printNodeOrName(net[i].nodes[j]); + + if (net[i].nodes[j + 1] == 0) + { + break; + } + else + { + + tabs += Serial.print(","); + } + } + + for (int i = 0; i < 3 - (tabs / 8); i++) + { + Serial.print("\t"); + } + + Serial.print("{"); + + tabs = 0; + for (int j = 0; j < MAX_BRIDGES; j++) + { + + tabs += printNodeOrName(net[i].bridges[j][0]); + tabs += Serial.print("-"); + tabs += printNodeOrName(net[i].bridges[j][1]); + // Serial.print(","); + + if (net[i].bridges[j + 1][0] == 0) + { + break; + } + else + { + + tabs += Serial.print(","); + } + } + tabs += Serial.print("}\t"); + + for (int i = 0; i < 3 - (tabs / 8); i++) + { + Serial.print("\t"); + } + + for (int j = 0; j < MAX_DNI; j++) + { + + tabs += printNodeOrName(net[i].doNotIntersectNodes[j]); + + if (net[i].doNotIntersectNodes[j + 1] == 0) + { + break; + } + else + { + + tabs += Serial.print(","); + } + } + } } Serial.print("\n\n\n\r"); } @@ -649,169 +772,98 @@ void listSpecialNets() Serial.print("\n\r"); } -void createNewNet() // add those nodes to a new net +void printBridgeArray(void) { - int newNetNumber = findFirstUnusedNetIndex(); - net[newNetNumber].number = newNetNumber; - - net[newNetNumber].name = netNameConstants[newNetNumber]; // dont need a function for this anymore - - net[newNetNumber].specialFunction = -1; - - addNodeToNet(newNetNumber, newNode1); - - addNodeToNet(newNetNumber, newNode2); - - addBridgeToNet(newNetNumber, newNode1, newNode2); -} - -void addBridgeToNet(uint8_t netToAddBridge, int8_t node1, int8_t node2) // just add those nodes to the net -{ - int newBridgeIndex = findFirstUnusedBridgeIndex(netToAddBridge); - net[netToAddBridge].bridges[newBridgeIndex][0] = node1; - net[netToAddBridge].bridges[newBridgeIndex][1] = node2; -} - -void addNodeToNet(int netToAddNode, int node) -{ - int newNodeIndex = findFirstUnusedNodeIndex(netToAddNode); // using a function lets us add more error checking later and maybe shift the nodes down so they're left justified - net[netToAddNode].nodes[newNodeIndex] = node; -} - -int findFirstUnusedNetIndex() // search for a free net[] -{ - for (int i = 0; i < MAX_NETS; i++) +//Serial.print("\n\n\r"); + //Serial.print("newBridgeIndex = "); + //Serial.println(newBridgeIndex); + Serial.print("\n\r"); + int tabs = 0; + int lineCount = 0; + for (int i = 0; i < newBridgeLength; i++) { - if (net[i].nodes[0] == 0) + tabs += Serial.print(i); + if (i < 10) { - Serial.print("found unused Net "); - Serial.println(i); - - return i; - break; + tabs += Serial.print(" "); } + if (i < 100) + { + tabs += Serial.print(" "); + } + tabs += Serial.print("["); + tabs += printNodeOrName(path[i].node1); + tabs += Serial.print(","); + tabs += printNodeOrName(path[i].node2); + tabs += Serial.print(",Net "); + tabs += printNodeOrName(path[i].net); + tabs += Serial.print("],"); + lineCount++; + //Serial.print(tabs); + for (int i = 0; i < 24 - (tabs); i++) + { + Serial.print(" "); + } + tabs = 0; + + if (lineCount == 5) + { + Serial.print("\n\r"); + lineCount = 0; + } + } - return 0x7f; + if(debugNMtime) Serial.println("\n\r"); + if(debugNMtime) timeToNM = millis() - timeToNM; + if(debugNMtime) Serial.print("\n\rtook "); + if(debugNMtime) Serial.print(timeToNM); + if(debugNMtime) Serial.print("ms to run net manager\n\r"); } -int findFirstUnusedBridgeIndex(int netNumber) +int printNodeOrName(int node) // returns number of characters printed (for tabs) { - for (int i = 0; i < MAX_BRIDGES; i++) - { - if (net[netNumber].bridges[i][0] == 0) - { - // Serial.print("found unused bridge "); - // Serial.println(i); - return i; - break; - } + if (node >= 100) + { + return Serial.print(definesToChar(node)); + } + else if (node >= NANO_D0) + { + return Serial.print(definesToChar(node)); + } + else + { + return Serial.print(node); } - return 0x7f; } - -int findFirstUnusedNodeIndex(int netNumber) // search for a free net[] -{ - for (int i = 0; i < MAX_NODES; i++) - { - if (net[netNumber].nodes[i] == 0) - { - // Serial.printf("found unused node index net[%d]. node[%d]\n\r", netNumber, i); - // Serial.println(i); - - return i; - break; - } - } - return 0x7f; -} - -int checkDoNotIntersectsByNet(int netToCheck1, int netToCheck2) //If you're searching DNIs by net, there won't be any valid ways to make a new net with both nodes, so its skipped -{ - int problem = 0; - - for (int i = 0; i <= MAX_DNI; i++) - { - if (net[netToCheck1].doNotIntersectNodes[i] == 0) - { - break; - } - - for (int j = 0; j <= MAX_NODES; j++) - { //Serial.print (net[netToCheck1].doNotIntersectNodes[i]); - //Serial.print ("-"); - // Serial.println (net[netToCheck2].nodes[j]); - - if (net[netToCheck2].nodes[j] == 0) - { - break; - } - - if (net[netToCheck1].doNotIntersectNodes[i] == net[netToCheck2].nodes[j]) - { - Serial.print("Net "); - printNodeOrName(netToCheck2); - Serial.print(" can't be combined with Net "); - Serial.print(netToCheck1); - Serial.print(" due to Do Not Intersect rules, skipping (first net DNI to second net nodes)\n\r"); - return 0; - problem ++; - } - } - //Serial.println (" "); - } - - for (int i = 0; i <= MAX_DNI; i++) - { - if (net[netToCheck2].doNotIntersectNodes[i] == 0) - { - break; - } - - for (int j = 0; j <= MAX_NODES; j++) - { - if (net[netToCheck1].nodes[j] == 0) - { - break; - } - - if (net[netToCheck2].doNotIntersectNodes[i] == net[netToCheck1].nodes[j]) - { - Serial.print("Net "); - printNodeOrName(netToCheck2); - Serial.print(" can't be combined with Net "); - Serial.print(netToCheck1); - Serial.print(" due to Do Not Intersect rules, skipping(second net DNI to first net nodes)\n\r"); - return 0; - } - } - } - - return 1; // return 1 if it's ok to connect these nets -} - -int checkDoNotIntersectsByNode(int netToCheck, int nodeToCheck) // make sure none of the nodes on the net violate doNotIntersect rules, exit and warn + char same[12] = " "; +const char *definesToChar(int defined) // converts the internally used #defined numbers into human readable strings { - for (int i = 0; i < MAX_DNI; i++) + const char *defNanoToChar[26] = {"D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "D10", "D11", "D12", "D13", "RESET", "AREF", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7"}; + + const char *defSpecialToChar[12] = {"GND", "NOT_DEFINED", "NOT_DEFINED", "3V3", "NOT_DEFINED", "5V", "DAC_0", "DAC_1", "I_POS", "I_NEG"}; + + const char *emptyNet[] = {"EMPTY_NET", "?"}; + + if (defined >= 70 && defined <= 93) { - if (net[netToCheck].doNotIntersectNodes[i] == 0) - { - break; - } - - if (net[netToCheck].doNotIntersectNodes[i] == nodeToCheck) - { - Serial.print("Node "); - printNodeOrName(nodeToCheck); - Serial.print(" is not allowed on Net "); - Serial.print(netToCheck); - Serial.print(" due to Do Not Intersect rules, a new net will be created\n\r"); - return 0; - } + return defNanoToChar[defined - 70]; + } + else if (defined >= 100 && defined <= 110) + { + return defSpecialToChar[defined - 100]; + } + else if (defined == EMPTY_NET) + { + return emptyNet[0]; + } + else + { + + itoa(defined, same, 10); + return same; } - - return 1; // return 1 if it's ok to connect these nets } /* diff --git a/JumperlessNano/src/NetManager.h b/JumperlessNano/src/NetManager.h index ca801e7..9bd4fc0 100644 --- a/JumperlessNano/src/NetManager.h +++ b/JumperlessNano/src/NetManager.h @@ -6,15 +6,14 @@ #include "JumperlessDefinesRP2040.h" //#include "MatrixStateRP2040.h" +extern int newBridge[MAX_BRIDGES][3]; // node1, node2, net +extern int newBridgeLength; +extern int newBridgeIndex; + void writeJSONtoFile(); -void openNodeFile(); - -void splitStringToFields(); -void replaceSFNamesWithDefinedInts(); -void parseStringToBridges(); int printNodeOrName(int node); void getNodesToConnect(); //read in the nodes you'd like to connect @@ -39,7 +38,7 @@ int checkDoNotIntersectsByNet(int,int); //make sure none of the nodes on the net int checkDoNotIntersectsByNode(int,int); //make sure none of the nodes on the net violate doNotIntersect rules, exit and warn -void combineNets(); //combine those 2 nets into a single net, probably call addNodesToNet and deleteNet and just expand the lower numbered one. Should we shift nets down? or just reuse the newly emply space for the next net +void combineNets(int,int); //combine those 2 nets into a single net, probably call addNodesToNet and deleteNet and just expand the lower numbered one. Should we shift nets down? or just reuse the newly emply space for the next net void deleteNet(int); //make sure to check special function nets and clear connections to it @@ -49,6 +48,12 @@ void deleteBridge(); void deleteNode(); //disconnects everything connected to that one node +const char* definesToChar (int defined); + +void printBridgeArray(); + + + void checkIfNodesAreABridge(); //if both of those nodes make up a memberBridge[][] pair. if not, warn and exit void deleteBridgeAndShift(); //shift the remaining bridges over so they're left justified and we don't need to search the entire memberBridges[] every time diff --git a/JumperlessNano/src/NetsToChipConnections.cpp b/JumperlessNano/src/NetsToChipConnections.cpp new file mode 100644 index 0000000..f6fc38a --- /dev/null +++ b/JumperlessNano/src/NetsToChipConnections.cpp @@ -0,0 +1,793 @@ + + +#include +#include "JumperlessDefinesRP2040.h" +#include "MatrixStateRP2040.h" +#include "NetManager.h" +#include "NetsToChipConnections.h" + +//don't try to understand this, it's still a mess + +int startEndChip[2] = {-1, -1}; +int bothNodes[2] = {-1, -1}; +int endChip; +int chipCandidates[2][4] = {{-1, -1, -1, -1}, {-1, -1, -1, -1}}; // nano and sf nodes have multiple possible chips they could be connected to, so we need to store them all and check them all + +int chipsLeastToMostCrowded[12] = {0,1,2,3,4,5,6,7,8,9,10,11}; //this will be sorted from most to least crowded, and will be used to determine which chip to use for each node +int sfChipsLeastToMostCrowded[4] = {8,9,10,11}; //this will be sorted from most to least crowded, and will be used to determine which chip to use for each node +int bbToSfLanes[8][4] = {{0}}; // [Chip A - H][CHIP I-K] 0 = free 1 = used + +int numberOfUniqueNets = 0; +int numberOfNets = 0; +int numberOfPaths = 0; +unsigned long timeToSort = 0; + +bool debugNTCC = false; + +void sortPathsByNet(void) // not actually sorting, just copying the bridges and nets back from netStruct so they're both in the same order +{ + timeToSort = micros(); + printBridgeArray(); + + for (int i = 0; i < MAX_BRIDGES; i++) + { + if (net[i].number == 0) + { + numberOfNets = i; + break; + } + } + + for (int i = 0; i < MAX_BRIDGES; i++) + { + if (path[i].node1 == 0 && path[i].node2 == 0) + { + numberOfPaths = i; + break; + } + } + // printPathArray(); + + Serial.print("number of nets: "); + Serial.println(numberOfNets); + int pathIndex = 0; + + for (int j = 1; j <= numberOfPaths; j++) + { + + for (int k = 0; k < MAX_BRIDGES; k++) + { + if (net[j].bridges[k][0] == 0) + { + + break; + } + else + { + path[pathIndex].net = net[j].number; + path[pathIndex].node1 = net[j].bridges[k][0]; + path[pathIndex].node2 = net[j].bridges[k][1]; + + if (path[pathIndex].net == path[pathIndex - 1].net) + { + } + else + { + numberOfUniqueNets++; + } + + // Serial.print("path["); + // Serial.print(pathIndex); + // Serial.print("] net: "); + // Serial.println(path[pathIndex].net); + pathIndex++; + } + } + } + + newBridgeLength = pathIndex; + numberOfPaths = pathIndex; + + Serial.print("number unique of nets: "); + Serial.println(numberOfUniqueNets); + Serial.print("pathIndex: "); + Serial.println(pathIndex); + Serial.print("numberOfPaths: "); + Serial.println(numberOfPaths); + + clearChipsOnPathToNegOne(); // clear chips and all trailing paths to -1{if there are bridges that weren't made due to DNI rules, there will be fewer paths now because they were skipped} + printBridgeArray(); + Serial.println("\n\r"); + timeToSort = micros() - timeToSort; + Serial.print("time to sort: "); + Serial.print(timeToSort); + Serial.println("us\n\r"); +} + +void bridgesToPaths(void) +{ + sortPathsByNet(); + for (int i = 0; i < numberOfPaths; i++) + { + + Serial.print("path["); + Serial.print(i); + Serial.print("]\n\rnodes ["); + Serial.print(path[i].node1); + Serial.print("-"); + Serial.print(path[i].node2); + Serial.println("]\n\r"); + + findStartAndEndChips(path[i].node1, path[i].node2, i); + + Serial.print("\n\rstart chip: "); + Serial.println(chipNumToChar(startEndChip[0])); + Serial.print("end chip: "); + Serial.println(chipNumToChar(startEndChip[1])); + Serial.println("\n\n\n\r"); + } + + printPathArray(); + sortAllChipsLeastToMostCrowded(); + resolveChipCandidates(); +} + +void findStartAndEndChips(int node1, int node2, int pathIdx) +{ + bothNodes[0] = node1; + bothNodes[1] = node2; + startEndChip[0] = -1; + startEndChip[1] = -1; + + Serial.print("finding chips for nodes: "); + Serial.print(definesToChar(node1)); + Serial.print("-"); + Serial.println(definesToChar(node2)); + + for (int twice = 0; twice < 2; twice++) // first run gets node1 and start chip, second is node2 and end + { + Serial.print("\n\rnode: "); + Serial.println(twice + 1); + Serial.println(" "); + int candidatesFound = 0; + + switch (bothNodes[twice]) // not checking availability, just finding the chip + { + + case 1: + case 30: + case 32: + case 61: + { + startEndChip[twice] = CHIP_L; + Serial.print("sf chip: "); + Serial.println(chipNumToChar(startEndChip[twice])); + path[pathIdx].chip[twice] = startEndChip[twice]; + + break; + } + + case 2 ... 29: // on the breadboard + case 33 ... 60: + { + for (int i = 0; i < 8; i++) + { + for (int j = 1; j < 8; j++) // start at 1 so we dont confuse CHIP_L for a node + { + if (ch[i].yMap[j] == bothNodes[twice]) + { + startEndChip[twice] = i; + Serial.print("bb chip: "); + Serial.println(chipNumToChar(startEndChip[twice])); + path[pathIdx].chip[twice] = startEndChip[twice]; + break; + } + } + } + break; + } + case NANO_D0 ... NANO_A7: // on the nano + { + int nanoIndex = defToNano(bothNodes[twice]); + + if (nano.numConns[nanoIndex] == 1) + { + startEndChip[twice] = nano.mapIJ[nanoIndex]; + Serial.print("nano chip: "); + Serial.println(chipNumToChar(startEndChip[twice])); + path[pathIdx].chip[twice] = startEndChip[twice]; + } + else + { + chipCandidates[twice][0] = nano.mapIJ[nanoIndex]; + path[pathIdx].candidates[twice][0] = chipCandidates[twice][0]; + candidatesFound++; + chipCandidates[twice][1] = nano.mapKL[nanoIndex]; + path[pathIdx].candidates[twice][1] = chipCandidates[twice][1]; + candidatesFound++; + Serial.print("nano candidate chips: "); + Serial.print(chipNumToChar(chipCandidates[twice][0])); + Serial.print(" "); + Serial.println(chipNumToChar(chipCandidates[twice][1])); + } + break; + } + case GND ... CURRENT_SENSE_MINUS: + { + + Serial.print("special function candidate chips: "); + for (int i = 8; i < 12; i++) + { + for (int j = 0; j < 16; j++) + { + if (ch[i].xMap[j] == bothNodes[twice]) + { + chipCandidates[twice][candidatesFound] = i; + path[pathIdx].candidates[twice][candidatesFound] = chipCandidates[twice][candidatesFound]; + candidatesFound++; + Serial.print(chipNumToChar(i)); + Serial.print(" "); + } + } + } + Serial.println(" "); + break; + } + } + //Serial.print("\n\r"); + } + + if (startEndChip[0] == -1 || startEndChip[1] == -1) + { + } + else + { + + } + + +} + +void resolveChipCandidates(void) +{ + int nodesToResolve[2] = {0,0}; // {node1,node2} 0 = already found, 1 = needs resolving + + + + for (int pathIndex = 0; pathIndex < numberOfPaths; pathIndex++) + { + nodesToResolve[0] = 0; + nodesToResolve[1] = 0; + + if (path[pathIndex].chip[0] == -1) + { + nodesToResolve[0] = 1; + } + else + { + nodesToResolve[0] = 0; + } + + if (path[pathIndex].chip[1] == -1) + { + nodesToResolve[1] = 1; + } + else + { + nodesToResolve[1] = 0; + } + + + + + for (int nodeOneOrTwo = 0; nodeOneOrTwo < 2; nodeOneOrTwo++) + { + if(nodesToResolve[nodeOneOrTwo] == 1) + { + + + path[pathIndex].chip[nodeOneOrTwo] = moreAvailableChip(path[pathIndex].candidates[nodeOneOrTwo][0], path[pathIndex].candidates[nodeOneOrTwo][1]); + + Serial.print("path["); + Serial.print(pathIndex); + Serial.print("] chip from "); + Serial.print(chipNumToChar(path[pathIndex].chip[(1+nodeOneOrTwo)%2])); + Serial.print(" to chip "); + Serial.print(chipNumToChar(path[pathIndex].chip[nodeOneOrTwo])); + Serial.print(" chosen\n\n\r"); + } + + + + } + + + + + } + + +} + +void bbToSfConnections (void) +{ + + for (int i = 0 ; i < numberOfPaths; i++) + { + if (path[i].chip[0] > 7 && path[i].chip[1] <= 7 && path[i].chip[1] >= 0) + { + + + bbToSfLanes[path[i].chip[1]][path[i].chip[0] - 8] ++; //why is this happening every loop + Serial.print (i); + Serial.print (" "); + Serial.print (chipNumToChar((path[i].chip[1]))); + Serial.print ("-"); + Serial.println (chipNumToChar((path[i].chip[0]))); + + + } else if (path[i].chip[1] > 7 && path[i].chip[0] <= 7 && path[i].chip[0] >= 0) + + bbToSfLanes[path[i].chip[0]][path[i].chip[1] - 8] ++; + Serial.print (i); + Serial.print (" "); + Serial.print (chipNumToChar((path[i].chip[0]))); + Serial.print ("-"); + Serial.println (chipNumToChar((path[i].chip[1]))); + + + + + } + + + +for (int i = 0; i < 8; i++) +{ + Serial.print(chipNumToChar(i)); + Serial.print(": "); + for (int j = 0; j < 4; j++) + { + Serial.print(chipNumToChar(j + 8)); + Serial.print(bbToSfLanes[i][j]); + Serial.print(" "); + } + Serial.println("\n\r"); +} + + +} + +int moreAvailableChip (int chip1 , int chip2) +{ + int chipChosen = -1; + sortAllChipsLeastToMostCrowded(); + + for (int i = 0; i < 12; i++) + { + if (chipsLeastToMostCrowded[i] == chip1 || chipsLeastToMostCrowded[i] == chip2) + { + chipChosen = chipsLeastToMostCrowded[i]; + break; + } + } +return chipChosen; + +} + + +void sortSFchipsLeastToMostCrowded(void) +{ + int numberOfConnectionsPerSFchip[4] = {0,0,0,0}; + + + for (int i = 0; i < numberOfPaths; i++) + { + for (int j = 0; j < 2; j++) + { + if (path[i].chip[j] > 7) + { + numberOfConnectionsPerSFchip[path[i].chip[j] - 8]++; + } + } + + + + + } +for (int i = 0; i < 4; i++) +{ +Serial.print("sf connections: "); +Serial.print (chipNumToChar(i + 8)); +Serial.print(numberOfConnectionsPerSFchip[i]); +Serial.print("\n\r"); + + +} + + + +} + +void sortAllChipsLeastToMostCrowded(void) +{ + debugNTCC = false; + int numberOfConnectionsPerChip[12] = {0,0,0,0,0,0,0,0,0,0,0,0}; //this will be used to determine which chip is most crowded + + + for (int i = 0; i < 12; i++) + { + chipsLeastToMostCrowded[i] = i; + + } + + Serial.println("\n\r"); + + for (int i = 0; i < numberOfPaths; i++) + { + for (int j = 0; j < 2; j++) + { + if (path[i].chip[j] != -1) + { + numberOfConnectionsPerChip[path[i].chip[j]]++; + } + } + + } +if (debugNTCC) +{ + for (int i = 0; i < 12; i++) + { + Serial.print(chipNumToChar(i)); + Serial.print(": "); + Serial.println(numberOfConnectionsPerChip[i]); + } + + Serial.println("\n\r"); +} + int temp = 0; + + for (int i = 0; i < 12; i++) + { + for (int j = 0; j < 11; j++) + { + if (numberOfConnectionsPerChip[j] > numberOfConnectionsPerChip[j + 1]) + { + temp = numberOfConnectionsPerChip[j]; + //chipsLeastToMostCrowded[j] = chipsLeastToMostCrowded[j + 1]; + numberOfConnectionsPerChip[j] = numberOfConnectionsPerChip[j + 1]; + numberOfConnectionsPerChip[j + 1] = temp; + + temp = chipsLeastToMostCrowded[j]; + chipsLeastToMostCrowded[j] = chipsLeastToMostCrowded[j + 1]; + chipsLeastToMostCrowded[j + 1] = temp; + } + } + } + + for (int i = 0; i < 12; i++) + { + + if (chipsLeastToMostCrowded[i] > 7) + { + sfChipsLeastToMostCrowded[i - 8] = chipsLeastToMostCrowded[i]; + } + if (debugNTCC) +{ + Serial.print(chipNumToChar(chipsLeastToMostCrowded[i])); + Serial.print(": "); + Serial.println(numberOfConnectionsPerChip[i]); +} + } +if (debugNTCC) +{ + for (int i = 0; i < 4; i++) + { + Serial.print("\n\n\r"); + Serial.print(chipNumToChar(sfChipsLeastToMostCrowded[i])); + Serial.print(": "); + + Serial.print("\n\n\r"); + } +} +debugNTCC = true; +bbToSfConnections(); + +} + + +void printPathArray(void) // this also prints candidates and x y +{ + // Serial.print("\n\n\r"); + // Serial.print("newBridgeIndex = "); + // Serial.println(newBridgeIndex); + Serial.print("\n\r"); + int tabs = 0; + int lineCount = 0; + for (int i = 0; i < newBridgeLength; i++) + { + tabs += Serial.print(i); + Serial.print(" "); + if (i < 10) + { + tabs += Serial.print(" "); + } + if (i < 100) + { + tabs += Serial.print(" "); + } + tabs += Serial.print("["); + tabs += printNodeOrName(path[i].node1); + tabs += Serial.print("-"); + tabs += printNodeOrName(path[i].node2); + tabs += Serial.print("]\tNet "); + tabs += printNodeOrName(path[i].net); + tabs += Serial.println(" "); + tabs += Serial.print("\n\rnode1 chip: "); + tabs += printChipNumToChar(path[i].chip[0]); + tabs += Serial.print("\n\rnode2 chip: "); + tabs += printChipNumToChar(path[i].chip[1]); + tabs += Serial.print("\n\n\rnode1 candidates: "); + for (int j = 0; j < 3; j++) + { + printChipNumToChar(path[i].candidates[0][j]); + tabs += Serial.print(" "); + } + tabs += Serial.print("\n\rnode2 candidates: "); + for (int j = 0; j < 3; j++) + { + printChipNumToChar(path[i].candidates[1][j]); + tabs += Serial.print(" "); + } + + tabs += Serial.println("\n\n\r"); + + // Serial.print(tabs); + // for (int i = 0; i < 24 - (tabs); i++) + //{ + // Serial.print(" "); + // } + tabs = 0; + } +} + +int defToNano(int nanoIndex) +{ + return nanoIndex - NANO_D0; +} + +char chipNumToChar(int chipNumber) +{ + return chipNumber + 'A'; +} + +int printChipNumToChar(int chipNumber) +{ + if (chipNumber == -1) + { + return Serial.print(" "); + } + else + { + + return Serial.print((char)(chipNumber + 'A')); + } +} + +void clearChipsOnPathToNegOne(void) +{ + for (int i = 0; i < MAX_BRIDGES; i++) + { + if (i > numberOfPaths) + { + path[i].node1 = -1; // i know i can just do {-1,-1,-1} but + path[i].node2 = -1; + path[i].net = -1; + } + + for (int c = 0; c < 3; c++) + { + path[i].chip[c] = -1; + path[i].x[c] = -1; + path[i].y[c] = -1; + + path[i].candidates[c][0] = -1; + path[i].candidates[c][1] = -1; + path[i].candidates[c][2] = -1; //CEEEEEEEE!!!!!! i had this set to 3 and it was clearing everything, but no im not using rust + } + } +} +/* +So the nets are all made, now we need to figure out which chip connections need to be made to make that phycically happen + +start with the special function nets, they're the highest priority + +maybe its simpler to make an array of every possible connection + + +start at net 1 and go up + +find start and end chip + +bb chips +sf chips +nano chips + + +things that store x and y valuse for paths +chipStatus.xStatus[] +chipStatus.yStatus[] +nanoStatus.xStatusIJKL[] + + +struct nanoStatus { //there's only one of these so ill declare and initalize together unlike above + +//all these arrays should line up (both by index and visually) so one index will give you all this data + +// | | | | | | | | | | | | | | | | | | | | | | | | | +const char *pinNames[24]= { " D0", " D1", " D2", " D3", " D4", " D5", " D6", " D7", " D8", " D9", "D10", "D11", "D12", "D13", "RST", "REF", " A0", " A1", " A2", " A3", " A4", " A5", " A6", " A7"};// String with readable name //padded to 3 chars (space comes before chars) +// | | | | | | | | | | | | | | | | | | | | | | | | | +const int8_t pinMap[24] = { NANO_D0, NANO_D1, NANO_D2, NANO_D3, NANO_D4, NANO_D5, NANO_D6, NANO_D7, NANO_D8, NANO_D9, NANO_D10, NANO_D11, NANO_D12, NANO_D13, NANO_RESET, NANO_AREF, NANO_A0, NANO_A1, NANO_A2, NANO_A3, NANO_A4, NANO_A5, NANO_A6, NANO_A7};//Array index to internal arbitrary #defined number +// | | | | | | | | | | | | | | | | | | | | | | | | | +const int8_t numConns[24]= { 1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 1 };//Whether this pin has 1 or 2 connections to special function chips (OR maybe have it be a map like i = 2 j = 3 k = 4 l = 5 if there's 2 it's the product of them ij = 6 ik = 8 il = 10 jk = 12 jl = 15 kl = 20 we're trading minuscule amounts of CPU for RAM) +// | | | | | | | | | | | | | | | | | | | | | | | | | +const int8_t mapIJ[24] = { CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J , CHIP_I , CHIP_J };//Since there's no overlapping connections between Chip I and J, this holds which of those 2 chips has a connection at that index, if numConns is 1, you only need to check this one +const int8_t mapKL[24] = { -1 , -1 , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , -1 , -1 , -1 , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_L , CHIP_L , -1 , -1 };//Since there's no overlapping connections between Chip K and L, this holds which of those 2 chips has a connection at that index, -1 for no connection +// | | | | | | | | | | | | | | | | | | | | | | | | | +const int8_t xMapI[24] = { -1 , 1 , -1 , 3 , -1 , 5 , -1 , 7 , -1 , 9 , -1 , 8 , -1 , 10 , 11 , -1 , 0 , -1 , 2 , -1 , 4 , -1 , 6 , -1 };//holds which X pin is connected to the index on Chip I, -1 for none + int8_t xStatusI[24] = { -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 };//-1 for not connected to that chip, 0 for available, >0 means it's connected and the netNumber is stored here +// | | | | | | | | | | | | | | | | | | | | | | | | | +const int8_t xMapJ[24] = { 0 , -1 , 2 , -1 , 4 , -1 , 6 , -1 , 8 , -1 , 9 , -1 , 10 , -1 , -1 , 11 , -1 , 1 , -1 , 3 , -1 , 5 , -1 , 7 };//holds which X pin is connected to the index on Chip J, -1 for none + int8_t xStatusJ[24] = { 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 , -1 , 0 };//-1 for not connected to that chip, 0 for available, >0 means it's connected and the netNumber is stored here +// | | | | | | | | | | | | | | | | | | | | | | | | | +const int8_t xMapK[24] = { -1 , -1 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , -1 , -1 , -1 , 0 , 1 , 2 , 3 , -1 , -1 , -1 , -1 };//holds which X pin is connected to the index on Chip K, -1 for none + int8_t xStatusK[24] = { -1 , -1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , -1 , -1 , -1 , -1 };//-1 for not connected to that chip, 0 for available, >0 means it's connected and the netNumber is stored here +// | | | | | | | | | | | | | | | | | | | | | | | | | +const int8_t xMapL[24] = { -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , 12 , 13 , -1 , -1 };//holds which X pin is connected to the index on Chip L, -1 for none + int8_t xStatusL[24] = { -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , 0 , 0 , -1 , -1 };//-1 for not connected to that chip, 0 for available, >0 means it's connected and the netNumber is stored here + +// mapIJKL[] will tell you whethher there's a connection from that nano pin to the corresponding special function chip +// xMapIJKL[] will tell you the X pin that it's connected to on that sf chip +// xStatusIJKL[] says whether that x pin is being used (this should be the same as mt[8-10].xMap[] if theyre all stacked on top of each other) +// I haven't decided whether to make this just a flag, or store that signal's destination +const int8_t reversePinMap[110] = {NANO_D0, NANO_D1, NANO_D2, NANO_D3, NANO_D4, NANO_D5, NANO_D6, NANO_D7, NANO_D8, NANO_D9, NANO_D10, NANO_D11, NANO_D12, NANO_D13, NANO_RESET, NANO_AREF, NANO_A0, NANO_A1, NANO_A2, NANO_A3, NANO_A4, NANO_A5, NANO_A6, NANO_A7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,GND,101,102,SUPPLY_3V3,104,SUPPLY_5V,DAC0_5V,DAC1_8V,CURRENT_SENSE_PLUS,CURRENT_SENSE_MINUS}; + +}; + +struct netStruct net[MAX_NETS] = { //these are the special function nets that will always be made +//netNumber, ,netName ,memberNodes[] ,memberBridges[][2] ,specialFunction ,intsctNet[] ,doNotIntersectNodes[] ,priority + { 127 ,"Empty Net" ,{EMPTY_NET} ,{{}} ,EMPTY_NET ,{} ,{EMPTY_NET,EMPTY_NET,EMPTY_NET,EMPTY_NET,EMPTY_NET,EMPTY_NET,EMPTY_NET} , 0}, + { 1 ,"GND\t" ,{GND} ,{{}} ,GND ,{} ,{SUPPLY_3V3,SUPPLY_5V,DAC0_5V,DAC1_8V} , 1}, + { 2 ,"+5V\t" ,{SUPPLY_5V} ,{{}} ,SUPPLY_5V ,{} ,{GND,SUPPLY_3V3,DAC0_5V,DAC1_8V} , 1}, + { 3 ,"+3.3V\t" ,{SUPPLY_3V3} ,{{}} ,SUPPLY_3V3 ,{} ,{GND,SUPPLY_5V,DAC0_5V,DAC1_8V} , 1}, + { 4 ,"DAC 0\t" ,{DAC0_5V} ,{{}} ,DAC0_5V ,{} ,{GND,SUPPLY_5V,SUPPLY_3V3,DAC1_8V} , 1}, + { 5 ,"DAC 1\t" ,{DAC1_8V} ,{{}} ,DAC1_8V ,{} ,{GND,SUPPLY_5V,SUPPLY_3V3,DAC0_5V} , 1}, + { 6 ,"I Sense +" ,{CURRENT_SENSE_PLUS} ,{{}} ,CURRENT_SENSE_PLUS ,{} ,{CURRENT_SENSE_MINUS} , 2}, + { 7 ,"I Sense -" ,{CURRENT_SENSE_MINUS} ,{{}} ,CURRENT_SENSE_MINUS ,{} ,{CURRENT_SENSE_PLUS} , 2}, +}; + + + +Index Name Number Nodes Bridges Do Not Intersects +0 Empty Net 127 EMPTY_NET {0-0} EMPTY_NET +1 GND 1 GND,1,2,D0,3,4 {1-GND,1-2,D0-1,2-3,3-4} 3V3,5V,DAC_0,DAC_1 +2 +5V 2 5V,11,12,10,9 {11-5V,11-12,10-11,9-10} GND,3V3,DAC_0,DAC_1 +3 +3.3V 3 3V3,D10,D11,D12 {D10-3V3,D10-D11,D11-D12} GND,5V,DAC_0,DAC_1 +4 DAC 0 4 DAC_0 {0-0} GND,5V,3V3,DAC_1 +5 DAC 1 5 DAC_1 {0-0} GND,5V,3V3,DAC_0 +6 I Sense + 6 I_POS,6,5,A1,AREF {6-I_POS,5-6,A1-5,AREF-A1} I_NEG +7 I Sense - 7 I_NEG {0-0} I_POS + +Index Name Number Nodes Bridges Do Not Intersects +8 Net 8 8 7,8 {7-8} 0 +9 Net 9 9 D13,D1,A7 {D13-D1,D13-A7} 0 + + + + +struct chipStatus{ + +int chipNumber; +char chipChar; +int8_t xStatus[16]; //store the bb row or nano conn this is eventually connected to so they can be stacked if conns are redundant +int8_t yStatus[8]; //store the row/nano it's connected to +const int8_t xMap[16]; +const int8_t yMap[8]; + +}; + + + +struct chipStatus ch[12] = { + {0,'A', + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // x status + {-1,-1,-1,-1,-1,-1,-1,-1}, //y status + {CHIP_I, CHIP_J, CHIP_B, CHIP_B, CHIP_C, CHIP_C, CHIP_D, CHIP_D, CHIP_E, CHIP_K, CHIP_F, CHIP_F, CHIP_G, CHIP_G, CHIP_H, CHIP_H},//X MAP constant + {CHIP_L, t2,t3, t4, t5, t6, t7, t8}}, // Y MAP constant + + {1,'B', + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // x status + {-1,-1,-1,-1,-1,-1,-1,-1}, //y status + {CHIP_A, CHIP_A, CHIP_I, CHIP_J, CHIP_C, CHIP_C, CHIP_D, CHIP_D, CHIP_E, CHIP_E, CHIP_F, CHIP_K, CHIP_G, CHIP_G, CHIP_H, CHIP_H}, + {CHIP_L, t9,t10,t11,t12,t13,t14,t15}}, + + {2,'C', + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // x status + {-1,-1,-1,-1,-1,-1,-1,-1}, //y status + {CHIP_A, CHIP_A, CHIP_B, CHIP_B, CHIP_I, CHIP_J, CHIP_D, CHIP_D, CHIP_E, CHIP_E, CHIP_F, CHIP_F, CHIP_G, CHIP_K, CHIP_H, CHIP_H}, + {CHIP_L, t16,t17,t18,t19,t20,t21,t22}}, + + {3,'D', + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // x status + {-1,-1,-1,-1,-1,-1,-1,-1}, //y status + {CHIP_A, CHIP_A, CHIP_B, CHIP_B, CHIP_C, CHIP_C, CHIP_I, CHIP_J, CHIP_E, CHIP_E, CHIP_F, CHIP_F, CHIP_G, CHIP_G, CHIP_H, CHIP_K}, + {CHIP_L, t23,t24,t25,t26,t27,t28,t29}}, + + {4,'E', + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // x status + {-1,-1,-1,-1,-1,-1,-1,-1}, //y status + {CHIP_A, CHIP_K, CHIP_B, CHIP_B, CHIP_C, CHIP_C, CHIP_D, CHIP_D, CHIP_I, CHIP_J, CHIP_F, CHIP_F, CHIP_G, CHIP_G, CHIP_H, CHIP_H}, + {CHIP_L, b2, b3, b4, b5, b6, b7, b8}}, + + {5,'F', + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // x status + {-1,-1,-1,-1,-1,-1,-1,-1}, //y status + {CHIP_A, CHIP_A, CHIP_B, CHIP_K, CHIP_C, CHIP_C, CHIP_D, CHIP_D, CHIP_E, CHIP_E, CHIP_I, CHIP_J, CHIP_G, CHIP_G, CHIP_H, CHIP_H}, + {CHIP_L, b9, b10,b11,b12,b13,b14,b15}}, + + {6,'G', + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // x status + {-1,-1,-1,-1,-1,-1,-1,-1}, //y status + {CHIP_A, CHIP_A, CHIP_B, CHIP_B, CHIP_C, CHIP_K, CHIP_D, CHIP_D, CHIP_E, CHIP_E, CHIP_F, CHIP_F, CHIP_I, CHIP_J, CHIP_H, CHIP_H}, + {CHIP_L, b16,b17,b18,b19,b20,b21,b22}}, + + {7,'H', + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // x status + {-1,-1,-1,-1,-1,-1,-1,-1}, //y status + {CHIP_A, CHIP_A, CHIP_B, CHIP_B, CHIP_C, CHIP_C, CHIP_D, CHIP_K, CHIP_E, CHIP_E, CHIP_F, CHIP_F, CHIP_G, CHIP_G, CHIP_I, CHIP_J}, + {CHIP_L, b23,b24,b25,b26,b27,b28,b29}}, + + {8,'I', + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // x status + {-1,-1,-1,-1,-1,-1,-1,-1}, //y status + {NANO_A0, NANO_D1, NANO_A2, NANO_D3, NANO_A4, NANO_D5, NANO_A6, NANO_D7, NANO_D11, NANO_D9, NANO_D13, NANO_RESET, DAC0_5V, ADC0_5V, SUPPLY_3V3, GND}, + {CHIP_A,CHIP_B,CHIP_C,CHIP_D,CHIP_E,CHIP_F,CHIP_G,CHIP_H}}, + + {9,'J', + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // x status + {-1,-1,-1,-1,-1,-1,-1,-1}, //y status + {NANO_D0, NANO_A1, NANO_D2, NANO_A3, NANO_D4, NANO_A5, NANO_D6, NANO_A7, NANO_D8, NANO_D10, NANO_D12, NANO_AREF, DAC1_8V, ADC1_5V, SUPPLY_5V, GND}, + {CHIP_A,CHIP_B,CHIP_C,CHIP_D,CHIP_E,CHIP_F,CHIP_G,CHIP_H}}, + + {10,'K', + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // x status + {-1,-1,-1,-1,-1,-1,-1,-1}, //y status + {NANO_A0, NANO_A1, NANO_A2, NANO_A3, NANO_A4, NANO_A5, NANO_A6, NANO_A7, NANO_D2, NANO_D3, NANO_D4, NANO_D5, NANO_D6, NANO_D7, NANO_D8, NANO_D9}, + {CHIP_A,CHIP_B,CHIP_C,CHIP_D,CHIP_E,CHIP_F,CHIP_G,CHIP_H}}, + + {11,'L', + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // x status + {-1,-1,-1,-1,-1,-1,-1,-1}, //y status + {CURRENT_SENSE_MINUS, CURRENT_SENSE_PLUS, ADC0_5V, ADC1_5V, ADC2_5V, ADC3_8V, DAC1_8V, DAC0_5V, t1, t30, b1, b30, NANO_A4, NANO_A5, SUPPLY_5V, GND}, + {CHIP_A,CHIP_B,CHIP_C,CHIP_D,CHIP_E,CHIP_F,CHIP_G,CHIP_H}} + }; + +enum nanoPinsToIndex { NANO_PIN_D0 , NANO_PIN_D1 , NANO_PIN_D2 , NANO_PIN_D3 , NANO_PIN_D4 , NANO_PIN_D5 , NANO_PIN_D6 , NANO_PIN_D7 , NANO_PIN_D8 , NANO_PIN_D9 , NANO_PIN_D10 , NANO_PIN_D11 , NANO_PIN_D12 , NANO_PIN_D13 , NANO_PIN_RST , NANO_PIN_REF , NANO_PIN_A0 , NANO_PIN_A1 , NANO_PIN_A2 , NANO_PIN_A3 , NANO_PIN_A4 , NANO_PIN_A5 , NANO_PIN_A6 , NANO_PIN_A7 }; + +extern struct nanoStatus nano; + + +struct pathStruct{ + + int node1; //these are the rows or nano header pins to connect + int node2; + int net; + + int chip[3]; + int x[3]; + int y[3]; + int candidates[3][3]; + +}; + +*/ \ No newline at end of file diff --git a/JumperlessNano/src/NetsToChipConnections.h b/JumperlessNano/src/NetsToChipConnections.h new file mode 100644 index 0000000..18768c6 --- /dev/null +++ b/JumperlessNano/src/NetsToChipConnections.h @@ -0,0 +1,56 @@ +#ifndef NETTOCHIPCONNECTIONS_H +#define NETTOCHIPCONNECTIONS_H + + + + + + + +void sortPathsByNet(void); +void bridgesToPaths(void); + +void findStartAndEndChips(int node1, int node2, int net); + +void resolveChipCandidates(); + +void printPathArray(); + +int defToNano(int nanoIndex); + +void bbToSfConnections(void); + +char chipNumToChar(int); +int printChipNumToChar(int); + +void clearChipsOnPathToNegOne(void); + +void sortAllChipsLeastToMostCrowded(void); + +void sortSFchipsMostToLeastCrowded(void); + +int moreAvailableChip (int chip1 , int chip2); + + + + + + + + + + + + + + + + + + + + + + + +#endif \ No newline at end of file diff --git a/JumperlessNano/src/main.cpp b/JumperlessNano/src/main.cpp index 0ccac6b..ac1432c 100644 --- a/JumperlessNano/src/main.cpp +++ b/JumperlessNano/src/main.cpp @@ -3,7 +3,9 @@ #include "NetManager.h" #include "MatrixStateRP2040.h" #include "LittleFS.h" - +#include "FileParsing.h" +#include "NetsToChipConnections.h" +#include "LEDs.h" //nanoStatus nano; @@ -15,29 +17,38 @@ const char* definesToChar (int); //i really need to find a way to not need to fo void setup() { Serial.begin(115200); - pinMode(LED_BUILTIN, OUTPUT_12MA); + pinMode(25, OUTPUT); + LittleFS.begin(); delay(3000); openNodeFile(); + +initLEDs(); + } void loop() { -digitalWrite(LED_BUILTIN,HIGH); -delay(100); -digitalWrite(LED_BUILTIN,LOW); +//digitalWrite(LED_BUILTIN,HIGH); +//delay(100); +//digitalWrite(LED_BUILTIN,LOW); - delay(800); + rainbowy(180 ,55 , 20); // Red + + //delay(800); getNodesToConnect(); -delay(800); +//delay(800); Serial.println("\n\n\rfinal netlist\n\n\r"); listSpecialNets(); listNets(); +//printBridgeArray(); + +bridgesToPaths(); while(1); -Serial.println("\n\r"); +//Serial.println("\n\r"); //writeJSONtoFile();