mirror of
https://github.com/Architeuthis-Flux/Jumperless.git
synced 2025-02-16 02:32:34 +01:00
642 lines
13 KiB
C++
642 lines
13 KiB
C++
// SPDX-License-Identifier: MIT
|
|
|
|
#include "CH446Q.h"
|
|
#include "MatrixStateRP2040.h"
|
|
#include "NetsToChipConnections.h"
|
|
#include "LEDs.h"
|
|
#include "Peripherals.h"
|
|
#include "JumperlessDefinesRP2040.h"
|
|
|
|
#include "hardware/pio.h"
|
|
|
|
#include "spi.pio.h"
|
|
#include "pio_spi.h"
|
|
|
|
#define MYNAMEISERIC 0 // on the board I sent to eric, the data and clock lines are bodged to GPIO 18 and 19. To allow for using hardware SPI
|
|
|
|
int chipToPinArray[12] = {CS_A, CS_B, CS_C, CS_D, CS_E, CS_F, CS_G, CS_H, CS_I, CS_J, CS_K, CS_L};
|
|
PIO pio = pio0;
|
|
|
|
uint sm = pio_claim_unused_sm(pio, true);
|
|
|
|
volatile int chipSelect = 0;
|
|
volatile uint32_t irq_flags = 0;
|
|
|
|
void isrFromPio(void)
|
|
{
|
|
switch (chipSelect)
|
|
{
|
|
case CHIP_A:
|
|
{
|
|
digitalWriteFast(CS_A, HIGH);
|
|
break;
|
|
}
|
|
case CHIP_B:
|
|
{
|
|
digitalWriteFast(CS_B, HIGH);
|
|
break;
|
|
}
|
|
case CHIP_C:
|
|
{
|
|
digitalWriteFast(CS_C, HIGH);
|
|
break;
|
|
}
|
|
case CHIP_D:
|
|
{
|
|
digitalWriteFast(CS_D, HIGH);
|
|
break;
|
|
}
|
|
case CHIP_E:
|
|
{
|
|
digitalWriteFast(CS_E, HIGH);
|
|
break;
|
|
}
|
|
case CHIP_F:
|
|
{
|
|
digitalWriteFast(CS_F, HIGH);
|
|
break;
|
|
}
|
|
case CHIP_G:
|
|
{
|
|
digitalWriteFast(CS_G, HIGH);
|
|
break;
|
|
}
|
|
case CHIP_H:
|
|
{
|
|
digitalWriteFast(CS_H, HIGH);
|
|
break;
|
|
}
|
|
case CHIP_I:
|
|
{
|
|
digitalWriteFast(CS_I, HIGH);
|
|
break;
|
|
}
|
|
case CHIP_J:
|
|
{
|
|
digitalWriteFast(CS_J, HIGH);
|
|
break;
|
|
}
|
|
case CHIP_K:
|
|
{
|
|
digitalWriteFast(CS_K, HIGH);
|
|
break;
|
|
}
|
|
case CHIP_L:
|
|
{
|
|
digitalWriteFast(CS_L, HIGH);
|
|
break;
|
|
}
|
|
}
|
|
|
|
delayMicroseconds(2);
|
|
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);
|
|
digitalWriteFast(CS_L, LOW);
|
|
delayMicroseconds(1);
|
|
irq_flags = pio0_hw->irq;
|
|
pio_interrupt_clear(pio, PIO0_IRQ_0);
|
|
hw_clear_bits(&pio0_hw->irq, irq_flags);
|
|
}
|
|
|
|
void initCH446Q(void)
|
|
{
|
|
|
|
uint dat = 14;
|
|
uint clk = 15;
|
|
|
|
if (MYNAMEISERIC)
|
|
{
|
|
dat = 18;
|
|
clk = 19;
|
|
}
|
|
|
|
uint cs = 7;
|
|
|
|
irq_add_shared_handler(PIO0_IRQ_0, isrFromPio, PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY);
|
|
irq_set_enabled(PIO0_IRQ_0, true);
|
|
|
|
uint offset = pio_add_program(pio, &spi_ch446_multi_cs_program);
|
|
// uint offsetCS = pio_add_program(pio, &spi_ch446_cs_handler_program);
|
|
|
|
Serial.print("offset: ");
|
|
Serial.println(offset);
|
|
|
|
pio_spi_ch446_multi_cs_init(pio, sm, offset, 8, 16, 0, 1, clk, dat);
|
|
// pio_spi_ch446_cs_handler_init(pio, smCS, offsetCS, 256, 1, 8, 20, 6);
|
|
// pinMode(CS_A, OUTPUT);
|
|
// digitalWrite(CS_A, HIGH);
|
|
|
|
pinMode(CS_A, OUTPUT);
|
|
pinMode(CS_B, OUTPUT);
|
|
pinMode(CS_C, OUTPUT);
|
|
pinMode(CS_D, OUTPUT);
|
|
pinMode(CS_E, OUTPUT);
|
|
pinMode(CS_F, OUTPUT);
|
|
pinMode(CS_G, OUTPUT);
|
|
pinMode(CS_H, OUTPUT);
|
|
pinMode(CS_I, OUTPUT);
|
|
pinMode(CS_J, OUTPUT);
|
|
pinMode(CS_K, OUTPUT);
|
|
pinMode(CS_L, OUTPUT);
|
|
|
|
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(CS_L, LOW);
|
|
|
|
pinMode(RESETPIN, OUTPUT);
|
|
|
|
digitalWrite(RESETPIN, HIGH);
|
|
delay(2);
|
|
digitalWrite(RESETPIN, LOW);
|
|
}
|
|
|
|
void resetArduino(void)
|
|
{
|
|
int lastPath = MAX_BRIDGES - 1;
|
|
path[lastPath].chip[0] = CHIP_I;
|
|
path[lastPath].chip[1] = CHIP_I;
|
|
path[lastPath].x[0] = 11;
|
|
path[lastPath].y[0] = 0;
|
|
path[lastPath].x[1] = 15;
|
|
path[lastPath].y[1] = 0;
|
|
|
|
sendPath(lastPath, 1);
|
|
delay(15);
|
|
sendPath(lastPath, 0);
|
|
}
|
|
void sendAllPaths(void) // should we sort them by chip? for now, no
|
|
{
|
|
|
|
for (int i = 0; i < numberOfPaths; i++)
|
|
{
|
|
|
|
if (path[i].skip == true)
|
|
{
|
|
continue;
|
|
}
|
|
sendPath(i, 1);
|
|
if (debugNTCC)
|
|
{
|
|
Serial.print("path ");
|
|
Serial.print(i);
|
|
Serial.print(" \t");
|
|
printPathType(i);
|
|
Serial.print(" \n\r");
|
|
for (int j = 0; j < 4; j++)
|
|
{
|
|
printChipNumToChar(path[i].chip[j]);
|
|
Serial.print(" x[");
|
|
Serial.print(j);
|
|
Serial.print("]:");
|
|
Serial.print(path[i].x[j]);
|
|
Serial.print(" y[");
|
|
Serial.print(j);
|
|
Serial.print("]:");
|
|
Serial.print(path[i].y[j]);
|
|
Serial.print(" \t ");
|
|
}
|
|
Serial.print("\n\n\r");
|
|
}
|
|
}
|
|
}
|
|
|
|
void sendXYraw(int chip, int x, int y, int setOrClear)
|
|
{
|
|
uint32_t chAddress = 0;
|
|
chipSelect = chip;
|
|
|
|
int chYdata = y;
|
|
int chXdata = x;
|
|
|
|
chYdata = chYdata << 5;
|
|
chYdata = chYdata & 0b11100000;
|
|
|
|
chXdata = chXdata << 1;
|
|
chXdata = chXdata & 0b00011110;
|
|
|
|
chAddress = chYdata | chXdata;
|
|
|
|
if (setOrClear == 1)
|
|
{
|
|
chAddress = chAddress | 0b00000001; // this last bit determines whether we set or unset the path
|
|
}
|
|
|
|
chAddress = chAddress << 24;
|
|
|
|
delayMicroseconds(20);
|
|
|
|
pio_sm_put(pio, sm, chAddress);
|
|
|
|
delayMicroseconds(40);
|
|
}
|
|
|
|
int probeHalfPeriodus = 10;
|
|
|
|
int readFloatingOrState(int pin, int rowBeingScanned)
|
|
{
|
|
|
|
enum measuredState state = floating;
|
|
int readingPullup = 0;
|
|
int readingPullup2 = 0;
|
|
int readingPullup3 = 0;
|
|
|
|
int readingPulldown = 0;
|
|
int readingPulldown2 = 0;
|
|
int readingPulldown3 = 0;
|
|
|
|
pinMode(pin, INPUT_PULLUP);
|
|
|
|
delayMicroseconds(100);
|
|
|
|
readingPullup = digitalRead(pin);
|
|
delayMicroseconds(probeHalfPeriodus);
|
|
readingPullup2 = digitalRead(pin);
|
|
delayMicroseconds(probeHalfPeriodus / 2);
|
|
readingPullup3 = digitalRead(pin);
|
|
|
|
pinMode(pin, INPUT_PULLDOWN);
|
|
delayMicroseconds(100);
|
|
|
|
readingPulldown = digitalRead(pin);
|
|
delayMicroseconds(probeHalfPeriodus);
|
|
readingPulldown2 = digitalRead(pin);
|
|
delayMicroseconds(probeHalfPeriodus / 2);
|
|
readingPulldown3 = digitalRead(pin);
|
|
|
|
if (readingPullup != readingPullup2 || readingPullup2 != readingPullup3 && rowBeingScanned != -1)
|
|
{
|
|
if (readingPulldown != readingPulldown2 || readingPulldown2 != readingPulldown3)
|
|
{
|
|
state = probe;
|
|
|
|
// leds.setPixelColor(nodesToPixelMap[rowBeingScanned], rainbowList[rainbowIndex][0], rainbowList[rainbowIndex][1], rainbowList[rainbowIndex][2]);
|
|
|
|
// Serial.print("probe");
|
|
//
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
// Serial.print(readingPulldown);
|
|
// Serial.print("\t");
|
|
if (readingPullup == 1 && readingPulldown == 0)
|
|
{
|
|
// Serial.print("floating");
|
|
// leds.setPixelColor(nodesToPixelMap[rowBeingScanned], 0, 0, 3);
|
|
state = floating;
|
|
}
|
|
else if (readingPullup == 1 && readingPulldown == 1)
|
|
{
|
|
// Serial.print("HIGH");
|
|
// leds.setPixelColor(nodesToPixelMap[rowBeingScanned], 45, 0, 0);
|
|
state = high;
|
|
}
|
|
else if (readingPullup == 0 && readingPulldown == 0)
|
|
{
|
|
// Serial.print("LOW");
|
|
// leds.setPixelColor(nodesToPixelMap[rowBeingScanned], 0, 45, 0);
|
|
state = low;
|
|
}
|
|
else if (readingPullup == 0 && readingPulldown == 1)
|
|
{
|
|
// Serial.print("shorted");
|
|
}
|
|
}
|
|
// Serial.print("\n");
|
|
leds.show();
|
|
// delayMicroseconds(100);
|
|
|
|
return state;
|
|
}
|
|
|
|
void startProbe(int probeSpeed)
|
|
{
|
|
probeHalfPeriodus = 1000000 / probeSpeed / 2;
|
|
pinMode(19, OUTPUT);
|
|
analogWriteFreq(probeSpeed);
|
|
analogWrite(19, 128);
|
|
// delayMicroseconds(10);
|
|
pinMode(18, INPUT);
|
|
}
|
|
|
|
int rainbowList[12][3] = {
|
|
{45, 35, 8},
|
|
{10, 45, 30},
|
|
{30, 15, 45},
|
|
{8, 27, 45},
|
|
{45, 18, 19},
|
|
{35, 42, 5},
|
|
{02, 45, 35},
|
|
{18, 25, 45},
|
|
{40, 12, 45},
|
|
{10, 32, 45},
|
|
{18, 5, 43},
|
|
{45, 28, 13}};
|
|
int rainbowIndex = 0;
|
|
int lastFound[5] = {-1, -1, -1, -1, -1};
|
|
int nextIsSupply = 0;
|
|
int nextIsGnd = 0;
|
|
int justCleared = 1;
|
|
|
|
int scanRows(int pin, bool clearLastFound)
|
|
{
|
|
|
|
int found = -1;
|
|
|
|
if (clearLastFound)
|
|
{
|
|
// for (int i = 0; i < 5; i++)
|
|
// {
|
|
// lastFound[i] = -1;
|
|
// }
|
|
|
|
|
|
rainbowIndex++;
|
|
if (rainbowIndex > 11)
|
|
{
|
|
rainbowIndex = 0;
|
|
}
|
|
|
|
justCleared = 1;
|
|
nextIsGnd = 0;
|
|
nextIsSupply = 0;
|
|
return -1;
|
|
}
|
|
|
|
digitalWrite(RESETPIN, HIGH);
|
|
delayMicroseconds(10);
|
|
digitalWrite(RESETPIN, LOW);
|
|
startProbe();
|
|
int chipToConnect = 0;
|
|
int rowBeingScanned = 0;
|
|
|
|
int xMapRead = 15;
|
|
|
|
if (pin == ADC0_PIN)
|
|
{
|
|
xMapRead = 2;
|
|
}
|
|
else if (pin == ADC1_PIN)
|
|
{
|
|
xMapRead = 3;
|
|
}
|
|
else if (pin == ADC2_PIN)
|
|
{
|
|
xMapRead = 4;
|
|
}
|
|
else if (pin == ADC3_PIN)
|
|
{
|
|
xMapRead = 5;
|
|
}
|
|
|
|
// Serial.print("xMapRead: ");
|
|
// Serial.println(xMapRead);
|
|
|
|
pinMode(pin, INPUT);
|
|
for (int chipScan = CHIP_A; chipScan < 8; chipScan++)
|
|
{
|
|
|
|
sendXYraw(CHIP_L, xMapRead, chipScan, 1);
|
|
|
|
for (int yToScan = 1; yToScan < 8; yToScan++)
|
|
{
|
|
|
|
sendXYraw(chipScan, 0, 0, 1);
|
|
sendXYraw(chipScan, 0, yToScan, 1);
|
|
|
|
// analogRead(ADC0_PIN);
|
|
|
|
rowBeingScanned = ch[chipScan].yMap[yToScan];
|
|
if (readFloatingOrState(pin, rowBeingScanned) == probe && rowBeingScanned != lastFound[0])
|
|
{
|
|
found = rowBeingScanned;
|
|
if (nextIsSupply)
|
|
{
|
|
leds.setPixelColor(nodesToPixelMap[rowBeingScanned], 65, 10, 10);
|
|
}
|
|
else if (nextIsGnd)
|
|
{
|
|
leds.setPixelColor(nodesToPixelMap[rowBeingScanned], 10, 65, 10);
|
|
}
|
|
else
|
|
{
|
|
leds.setPixelColor(nodesToPixelMap[rowBeingScanned], rainbowList[rainbowIndex][0], rainbowList[rainbowIndex][1], rainbowList[rainbowIndex][2]);
|
|
}
|
|
|
|
leds.show();
|
|
for (int i = 4; i > 0; i--)
|
|
{
|
|
lastFound[i] = lastFound[i - 1];
|
|
}
|
|
lastFound[0] = found;
|
|
}
|
|
|
|
sendXYraw(chipScan, 0, 0, 0);
|
|
sendXYraw(chipScan, 0, yToScan, 0);
|
|
|
|
if (found != -1)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
sendXYraw(CHIP_L, 2, chipScan, 0);
|
|
|
|
|
|
}
|
|
|
|
int corners[4] = {1, 30, 31, 60};
|
|
sendXYraw(CHIP_L, xMapRead, 0, 1);
|
|
for (int cornerScan = 0; cornerScan < 4; cornerScan++)
|
|
{
|
|
|
|
sendXYraw(CHIP_L, cornerScan + 8, 0, 1);
|
|
|
|
// analogRead(ADC0_PIN);
|
|
|
|
rowBeingScanned = corners[cornerScan];
|
|
if (readFloatingOrState(pin, rowBeingScanned) == probe && rowBeingScanned != lastFound[0])
|
|
{
|
|
found = rowBeingScanned;
|
|
if (nextIsSupply)
|
|
{
|
|
leds.setPixelColor(nodesToPixelMap[rowBeingScanned], 65, 10, 10);
|
|
}
|
|
else if (nextIsGnd)
|
|
{
|
|
leds.setPixelColor(nodesToPixelMap[rowBeingScanned], 10, 65, 10);
|
|
}
|
|
else
|
|
{
|
|
leds.setPixelColor(nodesToPixelMap[rowBeingScanned], rainbowList[rainbowIndex][0], rainbowList[rainbowIndex][1], rainbowList[rainbowIndex][2]);
|
|
}
|
|
leds.show();
|
|
for (int i = 4; i > 0; i--)
|
|
{
|
|
lastFound[i] = lastFound[i - 1];
|
|
}
|
|
lastFound[0] = found;
|
|
}
|
|
|
|
sendXYraw(CHIP_L, cornerScan + 8, 0, 0);
|
|
|
|
if (found != -1)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
sendXYraw(CHIP_L, xMapRead, 0, 0);
|
|
|
|
int gp18read = readFloatingOrState(18, -1);
|
|
|
|
if (gp18read == probe)
|
|
{
|
|
delayMicroseconds(1000);
|
|
if (readFloatingOrState(18, -1) == probe)
|
|
{
|
|
return -18;
|
|
}
|
|
|
|
}
|
|
|
|
pinMode(19, INPUT);
|
|
delayMicroseconds(900);
|
|
int probeRead = readFloatingOrState(19, -1);
|
|
|
|
if (probeRead == high && ((lastFound[0] != SUPPLY_3V3 )))
|
|
{
|
|
found = SUPPLY_3V3;
|
|
if (justCleared)
|
|
{
|
|
nextIsSupply = 1;
|
|
//justCleared = 0;
|
|
}
|
|
else
|
|
{
|
|
leds.setPixelColor(nodesToPixelMap[lastFound[0]], 65, 10, 10);
|
|
nextIsSupply = 0;
|
|
}
|
|
|
|
for (int i = 4; i > 0; i--)
|
|
{
|
|
lastFound[i] = lastFound[i - 1];
|
|
}
|
|
lastFound[0] = found;
|
|
}
|
|
else if (probeRead == low && ((lastFound[0] != GND )))
|
|
{
|
|
found = GND;
|
|
if (justCleared)
|
|
{
|
|
// leds.setPixelColor(nodesToPixelMap[lastFound[0]], 0, 0, 0);
|
|
nextIsGnd = 1;
|
|
//justCleared = 0;
|
|
}
|
|
else
|
|
{
|
|
leds.setPixelColor(nodesToPixelMap[lastFound[0]], 10, 65, 10);
|
|
nextIsGnd = 0;
|
|
}
|
|
|
|
for (int i = 4; i > 0; i--)
|
|
{
|
|
lastFound[i] = lastFound[i - 1];
|
|
}
|
|
lastFound[0] = found;
|
|
}
|
|
|
|
if (justCleared && found != -1)
|
|
{
|
|
// Serial.print("\n\rjustCleared: ");
|
|
// Serial.println(justCleared);
|
|
// Serial.print("nextIsSupply: ");
|
|
// Serial.println(nextIsSupply);
|
|
// Serial.print("nextIsGnd: ");
|
|
// Serial.println(nextIsGnd);
|
|
|
|
justCleared = 0;
|
|
}
|
|
|
|
return found;
|
|
|
|
// return 0;
|
|
}
|
|
|
|
void sendPath(int i, int setOrClear)
|
|
{
|
|
|
|
uint32_t chAddress = 0;
|
|
|
|
int chipToConnect = 0;
|
|
int chYdata = 0;
|
|
int chXdata = 0;
|
|
|
|
for (int chip = 0; chip < 4; chip++)
|
|
{
|
|
if (path[i].chip[chip] != -1)
|
|
{
|
|
chipSelect = path[i].chip[chip];
|
|
|
|
chipToConnect = path[i].chip[chip];
|
|
|
|
if (path[i].y[chip] == -1 || path[i].x[chip] == -1)
|
|
{
|
|
if (debugNTCC)
|
|
Serial.print("!");
|
|
|
|
continue;
|
|
}
|
|
|
|
chYdata = path[i].y[chip];
|
|
chXdata = path[i].x[chip];
|
|
|
|
chYdata = chYdata << 5;
|
|
chYdata = chYdata & 0b11100000;
|
|
|
|
chXdata = chXdata << 1;
|
|
chXdata = chXdata & 0b00011110;
|
|
|
|
chAddress = chYdata | chXdata;
|
|
|
|
if (setOrClear == 1)
|
|
{
|
|
chAddress = chAddress | 0b00000001; // this last bit determines whether we set or unset the path
|
|
}
|
|
|
|
chAddress = chAddress << 24;
|
|
|
|
// delayMicroseconds(50);
|
|
|
|
delayMicroseconds(20);
|
|
|
|
pio_sm_put(pio, sm, chAddress);
|
|
|
|
delayMicroseconds(40);
|
|
//}
|
|
}
|
|
}
|
|
}
|
|
|
|
void createXYarray(void)
|
|
{
|
|
}
|