diff --git a/firmware/lib/cw-commons/CWPreferences.h b/firmware/lib/cw-commons/CWPreferences.h
index 6a464ff..fadc4ab 100644
--- a/firmware/lib/cw-commons/CWPreferences.h
+++ b/firmware/lib/cw-commons/CWPreferences.h
@@ -12,6 +12,7 @@ struct ClockwiseParams
Preferences preferences;
const char* const PREF_SWAP_BLUE_GREEN = "swapBlueGreen";
+ const char* const PREF_SWAP_BLUE_RED = "swapBlueRed";
const char* const PREF_USE_24H_FORMAT = "use24hFormat";
const char* const PREF_DISPLAY_BRIGHT = "displayBright";
const char* const PREF_DISPLAY_ABC_MIN = "autoBrightMin";
@@ -25,8 +26,12 @@ struct ClockwiseParams
const char* const PREF_CANVAS_SERVER = "canvasServer";
const char* const PREF_MANUAL_POSIX = "manualPosix";
const char* const PREF_DISPLAY_ROTATION = "displayRotation";
+ const char* const PREF_DRIVER = "driver";
+ const char* const PREF_I2CSPEED = "i2cSpeed";
+ const char* const PREF_E_PIN = "E_pin";
bool swapBlueGreen;
+ bool swapBlueRed;
bool use24hFormat;
uint8_t displayBright;
uint16_t autoBrightMin;
@@ -40,7 +45,9 @@ struct ClockwiseParams
String canvasServer;
String manualPosix;
uint8_t displayRotation;
-
+ uint8_t driver;
+ uint32_t i2cSpeed;
+ uint8_t E_pin;
ClockwiseParams() {
preferences.begin("clockwise", false);
@@ -56,6 +63,7 @@ struct ClockwiseParams
void save()
{
preferences.putBool(PREF_SWAP_BLUE_GREEN, swapBlueGreen);
+ preferences.putBool(PREF_SWAP_BLUE_RED, swapBlueRed);
preferences.putBool(PREF_USE_24H_FORMAT, use24hFormat);
preferences.putUInt(PREF_DISPLAY_BRIGHT, displayBright);
preferences.putUInt(PREF_DISPLAY_ABC_MIN, autoBrightMin);
@@ -69,11 +77,15 @@ struct ClockwiseParams
preferences.putString(PREF_CANVAS_SERVER, canvasServer);
preferences.putString(PREF_MANUAL_POSIX, manualPosix);
preferences.putUInt(PREF_DISPLAY_ROTATION, displayRotation);
+ preferences.putUInt(PREF_DRIVER, driver);
+ preferences.putUInt(PREF_I2CSPEED, i2cSpeed);
+ preferences.putUInt(PREF_E_PIN, E_pin);
}
void load()
{
swapBlueGreen = preferences.getBool(PREF_SWAP_BLUE_GREEN, false);
+ swapBlueRed = preferences.getBool(PREF_SWAP_BLUE_RED, false);
use24hFormat = preferences.getBool(PREF_USE_24H_FORMAT, true);
displayBright = preferences.getUInt(PREF_DISPLAY_BRIGHT, 32);
autoBrightMin = preferences.getUInt(PREF_DISPLAY_ABC_MIN, 0);
@@ -87,6 +99,9 @@ struct ClockwiseParams
canvasServer = preferences.getString(PREF_CANVAS_SERVER, "raw.githubusercontent.com");
manualPosix = preferences.getString(PREF_MANUAL_POSIX, "");
displayRotation = preferences.getUInt(PREF_DISPLAY_ROTATION, 0);
+ driver = preferences.getUInt(PREF_DRIVER, 0);
+ i2cSpeed = preferences.getUInt(PREF_I2CSPEED, (uint32_t)8000000);
+ E_pin = preferences.getUInt(PREF_E_PIN, 18);
}
};
diff --git a/firmware/lib/cw-commons/CWWebServer.h b/firmware/lib/cw-commons/CWWebServer.h
index 8eebdee..fa80bc0 100644
--- a/firmware/lib/cw-commons/CWWebServer.h
+++ b/firmware/lib/cw-commons/CWWebServer.h
@@ -111,6 +111,8 @@ struct ClockwiseWebServer
ClockwiseParams::getInstance()->autoBrightMax = value.substring(5,9).toInt();
} else if (key == ClockwiseParams::getInstance()->PREF_SWAP_BLUE_GREEN) {
ClockwiseParams::getInstance()->swapBlueGreen = (value == "1");
+ } else if (key == ClockwiseParams::getInstance()->PREF_SWAP_BLUE_RED) {
+ ClockwiseParams::getInstance()->swapBlueRed = (value == "1");
} else if (key == ClockwiseParams::getInstance()->PREF_USE_24H_FORMAT) {
ClockwiseParams::getInstance()->use24hFormat = (value == "1");
} else if (key == ClockwiseParams::getInstance()->PREF_LDR_PIN) {
@@ -127,6 +129,12 @@ struct ClockwiseWebServer
ClockwiseParams::getInstance()->manualPosix = value;
} else if (key == ClockwiseParams::getInstance()->PREF_DISPLAY_ROTATION) {
ClockwiseParams::getInstance()->displayRotation = value.toInt();
+ } else if (key == ClockwiseParams::getInstance()->PREF_DRIVER) {
+ ClockwiseParams::getInstance()->driver = value.toInt();
+ } else if (key == ClockwiseParams::getInstance()->PREF_I2CSPEED) {
+ ClockwiseParams::getInstance()->i2cSpeed = value.toInt();
+ } else if (key == ClockwiseParams::getInstance()->PREF_E_PIN) {
+ ClockwiseParams::getInstance()->E_pin = value.toInt();
}
ClockwiseParams::getInstance()->save();
client.println("HTTP/1.0 204 No Content");
@@ -154,6 +162,7 @@ struct ClockwiseWebServer
client.printf(HEADER_TEMPLATE_D, ClockwiseParams::getInstance()->PREF_DISPLAY_ABC_MIN, ClockwiseParams::getInstance()->autoBrightMin);
client.printf(HEADER_TEMPLATE_D, ClockwiseParams::getInstance()->PREF_DISPLAY_ABC_MAX, ClockwiseParams::getInstance()->autoBrightMax);
client.printf(HEADER_TEMPLATE_D, ClockwiseParams::getInstance()->PREF_SWAP_BLUE_GREEN, ClockwiseParams::getInstance()->swapBlueGreen);
+ client.printf(HEADER_TEMPLATE_D, ClockwiseParams::getInstance()->PREF_SWAP_BLUE_RED, ClockwiseParams::getInstance()->swapBlueRed);
client.printf(HEADER_TEMPLATE_D, ClockwiseParams::getInstance()->PREF_USE_24H_FORMAT, ClockwiseParams::getInstance()->use24hFormat);
client.printf(HEADER_TEMPLATE_D, ClockwiseParams::getInstance()->PREF_LDR_PIN, ClockwiseParams::getInstance()->ldrPin);
client.printf(HEADER_TEMPLATE_S, ClockwiseParams::getInstance()->PREF_TIME_ZONE, ClockwiseParams::getInstance()->timeZone.c_str());
@@ -163,6 +172,9 @@ struct ClockwiseWebServer
client.printf(HEADER_TEMPLATE_S, ClockwiseParams::getInstance()->PREF_CANVAS_SERVER, ClockwiseParams::getInstance()->canvasServer.c_str());
client.printf(HEADER_TEMPLATE_S, ClockwiseParams::getInstance()->PREF_MANUAL_POSIX, ClockwiseParams::getInstance()->manualPosix.c_str());
client.printf(HEADER_TEMPLATE_D, ClockwiseParams::getInstance()->PREF_DISPLAY_ROTATION, ClockwiseParams::getInstance()->displayRotation);
+ client.printf(HEADER_TEMPLATE_D, ClockwiseParams::getInstance()->PREF_DRIVER, ClockwiseParams::getInstance()->driver);
+ client.printf(HEADER_TEMPLATE_D, ClockwiseParams::getInstance()->PREF_I2CSPEED, ClockwiseParams::getInstance()->i2cSpeed);
+ client.printf(HEADER_TEMPLATE_D, ClockwiseParams::getInstance()->PREF_E_PIN, ClockwiseParams::getInstance()->E_pin);
client.printf(HEADER_TEMPLATE_S, "CW_FW_VERSION", CW_FW_VERSION);
client.printf(HEADER_TEMPLATE_S, "CW_FW_NAME", CW_FW_NAME);
diff --git a/firmware/lib/cw-commons/SettingsWebPage.h b/firmware/lib/cw-commons/SettingsWebPage.h
index 7a42c3f..503ba18 100644
--- a/firmware/lib/cw-commons/SettingsWebPage.h
+++ b/firmware/lib/cw-commons/SettingsWebPage.h
@@ -77,6 +77,14 @@ const char SETTINGS_PAGE[] PROGMEM = R""""(
save: "updatePreference('swapBlueGreen', Number(swapBG.checked))",
property: "swapBlueGreen"
},
+ {
+ title: "Swap Blue/Red pins?",
+ description: "Swap Blue and Red pins",
+ formInput: "",
+ icon: "fa-random",
+ save: "updatePreference('swapBlueRed', Number(swapBR.checked))",
+ property: "swapBlueRed"
+ },
{
title: "Timezone",
description: "Consult your TZ identifier here. Examples: America/Sao_Paulo, Europe/Lisbon",
@@ -143,7 +151,31 @@ const char SETTINGS_PAGE[] PROGMEM = R""""(
icon: "fa-rotate-right",
save: "updatePreference('displayRotation', rotation.value)",
property: "displayRotation"
- }
+ },
+ {
+ title: "Matrix Shift Driver",
+ description: "Hardware-specific chips used to drive matrix modules (default: SHIFTREG).",
+ formInput: "",
+ icon: "fa-microchip",
+ save: "updatePreference('driver', driver.value)",
+ property: "driver"
+ },
+ {
+ title: "I2C Speed",
+ description: "I2S clock speed selector (default: HZ_8M).",
+ formInput: "",
+ save: "updatePreference('i2cSpeed', speed.value)",
+ icon: "fa-microchip",
+ property: "i2cSpeed"
+ },
+ {
+ title: "E Pin",
+ description: "E pin is Address Line E used for 64-row LED panels to select specific rows (default: 18).",
+ formInput: "",
+ icon: "fa-microchip",
+ save: "updatePreference('E_pin', E_pin.value)",
+ property: "E_pin"
+ }
];
var base = document.querySelector('#base');
@@ -229,7 +261,7 @@ const char SETTINGS_PAGE[] PROGMEM = R""""(
}
//Local
- //createCards({ "displayBright": 30, "swapBlueGreen": 1, "use24hFormat": 0, "timeZone": "Europe/Lisbon", "ntpServer": "pool.ntp.org", "wifiSsid": "test", "autoBrightMin":0, "autoBrightMax":800, "ldrPin":35, "cw_fw_version":"1.2.2", "clockface_name":"cw-cf-0x07", "canvasServer":"raw.githubusercontent.com", "canvasFile":"star-wars.json" });
+ //createCards({ "displayBright": 30, "swapBlueGreen": 1, "swapBlueRed": 0, "use24hFormat": 0, "timeZone": "Europe/Lisbon", "ntpServer": "pool.ntp.org", "wifiSsid": "test", "autoBrightMin":0, "autoBrightMax":800, "ldrPin":35, "driver":1, "i2cspeed":16000000, "e_pin":18, "cw_fw_version":"1.2.2", "clockface_name":"cw-cf-0x07", "canvasServer":"raw.githubusercontent.com", "canvasFile":"star-wars.json" });
//Embedded
begin();
diff --git a/firmware/src/main.cpp b/firmware/src/main.cpp
index 61ca80d..6aeb2c9 100644
--- a/firmware/src/main.cpp
+++ b/firmware/src/main.cpp
@@ -26,7 +26,17 @@ bool autoBrightEnabled;
long autoBrightMillis = 0;
uint8_t currentBrightSlot = -1;
-void displaySetup(bool swapBlueGreen, uint8_t displayBright, uint8_t displayRotation)
+bool isValidI2SSpeed(uint32_t speed) {
+ return speed == 8000000 || speed == 16000000 || speed == 20000000;
+}
+
+bool isValidDriver(uint32_t drv) {
+ return drv >= 0 && drv <= 5;
+}
+
+
+
+void displaySetup(bool swapBlueGreen, bool swapBlueRed, uint8_t displayBright, uint8_t displayRotation, uint8_t driver, uint32_t i2cSpeed, uint8_t E_pin)
{
HUB75_I2S_CFG mxconfig(64, 64, 1);
@@ -39,9 +49,29 @@ void displaySetup(bool swapBlueGreen, uint8_t displayBright, uint8_t displayRota
mxconfig.gpio.g2 = 13;
}
- mxconfig.gpio.e = 18;
+ if (swapBlueRed)
+ {
+ // Swap Blue and Red pins.
+ mxconfig.gpio.b1 = 25;
+ mxconfig.gpio.b2 = 14;
+ mxconfig.gpio.r1 = 27;
+ mxconfig.gpio.r2 = 13;
+ }
+
+ mxconfig.gpio.e = E_pin;
mxconfig.clkphase = false;
+ if (isValidDriver(driver)) {
+ mxconfig.driver = static_cast(driver);
+ } else {
+ Serial.printf("[ERROR] Invalid driver from config:%d\n", driver);
+ }
+ if (isValidI2SSpeed(i2cSpeed)) {
+ mxconfig.i2sspeed = static_cast(i2cSpeed);
+ } else {
+ Serial.printf("[ERROR] Invalid I2S speed from config:%d\n", i2cSpeed);
+ }
+
// Display Setup
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
dma_display->begin();
@@ -89,7 +119,11 @@ void setup()
pinMode(ClockwiseParams::getInstance()->ldrPin, INPUT);
- displaySetup(ClockwiseParams::getInstance()->swapBlueGreen, ClockwiseParams::getInstance()->displayBright, ClockwiseParams::getInstance()->displayRotation);
+ uint8_t driver = ClockwiseParams::getInstance()->driver;
+ uint32_t i2cSpeed = ClockwiseParams::getInstance()->i2cSpeed;
+ uint8_t E_pin = ClockwiseParams::getInstance()->E_pin;
+
+ displaySetup(ClockwiseParams::getInstance()->swapBlueGreen, ClockwiseParams::getInstance()->swapBlueRed, ClockwiseParams::getInstance()->displayBright, ClockwiseParams::getInstance()->displayRotation, driver, i2cSpeed, E_pin);
clockface = new Clockface(dma_display);
autoBrightEnabled = (ClockwiseParams::getInstance()->autoBrightMax > 0);