Files
xserve-io/all-functions/all-functions.ino
2024-07-07 23:47:23 +02:00

331 lines
7.6 KiB
C++

#include "Wire.h"
#include <PCA9554.h> // Load the PCA9554 Library
#define TCAADDR 0x70
// byte saa1064 = 0x3B;
PCA9554 ioCon1(0x24); // Create an object at this address
// LEDs have two addresses, one for RED another for GREEN
bool fanGreenLED;
bool fanRedLED;
bool tempGreenLED;
bool tempRedLED;
bool powerGreenLED;
bool powerRedLED;
bool modeSelect;
bool nic1State = 0;
bool nic2State = 0;
bool lockButtonState = 1;
bool modeButtonState = 1;
int powerState = 0;
// first bit is current value, second bit is alarm state
int fanState[2] = {0, 0};
int tempState[2] = {0, 0};
byte centerColumnsMemoryMap[2][4] = {
{0b00000000, 0b00000000, 0b00000000, 0b00000000}, // left column
{0b00000000, 0b00000000, 0b00000000, 0b00000000} // right column
};
byte ioHash = 0;
// --- ADDRESS MAPs ---
int IOMapLength = 8;
bool* mapIO[8] = {&powerGreenLED, &powerRedLED, &fanGreenLED, &fanRedLED, &tempGreenLED, &tempRedLED, &lockButtonState, &modeSelect};
// bool mapNics[3] = {nic1State, nic2State};
// --- PIN DEFINITIONS ---
int POWER_FAIL_PIN = 8;
int FAN_PIN = 9;
int POWER_PIN = 12;
int NIC_1_PIN = 10;
int NIC_2_PIN = 11;
int BUTTON_LOCK_PIN = A3;
int BUTTON_MODE_PIN = A2;
unsigned long lastDebounceTimeLock = 0;
unsigned long lastDebounceTimeMode = 0;
const int DEBOUNCE_DELAY = 30;
unsigned long lastUpdateIO = 0;
const int IO_UPDATE_INTERVAL = 200;
void setup() {
Serial.begin(9600);
// Serial.println(mapIO[0]);
pinMode(POWER_FAIL_PIN, INPUT);
pinMode(FAN_PIN, INPUT);
pinMode(NIC_1_PIN, INPUT);
pinMode(NIC_2_PIN, INPUT);
pinMode(POWER_PIN, INPUT);
pinMode(BUTTON_LOCK_PIN, INPUT_PULLUP);
pinMode(BUTTON_MODE_PIN, INPUT_PULLUP);
Serial.println("setup all pinouts");
Wire.begin(); // start up I2C bus
Serial.println("i2c setup");
ioCon1.portMode(ALLOUTPUT);
Serial.println("iocon1 setup");
delay(500);
selectRightHalf();
lightUpIO();
selectLeftHalf();
lightUpIO();
}
void lightUpIO() {
Serial.println("ligthing up top io");
for (int i = 0; i < IOMapLength; ++i) {
ioCon1.digitalWrite(i, mapIO[i]);
}
Serial.println("finished ligthing up top io");
}
unsigned long currentTime = millis();
void updateTime() {
currentTime = millis();
}
int fanBlinkCounter = 0;
unsigned long fanToggledAt;
void updateFanState(int state) {
// fan changed and did so within 1 second
bool stateChanged = state != fanState[0];
fanState[0] = state;
// detect that blinking is happening
if (stateChanged && (currentTime - fanToggledAt > 250)) {
fanState[1] = 1;
fanToggledAt = currentTime;
}
// detect that blinking stopped
// if alarm && it changes && it has been more then 2 times the frex since last toggle
if (fanState[1] == 1 && (currentTime > fanToggledAt + 1000)) {
// nothing to see here
fanState[1] = 0;
}
}
unsigned long tempToggledAt;
void updateTempState(int state) {
bool stateChanged = state != tempState[0];
tempState[0] = state;
// was 2 seconds ago last time it toggled
if (stateChanged == 1 && (currentTime - tempToggledAt > 250)) {
tempState[1] = 1;
tempToggledAt = currentTime;
}
// detect that blinking stopped
// if alarm && it changes && it has been more then 2 times the frex since last toggle
if (tempState[1] == 1 && (currentTime > tempToggledAt + 1000)) {
// nothing to see here
tempState[1] = 0;
}
}
// TODO check that this goes RED when off
void greenRed(bool* greenLED, bool* redLED, bool value) {
// if no power set red led
if (value == 0) {
*greenLED = 0;
*redLED = 1;
// else if power set green led
} else {
*greenLED = 1;
*redLED = 0;
}
}
void greenRedOnAlarm(bool* greedLED, bool* redLED, bool alarm) {
// if not alarm set green led
if (alarm == 0) {
*greedLED = 1;
*redLED = 0;
// if alarm set red led
} else {
*greedLED = 0;
*redLED = 1;
}
}
void greenRedBlinkOnAlarm(bool* greenLED, bool* redLED, bool value, bool alarm) {
// void greenRedBlinkOnAlarm(bool* greenLED, bool* redLED, bool* currentState, bool* alarmState) {
// if no alarm --> set green led
if (alarm == 0) {
*greenLED = 1;
*redLED = 0;
return;
}
// everything below assumes alarm state
// alarm and signal --> red led (blink on)
if (value == 0) {
*greenLED = 0;
*redLED = 1;
}
// alarm and no signal --> no led (blink off)
else {
*greenLED = 0;
*redLED = 0;
}
}
void writeIOLEDPoweredOff() {
ioCon1.digitalWrite(0, HIGH);
ioCon1.digitalWrite(1, LOW);
ioCon1.digitalWrite(2, HIGH);
ioCon1.digitalWrite(3, HIGH);
ioCon1.digitalWrite(4, HIGH);
ioCon1.digitalWrite(5, HIGH);
ioCon1.digitalWrite(6, *(mapIO[6]) == 1 ? 0 : 1);
}
void updateIOLED() {
if (powerState == 0) {
writeIOLEDPoweredOff();
return;
}
for (int i = 0; i < IOMapLength; ++i) {
ioCon1.digitalWrite(i, *(mapIO[i]) == 1 ? 0 : 1);
}
}
int lastIOHash = -1;
bool shouldUpdateIOLed() {
greenRedBlinkOnAlarm(&fanGreenLED, &fanRedLED, fanState[0], fanState[1]);
greenRedOnAlarm(&tempGreenLED, &tempRedLED, tempState[1]);
greenRed(&powerGreenLED, &powerRedLED, powerState);
byte ioHash = 0;
for (byte i = 0; i < IOMapLength; i++)
{
bitWrite(ioHash, i, *(mapIO[i]));
}
if (ioHash == lastIOHash) {
// Don't update i2c ctrl if same value
// Serial.println("Not updating!!");
return false;
}
// Serial.println("Updating IO!!");
lastIOHash = ioHash;
return true;
}
void updateState() {
bool fanS = digitalRead(FAN_PIN);
updateFanState(fanS);
updateTempState(fanS);
powerState = digitalRead(POWER_PIN);
nic1State = !digitalRead(NIC_1_PIN);
nic2State = !digitalRead(NIC_2_PIN);
}
bool handleButtonPress(int address, bool* value, long unsigned int* debounce) {
bool btnVal = !digitalRead(address);
if (btnVal != *value) {
*debounce = currentTime;
*value = btnVal;
}
if (*debounce > 0 && (currentTime - *debounce) > DEBOUNCE_DELAY) {
*debounce = 0;
return true;
}
return false;
}
void changeModes() {
bool btnVal = !digitalRead(BUTTON_MODE_PIN);
if (btnVal == 1) {
modeSelect = !modeSelect;
}
}
void tcaselect(uint8_t i) {
if (i > 7) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1 << i);
Wire.endTransmission();
}
void selectLeftHalf() {
tcaselect(2);
}
void selectRightHalf() {
tcaselect(1);
}
void writeEthernetActivity() {
selectLeftHalf();
resetEthernetBit(centerColumnsMemoryMap[0]);
computeEthernetActivity(centerColumnsMemoryMap[0], nic1State);
writeCenterColumnFirstBank(centerColumnsMemoryMap[0]);
delay(1);
selectRightHalf();
resetEthernetBit(centerColumnsMemoryMap[1]);
computeEthernetActivity(centerColumnsMemoryMap[1], nic2State);
writeCenterColumnFirstBank(centerColumnsMemoryMap[1]);
}
void loop() {
// Serial.println("loop start");
updateTime();
updateState();
handleButtonPress(BUTTON_LOCK_PIN, &lockButtonState, &lastDebounceTimeLock);
if (handleButtonPress(BUTTON_MODE_PIN, &modeButtonState, &lastDebounceTimeMode)) {
changeModes();
}
writeEthernetActivity();
if (shouldUpdateIOLed() == true) {
resetBanks(centerColumnsMemoryMap[0]);
selectLeftHalf();
updateIOLED();
// displayUpToNumber(21);
displayPercentage(centerColumnsMemoryMap[0], 0.91);
delay(1);
resetBanks(centerColumnsMemoryMap[1]);
selectRightHalf();
updateIOLED();
displayUpToNumber(centerColumnsMemoryMap[1], random(24));
}
// if (currentTime - lastUpdateIO > IO_UPDATE_INTERVAL) {
// lastUpdateIO = currentTime;
// updateIOLED();
// }
// selectRightHalf();
// selectLeftHalf();
// shouldUpdateIOLed
// updateRightIOLED();
delay(20);
// Serial.println("loop end");
}