2024-02-14 11:24:30 -08:00

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)
{
}