Add files via upload

This commit is contained in:
Kevin Santo Cappuccio 2023-03-25 13:01:09 -07:00 committed by GitHub
parent 7e937e634b
commit b5f19ed4c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 1211 additions and 0 deletions

View File

@ -0,0 +1,143 @@
This is just to make a mental map or how an arduino board
plugged into jumperless will communicate what connections
to make to the onboard AVR32DD32 controller via I2C or
UART. We'll use the Stream library so the calls will be
the same either way. There should be a sections for each
of these things:
Data format - different message types/headers to be sent over I2C or UART to the control chip
Let's start with UART
#Dumb mode# *maybe start with this because it's way easier*
Dumb mode where pathfinding is done on the Nano and connections are sent raw
Messages will just be: crosspoint chip (A-K), Y connection (0-15), X connection(0-7), connect or disconnect (1/0), reset (y/n), DAC output (0-1023)
Storing connections and stuff will be the responsibility of the Nano and
DAC could just be included in the same message above for simplicity
@jumperless -dumb <A,12,3,1> <B,2,3,1> @end
sentinel mode ch,X ,Y,c
#Smart mode#
Connections/disconnections
Connect/disconnect from Nano to breadboard (I,J,K chips) this may call the BB connection function below
Return number of hops, estimated resistance
Connect/disconnect within the breadboard (A-H chips) optional priority and redundancy value (make parallel connections)
Return number of hops, estimated resistance
Load an entire state
Send @A0, (connection), (connection), @A1, (connection), etc. @row0, (connection), @row1, @row2, (connection), (connection), etc.
Reset all connections
Find a path and return it without actually making any connections
DAC setting/waveform generation (maybe store some lookup tables for various waves on the controller)
Send custom waveform lookup table (or equation to make it on the fly - that's distant future shit though)
Request the voltage setting on DAC
Request state of the matrix (Backend or frontend, how many open connections there are left and maybe some sort of "utilization score")
Low Level request per chip (so send A-K)
returns X[16] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, Y[8] {0,0,0,0,0,0,0,0} //0 = free 1 = used for that chip
High level style request for the board
returns breadboardRows{0-60} @row0,(if no connections send nothing after it), @row1, (send comma seprated rows it's connected to, and nano header labels), @row3, etc. $end
This is a tricky one, because there shouldn't reall be a maximum number of connections per row if we use all the tricks to get more connections
I guess there's some theoretical maximum that I should figure out (probably like ~40ish idk), but we don't want to allocate memory locations for the theoretical maximum
number of connections 60 times. It feels wasteful considering the reasonable maximum will be like ~5.
I recently redid this as a linked list where each connection is a new entry so it's only storing connections. So maybe that's fine.
I think these should be human readable, so maybe send something like @row1,(connections) so the values following aren't confused with moving onto the next row
and we can do this for the nano connections as text too, so @A0, (connection), (connection), @A1, (connection), @A2, @A3, etc.
So the @prefix will say "we're listing connnections for the following row/nano connection" and things following without the @ will be interpreted as connections
High level style request for the nano (same data as above but from the nano's POV instead)
returns nanoHeaderPins{0-30} @A0,(if no connections send nothing after it), @A1, (send comma seprated rows it's connected to, and other nano header labels), @A3, etc. $end
We should probably keep the linked list containing the connections in order so we don't have to search the whole thing every time
or maybe initialize it with an empty connection for every row so things can be easily found and placed into the list?
High level style request for a single row/nano pin
send @row/nano pin
returns @row/nano pin, (connection (without the @ prefix)), (connection), etc. then some sort of EOF signal, maybe $end or something like that
Request for which UNCONNECTED_(A-H) are free (send whether you want yes/no or what they're connected to) this will be used a lot in hop finding
if you just want free/used
returns UNCONNECTED[8] {0,0,0,0,0,0,0,0} // 0 for free, 1 for used
if you want what they're connected to it will be similar to above
returns @UNCONNECTED_A, (connection), (connection), (connection), @UNCONNECTED_B, (connection), @UNCONNECTED_C, etc. , $end
Change jumper settings
State of the solder jumpers that decide whether the unconnected BB rows are on both sides or the far right
Whether to disable the op amp (cause the power supply jumpers are cut) or not and and not worry about it
Voltage setting jumpers on the top and bottom rails (+3.3V, 5V, DAC+-9V, disconnected/external)
Maybe UPDI programming jumper but I'm not sure that even matters
Change I2C address, speed or UART baud setting
Storage of the state (on the controller chip or Nano? probably the controller with an option for the nano)
TODO: this isn't fully thought out but I need to go fix a water heater right now
I think we should keep a sorted linked list with an entry for each new connection like I've already done
Here's the struct from the current Jumperless code (it may need to be reworked to account for the nano headers, or have a separate one for them)
struct connection { //I can't decide whether to store both hops in the same struct but for now I will
bool used; //I guess if there's an entry for it, used will always be true
int row1; //this needs to be changed to account for the nano pins now
int row2;
int chip1;
int chip2;
int chip1Xaddr;
int chip1Yaddr;
int chip2Xaddr;
int chip2Yaddr;
int lane; //each chip has 2 connections to every other chip (almost, I took out one of the lanes for chips that are directly across
//from each other to make room for the K special function chip) values are 0 or 1 so it could be a bool
int hop; //also could be a bool unless we allow double hops in which case we need more hopChip entries below
int hopChip;
int hopChipXaddr1; //we know the Y address will be 0 because UNCONNECTED_(A-H) are all at Yaddr 0, but maybe it should be added for clarity
int hopChipXaddr2;
};

143
code/JumperlessDefines.h Normal file
View File

@ -0,0 +1,143 @@
#define CHIP_A 0
#define CHIP_B 1
#define CHIP_C 2
#define CHIP_D 3
#define CHIP_E 4
#define CHIP_F 5
#define CHIP_G 6
#define CHIP_H 7
#define CHIP_I 8
#define CHIP_J 9
#define CHIP_K 10
#define CS_A PIN_PA4
#define CS_B PIN_PA5
#define CS_C PIN_PA6
#define CS_D PIN_PA7
#define CS_E PIN_PF3
#define CS_F PIN_PF4
#define CS_G PIN_PF5
#define CS_H PIN_PD1
#define CS_I PIN_PD2
#define CS_J PIN_PD3
#define CS_K PIN_PD4
#define DATAPIN PIN_PA0
#define RESET PIN_PD7
#define STROBE PIN_PA1
#define AX0 PIN_PC0
#define AX1 PIN_PC1
#define AX2 PIN_PC2
#define AX3 PIN_PC3
#define AY0 PIN_PF0
#define AY1 PIN_PF1
#define AY2 PIN_PF2
#define DAC_OUT PIN_PD6
//#define I2C_UART_SELECTION_IN PIN_PD7
#define IN_TX_SDA PIN_PA2
#define IN_RX_SCL PIN_PA3
#define t1 1
#define t2 2
#define t3 3
#define t4 4
#define t5 5
#define t6 6
#define t7 7
#define t8 8
#define t9 9
#define t10 10
#define t11 11
#define t12 12
#define t13 13
#define t14 14
#define t15 15
#define t16 16
#define t17 17
#define t18 18
#define t19 19
#define t20 20
#define t21 21
#define t22 22
#define t23 23
#define t24 24
#define t25 25
#define t26 26
#define t27 27
#define t28 28
#define t29 29
#define t30 30
#define b1 32
#define b2 33
#define b3 34
#define b4 35
#define b5 36
#define b6 37
#define b7 38
#define b8 39
#define b9 40
#define b10 41
#define b11 42
#define b12 43
#define b13 44
#define b14 45
#define b15 46
#define b16 47
#define b17 48
#define b18 49
#define b19 50
#define b20 51
#define b21 52
#define b22 53
#define b23 54
#define b24 55
#define b25 56
#define b26 57
#define b27 58
#define b28 59
#define b29 60
#define b30 61
#define NANO_D0 70 //these are completely arbitrary but they should come in handy
#define NANO_D1 71
#define NANO_D2 72
#define NANO_D3 73
#define NANO_D4 74
#define NANO_D5 75
#define NANO_D6 76
#define NANO_D7 77
#define NANO_D8 78
#define NANO_D9 79
#define NANO_D10 80
#define NANO_D11 81
#define NANO_D12 82
#define NANO_D13 83
#define NANO_RESET 84
#define NANO_AREF 85
#define NANO_A0 86
#define NANO_A1 87
#define NANO_A2 88
#define NANO_A3 89
#define NANO_A4 90
#define NANO_A5 91
#define NANO_A6 92
#define NANO_A7 93
#define GND 100
#define TOP_RAIL 101
#define BOTTOM_RAIL 102
#define DAC0TO5V 103
#define DACPLUSMINUS9V 104

234
code/JumperlessNano.ino Normal file
View File

@ -0,0 +1,234 @@
#include <Arduino.h>
#include "JumperlessDefines.h"
#include "jMatrixControl.h"
#include "MatrixState.h"
jMatrixControl j;
//I would do this in PlatformIO but dxCore is outdated there and doesn't support DD series chips. And I spent some time on a workaround but gave up
nanoStatus nano;
void setup() {
//DAC0.CTRLA |= (DAC_OUTEN_bm | DAC_ENABLE_bm); // make sure the DAC is outputting 2.5V at rest so it doesn't heat the op amp trying to if it's unused
//DAC0.DATA = (1023 << 6);
//DAC0.DATA = (500 << 6);
//pinMode(PIN_PA2, OUTPUT);
// pinMode(PIN_PA3, OUTPUT);
//digitalWrite(PIN_PA2,LOW);
Serial.pins(PIN_PA2, PIN_PA3);
Serial.begin(115200);
pinMode(AY0, OUTPUT);
digitalWrite(AY0, LOW);
pinMode(AY1, OUTPUT);
digitalWrite(AY1, LOW);
pinMode(AY2, OUTPUT);
digitalWrite(AY2, LOW);
pinMode(AX0, OUTPUT);
digitalWrite(AX0, LOW);
pinMode(AX1, OUTPUT);
digitalWrite(AX1, LOW);
pinMode(AX2, OUTPUT);
digitalWrite(AX2, LOW);
pinMode(AX3, OUTPUT);
digitalWrite(AX3, LOW);
pinMode(CS_A, OUTPUT);
digitalWrite(CS_A, LOW);
pinMode(CS_B, OUTPUT);
digitalWrite(CS_B, LOW);
pinMode(CS_C, OUTPUT);
digitalWrite(CS_C, LOW);
pinMode(CS_D, OUTPUT);
digitalWrite(CS_D, LOW);
pinMode(CS_E, OUTPUT);
digitalWrite(CS_E, LOW);
pinMode(CS_F, OUTPUT);
digitalWrite(CS_F, LOW);
pinMode(CS_G, OUTPUT);
digitalWrite(CS_G, LOW);
pinMode(CS_H, OUTPUT);
digitalWrite(CS_H, LOW);
pinMode(CS_I, OUTPUT);
digitalWrite(CS_I, LOW);
pinMode(CS_J, OUTPUT);
digitalWrite(CS_J, LOW);
pinMode(CS_K, OUTPUT);
digitalWrite(CS_K, LOW);
pinMode(DATAPIN, OUTPUT);
pinMode(STROBE, OUTPUT);
pinMode(RESET, OUTPUT); // all of this just sets up all these pins as outputs and drives them LOW
// digitalWrite(RESET, HIGH); // I'm pretty sure Arduino IDE does this automatically but I wouldn't count on it
// delayMicroseconds(380);
digitalWrite(RESET, LOW);
j.clearAllConnections();
// j.connectDumbMode(1,5,'A',1);
}
int outVoltage = 0;
void loop() {
j.connectDumbMode(8, 1, 'E', 1); //right now all we have is dumb mode, there's a pathfinging function in the old repo but it needs to be redone in a more understandable way
j.connectDumbMode(14, 4, 'I', 1);
j.connectDumbMode(7, 6, 'D', 1);
j.connectDumbMode(12, 3, 'J', 1);
j.connectDumbMode(8, 2, 'D', 1);
j.connectDumbMode(6, 2, 'E', 1);
delay(1000);
j.connectDumbMode(6, 2, 'E', 0);
delay(1000);
printConnections();
delay(1000);
}
void printConnections(void) {
Serial.println("\n");
Serial.printf("Pin Name\tSF Chip Connections\n\r");
for (int i = 0; i < 24; i++) //just checking if I run out of space
{
Serial.print(nano.pinNames[i]);
Serial.print("\t\t");
if (nano.mapI[i] >= 0) {
Serial.print(j.chipIntToChar(nano.mapI[i]));
Serial.print(" x");
Serial.print(nano.xMapI[i]);
Serial.print("\t");
}
if (nano.mapJ[i] >= 0) {
Serial.print(j.chipIntToChar(nano.mapJ[i]));
Serial.print(" x");
Serial.print(nano.xMapJ[i]);
Serial.print("\t");
}
if (nano.mapK[i] >= 0) {
Serial.print(j.chipIntToChar(nano.mapK[i]));
Serial.print(" x");
Serial.print(nano.xMapK[i]);
Serial.print("\t");
}
Serial.println(" ");
}
Serial.println("\n\n");
Serial.println("\tX connections \t\t\t\t\t\t Y connections");
for (int i = 0; i < 11; i++) //just checking if I run out of space
{
if (i == 8) Serial.println(' ');
Serial.print(mt[i].chipChar);
Serial.print("\t ");
for (int j = 0; j < 16; j++) {
//mt[i].xStatus[j] = -1;
///int ch = (int) mt[i].xMap[j];
if (i < 8) {
Serial.print(mt[mt[i].xMap[j]].chipChar); //here we're using the value of yMap as the index to return chipChar on that chipStatus struct
} else {
switch (mt[i].xMap[j]) {
case GND:
Serial.print("GND");
break;
case TOP_RAIL:
Serial.print("TOP");
break;
case BOTTOM_RAIL:
Serial.print("BOT");
break;
case DAC0TO5V:
Serial.print("05V");
break;
case DACPLUSMINUS9V:
Serial.print("D9V");
break;
default:
//Serial.print(mt[i].xMap[j]);
Serial.print(nano.pinNames[nano.reversePinMap[mt[i].xMap[j]]]);
break;
}
}
if (j < 15) Serial.print(", ");
}
Serial.print("\t\t");
if (i > 7) Serial.print(" ");
for (int j = 0; j < 8; j++) {
//chips[i].yStatus[j] = j;
if (mt[i].yMap[j] > 0 && mt[i].yMap[j] < 10) Serial.print(' '); //padding
if (i > 7) {
Serial.print(mt[mt[i].yMap[j]].chipChar);
} else {
Serial.print(mt[i].yMap[j]);
}
if (j < 7) Serial.print(',');
}
Serial.println("\t <- Map");
Serial.print("\t");
for (int j = 0; j < 16; j++) {
//mt[i].xStatus[j] = -1;
if (i > 7) Serial.print(" ");
Serial.print(mt[i].xStatus[j]);
if (mt[i].xStatus[j] > 0 && mt[i].xStatus[j] < 10) Serial.print(' '); //padding
if (i > 7) Serial.print(" ");
if (j < 15) Serial.print(',');
}
Serial.print("\t\t");
for (int j = 0; j < 8; j++) {
//chips[i].yStatus[j] = j;
Serial.print(mt[i].yStatus[j]);
if (mt[i].yStatus[j] > 0 && mt[i].yStatus[j] < 10) Serial.print(' '); //padding
if (j < 7) Serial.print(',');
}
Serial.println("\t <- Status\n");
}
}

202
code/MatrixState.h Normal file
View File

@ -0,0 +1,202 @@
#ifndef MATRIXSTATE_H
#define MATRIXSTATE_H
#include <Arduino.h>
#include "JumperlessDefines.h"
//see the comments at the end for a more nicely formatted version that's not in struct initalizers
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 mt[11] = {
{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
{-1, 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},
{-1, 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},
{-1, 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},
{-1, 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},
{-1, 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},
{-1, 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},
{-1, 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},
{-1, 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, TOP_RAIL, BOTTOM_RAIL, GND, DAC0TO5V},
{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, TOP_RAIL, BOTTOM_RAIL, GND, DACPLUSMINUS9V},
{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}}
};
struct nanoStatus{ //there's only one of these so ill declare and initalize together unlike above
//all these arrays should line up 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 "};
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};
//this shows what sf chip each nano pin connects to
const int8_t mapI[24] = {-1 , CHIP_I , -1 , CHIP_I , -1 , CHIP_I , -1 , CHIP_I , -1 , CHIP_I , -1 , CHIP_I , -1 , CHIP_I , CHIP_I , -1 , CHIP_I , -1 , CHIP_I , -1 , CHIP_I , -1 , CHIP_I , -1 };
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 };
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
const int8_t mapJ[24] = {CHIP_J , -1 , CHIP_J , -1 , CHIP_J , -1 , CHIP_J , -1 , CHIP_J , -1 , CHIP_J , -1 , CHIP_J , -1 , -1 , CHIP_J , -1 , CHIP_J , -1 , CHIP_J , -1 , CHIP_J , -1 , CHIP_J };
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 };
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
const int8_t mapK[24] = {-1 , -1 , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , -1 , -1 , -1 , -1 , -1 , -1 , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K };
const int8_t xMapK[24] = {-1 , -1 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , -1 , -1 , -1 , -1 , -1 , -1 , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 };
int8_t xStatusK[24] = {-1 , -1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -1 , -1 , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }; //-1 for not connected to that chip, 0 for available
// mapIJK[] will tell you whethher there's a connection from that nano pin to the corresponding special function chip
// xMapIJK[] will tell you the X pin that it's connected to on that sf chip
// xStatusIJK[] 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[108] = {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,TOP_RAIL,BOTTOM_RAIL,DAC0TO5V,DACPLUSMINUS9V,105};
};
/*
uint8_t connectionsMatrix[85][85];
connectionsMatrix [1-60][1-60] are breadboard connections
connectionsMatrix [60-85][60-85] are Nano connections
value stored is row it's connected to, so we can use the value as the index for the next connection to see which nets are connected
or we can do a 64 bit number for the breadboard and just store a 1 or 0 in that bit location
uint64_t bbConns[64];
uint64_t nanoConns[25];
each set bit in the 64bit value correspond to which bb rows that nano pin is connected to
should nano conns be handled separately?
the problem with all this is that it says nothing about the path taken
*/
/*
//this is all defined in the struct initalizer now but leaving this here for reference
const int8_t sfyConnectionMap[8] = {CHIP_A,CHIP_B,CHIP_C,CHIP_D,CHIP_E,CHIP_F,CHIP_G,CHIP_H}; //chips
const int8_t xConnectionMapA[16] = {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};
const int8_t xConnectionMapB[16] = {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};
const int8_t xConnectionMapC[16] = {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};
const int8_t xConnectionMapD[16] = {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};
const int8_t xConnectionMapE[16] = {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};
const int8_t xConnectionMapF[16] = {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};
const int8_t xConnectionMapG[16] = {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};
const int8_t xConnectionMapH[16] = {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};
const int8_t yConnectionMapA[8] = {-1, t2,t3, t4, t5, t6, t7, t8};
const int8_t yConnectionMapB[8] = {-1, t9,t10,t11,t12,t13,t14,t15};
const int8_t yConnectionMapC[8] = {-1, t16,t17,t18,t19,t20,t21,t22};
const int8_t yConnectionMapD[8] = {-1, t23,t24,t25,t26,t27,t28,t29}; //make an alt_jumper version later
const int8_t yConnectionMapE[8] = {-1, b2, b3, b4, b5, b6, b7, b8};
const int8_t yConnectionMapF[8] = {-1, b9, b10,b11,b12,b13,b14,b15};
const int8_t yConnectionMapG[8] = {-1, b16,b17,b18,b19,b20,b21,b22};
const int8_t yConnectionMapH[8] = {-1, b23,b24,b25,b26,b27,b28,b29}; //make an alt_jumper version later
const int8_t yConnectionMapE[8] = {-1, 33, 34, 35, 36, 37, 38, 39}; // if you want to match them up with the schematic
const int8_t yConnectionMapF[8] = {-1, 40, 41, 42, 43, 44, 45, 46}; // use this for reference (it's the same thing as above)
const int8_t yConnectionMapG[8] = {-1, 47, 48, 49, 50, 51, 52, 53}; //
const int8_t yConnectionMapH[8] = {-1, 54, 55, 56, 57, 58, 59, 60}; //
const int8_t xConnectionMapI[16] = {NANO_A0, NANO_D1, NANO_A2, NANO_D3, NANO_A4, NANO_D5, NANO_A6, NANO_D7, NANO_D11, NANO_D9, NANO_D13, NANO_RESET, TOP_RAIL, BOTTOM_RAIL, GND, DAC0TO5V};
const int8_t xConnectionMapJ[16] = {NANO_D0, NANO_A1, NANO_D2, NANO_A3, NANO_D4, NANO_A5, NANO_D6, NANO_A7, NANO_D8, NANO_D10, NANO_D12, NANO_AREF, TOP_RAIL, BOTTOM_RAIL, GND, DACPLUSMINUS9V};
const int8_t xConnectionMapK[16] = {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};
//nanoConnectionMap[0] is the list of pin numbers, [1] and [3] are which special function chips they're connected to, [2] and [4] is the X pin on that chip, -1 for none
const char *pinNames[] ={ "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 nanoPinMap[] ={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 int8_t nanoConnectionMap[5][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},
{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 },
{0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 9 , 8 , 10 , 10 , 11 , 11 , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 },
{-1 , -1 , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , -1 , -1 , -1 , -1 , -1 , -1 , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K , CHIP_K },
{-1 , -1 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , -1 , -1 , -1 , -1 , -1 , -1 , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 }};
// so for example nanoConnectionMap
*/
#endif

460
code/jMatrixControl.cpp Normal file
View File

@ -0,0 +1,460 @@
#include "JumperlessDefines.h"
#include "jMatrixControl.h"
//This is basically copied from the old code and is working well so this can be taken for granted
jMatrixControl::jMatrixControl(void)
{
}
int jMatrixControl::connectDumbMode(int x,int y, int chip, int connectDisconnect) //overloaded to accept char, int or ascii ints as the chip selection
{
//digitalWriteFast(RESET, LOW);
char charChip = chipIntToChar(chip); //this converts the chip into a char and back to allow it to accept ascii number values and stuff
if (charChip == ' ') //if the chip sent was invalid (chipIntToChar returns a space), return 0
{
Serial.println("Bad Chip!");
return 0;
}
int intChipSanitized = chipCharToInt(charChip);
Serial.println(intChipSanitized);
setAddress(x,y);
selectChip(intChipSanitized);
strobeItIn(connectDisconnect);
deselectChip();
//Serial.printf("connected X %d to Y %d on chip %c\n\n\r", x,y,chipIntToChar(chip));
return 1;
}
int jMatrixControl::connectDumbMode(int x,int y, char chip, int connectDisconnect)
{
//digitalWriteFast(RESET, LOW);
int intChipSanitized = chipCharToInt(chip); //converts to an int and allows upper or lower case
if (intChipSanitized == -1) // returns 0 if the chip is invalid
{
Serial.println("Bad Chip!");
return 0;
}
setAddress(x,y);
selectChip(intChipSanitized);
strobeItIn(connectDisconnect);
deselectChip();
//Serial.printf("connected X %d to Y %d on chip %c\n\n\r", x,y,chipIntToChar(chip));
return 1;
}
void jMatrixControl::setAddress(int Xaddr, int Yaddr)
{
const byte MTfuckedUpTruthTable [16] = {0,1,2,3,4,5,8,9,10,11,12,13,6,7,14,15}; //apparently X12 and X13 needed to be crammed in between X5 and X6
byte XaddrFixed = MTfuckedUpTruthTable[Xaddr];
digitalWrite(AX3, LOW);
digitalWrite(AX2, LOW);
digitalWrite(AX1, LOW);
digitalWrite(AX0, LOW);
digitalWrite(AY2, LOW);
digitalWrite(AY1, LOW);
digitalWrite(AY0, LOW);
delayMicroseconds(310);
int tempAX3 = (XaddrFixed & B00001000);
tempAX3 = tempAX3 >> 3;
int tempAX2 = (XaddrFixed & B00000100);
tempAX2 = tempAX2 >> 2;
int tempAX1 = (XaddrFixed & B00000010);
tempAX1 = tempAX1 >> 1;
int tempAX0 = (XaddrFixed & B00000001);
digitalWrite(AX3, tempAX3); //this only writes the line high if that bit is set in binary value of Xaddr
digitalWrite(AX2, tempAX2); //for example Xaddr = 6 or B00000110 //note: && is logical AND, and & is bitwise AND
digitalWrite(AX1, tempAX1); //this bitwise ANDs Xaddr and a binary value with just one bit set
digitalWrite(AX0, tempAX0); //so we get Xaddr 00000110
/*
Serial.print ("X ");
Serial.print (tempAX3);
Serial.print (tempAX2);
Serial.print (tempAX1);
Serial.println (tempAX0);
*/
int tempAY2 = Yaddr & B00000100;
tempAY2 = tempAY2 >> 2;
int tempAY1 = Yaddr & B00000010;
tempAY1 = tempAY1 >> 1;
int tempAY0 = Yaddr & B00000001;
// AND bit selector 00001000 = 0
digitalWrite(AY2, tempAY2); //then we AND that again with HIGH (which is just interpreted as 1)
digitalWrite(AY1, tempAY1); //to get 1(HIGH) && 0(the result from above) = 0 (which is LOW)
digitalWrite(AY0, tempAY0); //we do that for each bit to end up with the address lines LLLLLHHL
/*
Serial.print ("\nY ");
Serial.print (tempAY2);
Serial.print (tempAY1);
Serial.println (tempAY0);
*/
delayMicroseconds(925);
}
void jMatrixControl::strobeItIn(int connectDisconnect)
{
if (connectDisconnect == 0)
{
digitalWrite(DATAPIN, LOW);
}
else
{
digitalWrite(DATAPIN, HIGH);
}
//pinMode(STROBE, OUTPUT);
//delayMicroseconds(2); //Hold time in the datasheet for the MT8816 says this only needs to be 10 nanoseconds
digitalWrite(STROBE, HIGH); //but we're not super concerned with speed so I'll give it 1000X more just to be safe
delayMicroseconds(250); //Strobe has to be a minimum of 20 nanoseconds, but I dont want to think about the
//Serial.println("!!!!!!!!!!!!");
digitalWrite(STROBE, LOW); //fact that light only travels like 4 meters in that time through copper
//pinMode(STROBE, OUTPUT);
delayMicroseconds(250);
digitalWrite(DATAPIN, LOW);
//delayMicroseconds(30);
}
int jMatrixControl::selectChip(int chipInt)
{ //asserts whichever chip select line we send it
digitalWrite(CS_A, LOW); //Chip Selects are Active High on the MT8816
digitalWrite(CS_B, LOW); //make sure they're all deselected first
digitalWrite(CS_C, LOW);
digitalWrite(CS_D, LOW);
digitalWrite(CS_E, LOW);
digitalWrite(CS_F, LOW);
digitalWrite(CS_G, LOW);
digitalWrite(CS_H, LOW);
digitalWrite(CS_I, LOW);
digitalWrite(CS_J, LOW);
digitalWrite(CS_K, LOW);
delayMicroseconds(200);
//Serial.print(chipToChar(chip));
switch(chipInt)
{
case 0:
digitalWrite(CS_A, HIGH);
return 1;
break;
case 1:
digitalWrite(CS_B, HIGH);
return 1;
break;
case 2:
digitalWrite(CS_C, HIGH);
return 1;
break;
case 3:
digitalWrite(CS_D, HIGH);
return 1;
break;
case 4:
digitalWrite(CS_E, HIGH);
return 1;
break;
case 5:
digitalWrite(CS_F, HIGH);
return 1;
break;
case 6:
digitalWrite(CS_G, HIGH);
return 1;
break;
case 7:
digitalWrite(CS_H, HIGH);
return 1;
break;
case 8:
digitalWrite(CS_I, HIGH);
return 1;
break;
case 9:
digitalWrite(CS_J, HIGH);
return 1;
break;
case 10:
digitalWrite(CS_K, HIGH);
return 1;
break;
default:
return 0;
}
}
void jMatrixControl::deselectChip(void)
{ //this should be fairly obvious
digitalWrite(CS_A, LOW);
digitalWrite(CS_B, LOW);
digitalWrite(CS_C, LOW);
digitalWrite(CS_D, LOW);
digitalWrite(CS_E, LOW);
digitalWrite(CS_F, LOW);
digitalWrite(CS_G, LOW);
digitalWrite(CS_H, LOW);
digitalWrite(CS_I, LOW);
digitalWrite(CS_J, LOW);
digitalWrite(CS_K, LOW);
digitalWrite(AX3, LOW);
digitalWrite(AX2, LOW);
digitalWrite(AX1, LOW);
digitalWrite(AX0, LOW);
digitalWrite(AY2, LOW);
digitalWrite(AY1, LOW);
digitalWrite(AY0, LOW);
digitalWrite(DATAPIN, LOW);
digitalWrite(STROBE, LOW);
digitalWriteFast(RESET, LOW);
return;
}
void jMatrixControl::clearAllConnections(void)
{ //when you send a reset pulse, all previous connections are cleared on whichever chip is CS_ed but we'll do both for now
/*
digitalWriteFast(CS_A, HIGH);
digitalWriteFast(CS_B, HIGH);
digitalWriteFast(CS_C, HIGH);
digitalWriteFast(CS_D, HIGH);
digitalWriteFast(CS_E, HIGH);
digitalWriteFast(CS_F, HIGH);
digitalWriteFast(CS_G, HIGH);
digitalWriteFast(CS_H, HIGH);
digitalWriteFast(CS_I, HIGH);
digitalWriteFast(CS_J, HIGH);
digitalWriteFast(CS_K, HIGH);
*/
digitalWriteFast(RESET, HIGH);
delayMicroseconds(2000); //datasheet says 40 nanoseconds minimum, this is a lot more than that
digitalWriteFast(RESET, LOW);
delayMicroseconds(925);
digitalWriteFast(CS_A, LOW);
digitalWriteFast(CS_B, LOW);
digitalWriteFast(CS_C, LOW);
digitalWriteFast(CS_D, LOW);
digitalWriteFast(CS_E, LOW);
digitalWriteFast(CS_F, LOW);
digitalWriteFast(CS_G, LOW);
digitalWriteFast(CS_H, LOW);
digitalWriteFast(CS_I, LOW);
digitalWriteFast(CS_J, LOW);
digitalWriteFast(CS_K, LOW);
}
char jMatrixControl::chipIntToChar(int chipInt)//also accepts the raw ascii values (65=A, 97=a, 66=B, 98=b...)
{
switch (chipInt)
{
case 0: //fall through
case 65:
case 97:
return 'A';
break;
case 1:
case 66:
case 98:
return 'B';
break;
case 2:
case 67:
case 99:
return 'C';
break;
case 3:
case 68:
case 100:
return 'D';
break;
case 4:
case 69:
case 101:
return 'E';
break;
case 5:
case 70:
case 102:
return 'F';
break;
case 6:
case 71:
case 103:
return 'G';
break;
case 7:
case 72:
case 104:
return 'H';
break;
case 8:
case 73:
case 105:
return 'I';
break;
case 9:
case 74:
case 106:
return 'J';
break;
case 10:
case 75:
case 107:
return 'K';
break;
default:
return ' ';
}
}
int jMatrixControl::chipCharToInt(char chipChar)
{
switch (chipChar)
{
case 'A':
case 'a':
return 0;
break;
case 'B':
case 'b':
return 1;
break;
case 'C':
case 'c':
return 2;
break;
case 'D':
case 'd':
return 3;
break;
case 'E':
case 'e':
return 4;
break;
case 'F':
case 'f':
return 5;
break;
case 'G':
case 'g':
return 6;
break;
case 'H':
case 'h':
return 7;
break;
case 'I':
case 'i':
return 8;
break;
case 'J':
case 'j':
return 9;
break;
case 'K':
case 'k':
return 10;
break;
default:
return -1;
}
}
int8_t bottomRowTranslation (int8_t rowToTranslate)
{
if(rowToTranslate <= 30)
{
return rowToTranslate + 31;
} else if (rowToTranslate > 30 && rowToTranslate <= 60){
return rowToTranslate - 31;
} else {
Serial.println("Invalid Row!");
return -1;
}
}

29
code/jMatrixControl.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef JMATRIXCONTROL_H // so this doesnt get defined twice
#define JMATRIXCONTROL_H
#include <Arduino.h> //move this eventually
class jMatrixControl{
public:
jMatrixControl();
int connectDumbMode(int x,int y, int chip, int connectDisconnect = 1); //X address, Y Address, Chip (Char,Int, or Int ascii), connect (1) or disconnect (0)
int connectDumbMode(int x,int y, char chip, int connectDisconnect = 1); //X address, Y Address, Chip (Char,Int, or Int ascii), connect (1) or disconnect (0)
void clearAllConnections(void);
char chipIntToChar(int chipChar); //returns ' ' (space) if invalid
int chipCharToInt(char); //returns -1 if invalid
int8_t bottomRowTranslation (int8_t rowToTranslate);//returns -1 if invalid - works both ways
private:
void setAddress(int, int);
void strobeItIn(int connectDisconnect);
int selectChip(int); //returns 1 if it's a valid chip number
void deselectChip(void);
};
#endif