Use mutexes to guard the MCP
This commit is contained in:
parent
a3783ceffa
commit
59f9b29df3
5 changed files with 164 additions and 77 deletions
|
@ -9,6 +9,8 @@ void buttonTask(void *parameter)
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||||
|
std::lock_guard<std::mutex> lock(mcpMutex);
|
||||||
|
|
||||||
TickType_t currentTime = xTaskGetTickCount();
|
TickType_t currentTime = xTaskGetTickCount();
|
||||||
if ((currentTime - lastDebounceTime) >= debounceDelay)
|
if ((currentTime - lastDebounceTime) >= debounceDelay)
|
||||||
{
|
{
|
||||||
|
@ -35,11 +37,14 @@ void buttonTask(void *parameter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mcp.clearInterrupts();
|
mcp.clearInterrupts();
|
||||||
// Very ugly, but for some reason this is necessary
|
}
|
||||||
while (!digitalRead(MCP_INT_PIN))
|
else
|
||||||
{
|
{
|
||||||
mcp.clearInterrupts();
|
}
|
||||||
}
|
// Very ugly, but for some reason this is necessary
|
||||||
|
while (!digitalRead(MCP_INT_PIN))
|
||||||
|
{
|
||||||
|
mcp.clearInterrupts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
Preferences preferences;
|
Preferences preferences;
|
||||||
Adafruit_MCP23X17 mcp;
|
Adafruit_MCP23X17 mcp;
|
||||||
std::vector<std::string> screenNameMap(SCREEN_COUNT);
|
std::vector<std::string> screenNameMap(SCREEN_COUNT);
|
||||||
|
std::mutex mcpMutex;
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
|
@ -15,12 +16,15 @@ void setup()
|
||||||
{
|
{
|
||||||
queueLedEffect(LED_POWER_TEST);
|
queueLedEffect(LED_POWER_TEST);
|
||||||
}
|
}
|
||||||
if (mcp.digitalRead(3) == LOW)
|
|
||||||
{
|
{
|
||||||
preferences.putBool("wifiConfigured", false);
|
std::lock_guard<std::mutex> lockMcp(mcpMutex);
|
||||||
|
if (mcp.digitalRead(3) == LOW)
|
||||||
|
{
|
||||||
|
preferences.putBool("wifiConfigured", false);
|
||||||
|
|
||||||
WiFi.eraseAP();
|
WiFi.eraseAP();
|
||||||
queueLedEffect(LED_EFFECT_WIFI_ERASE_SETTINGS);
|
queueLedEffect(LED_EFFECT_WIFI_ERASE_SETTINGS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tryImprovSetup();
|
tryImprovSetup();
|
||||||
|
@ -56,8 +60,13 @@ void tryImprovSetup()
|
||||||
uint8_t x_buffer[16];
|
uint8_t x_buffer[16];
|
||||||
uint8_t x_position = 0;
|
uint8_t x_position = 0;
|
||||||
|
|
||||||
|
bool buttonPress = false;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lockMcp(mcpMutex);
|
||||||
|
buttonPress = (mcp.digitalRead(2) == LOW);
|
||||||
|
}
|
||||||
// Hold second button to start QR code wifi config
|
// Hold second button to start QR code wifi config
|
||||||
if (mcp.digitalRead(2) == LOW)
|
if (buttonPress)
|
||||||
{
|
{
|
||||||
WiFiManager wm;
|
WiFiManager wm;
|
||||||
|
|
||||||
|
@ -81,8 +90,7 @@ void tryImprovSetup()
|
||||||
const String qrText = "qrWIFI:S:" + wifiManager->getConfigPortalSSID() + ";T:WPA;P:" + softAP_password.c_str() + ";;";
|
const String qrText = "qrWIFI:S:" + wifiManager->getConfigPortalSSID() + ";T:WPA;P:" + softAP_password.c_str() + ";;";
|
||||||
const String explainText = "*SSID: *\r\n" + wifiManager->getConfigPortalSSID() + "\r\n\r\n*Password:*\r\n" + softAP_password;
|
const String explainText = "*SSID: *\r\n" + wifiManager->getConfigPortalSSID() + "\r\n\r\n*Password:*\r\n" + softAP_password;
|
||||||
std::array<String, NUM_SCREENS> epdContent = {"Welcome!", "", "To setup\r\nscan QR or\r\nconnect\r\nmanually", "", explainText, "", qrText};
|
std::array<String, NUM_SCREENS> epdContent = {"Welcome!", "", "To setup\r\nscan QR or\r\nconnect\r\nmanually", "", explainText, "", qrText};
|
||||||
setEpdContent(epdContent);
|
setEpdContent(epdContent); });
|
||||||
});
|
|
||||||
|
|
||||||
wm.setSaveConfigCallback([]()
|
wm.setSaveConfigCallback([]()
|
||||||
{
|
{
|
||||||
|
@ -133,7 +141,7 @@ void tryImprovSetup()
|
||||||
vTaskDelay(pdMS_TO_TICKS(400));
|
vTaskDelay(pdMS_TO_TICKS(400));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// queueLedEffect(LED_EFFECT_WIFI_CONNECT_SUCCESS);
|
// queueLedEffect(LED_EFFECT_WIFI_CONNECT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupTime()
|
void setupTime()
|
||||||
|
@ -153,7 +161,6 @@ void setupPreferences()
|
||||||
{
|
{
|
||||||
preferences.begin("btclock", false);
|
preferences.begin("btclock", false);
|
||||||
|
|
||||||
|
|
||||||
setFgColor(preferences.getUInt("fgColor", DEFAULT_FG_COLOR));
|
setFgColor(preferences.getUInt("fgColor", DEFAULT_FG_COLOR));
|
||||||
setBgColor(preferences.getUInt("bgColor", DEFAULT_BG_COLOR));
|
setBgColor(preferences.getUInt("bgColor", DEFAULT_BG_COLOR));
|
||||||
setBlockHeight(preferences.getUInt("blockHeight", 816000));
|
setBlockHeight(preferences.getUInt("blockHeight", 816000));
|
||||||
|
@ -171,9 +178,12 @@ void setupWebsocketClients(void *pvParameters)
|
||||||
{
|
{
|
||||||
setupBlockNotify();
|
setupBlockNotify();
|
||||||
|
|
||||||
if (preferences.getBool("fetchEurPrice", false)) {
|
if (preferences.getBool("fetchEurPrice", false))
|
||||||
|
{
|
||||||
setupPriceFetchTask();
|
setupPriceFetchTask();
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
setupPriceNotify();
|
setupPriceNotify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +221,7 @@ void setupHardware()
|
||||||
WiFi.setHostname(getMyHostname().c_str());
|
WiFi.setHostname(getMyHostname().c_str());
|
||||||
;
|
;
|
||||||
if (!psramInit())
|
if (!psramInit())
|
||||||
{
|
{
|
||||||
Serial.println(F("PSRAM not available"));
|
Serial.println(F("PSRAM not available"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,60 +459,63 @@ void WiFiEvent(WiFiEvent_t event)
|
||||||
{
|
{
|
||||||
Serial.printf("[WiFi-event] event: %d\n", event);
|
Serial.printf("[WiFi-event] event: %d\n", event);
|
||||||
|
|
||||||
switch (event) {
|
switch (event)
|
||||||
case ARDUINO_EVENT_WIFI_READY:
|
{
|
||||||
Serial.println("WiFi interface ready");
|
case ARDUINO_EVENT_WIFI_READY:
|
||||||
break;
|
Serial.println("WiFi interface ready");
|
||||||
case ARDUINO_EVENT_WIFI_SCAN_DONE:
|
break;
|
||||||
Serial.println("Completed scan for access points");
|
case ARDUINO_EVENT_WIFI_SCAN_DONE:
|
||||||
break;
|
Serial.println("Completed scan for access points");
|
||||||
case ARDUINO_EVENT_WIFI_STA_START:
|
break;
|
||||||
Serial.println("WiFi client started");
|
case ARDUINO_EVENT_WIFI_STA_START:
|
||||||
break;
|
Serial.println("WiFi client started");
|
||||||
case ARDUINO_EVENT_WIFI_STA_STOP:
|
break;
|
||||||
Serial.println("WiFi clients stopped");
|
case ARDUINO_EVENT_WIFI_STA_STOP:
|
||||||
break;
|
Serial.println("WiFi clients stopped");
|
||||||
case ARDUINO_EVENT_WIFI_STA_CONNECTED:
|
break;
|
||||||
Serial.println("Connected to access point");
|
case ARDUINO_EVENT_WIFI_STA_CONNECTED:
|
||||||
break;
|
Serial.println("Connected to access point");
|
||||||
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
|
break;
|
||||||
Serial.println("Disconnected from WiFi access point");
|
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
|
||||||
queueLedEffect(LED_EFFECT_WIFI_CONNECT_ERROR);
|
Serial.println("Disconnected from WiFi access point");
|
||||||
break;
|
queueLedEffect(LED_EFFECT_WIFI_CONNECT_ERROR);
|
||||||
case ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE:
|
break;
|
||||||
Serial.println("Authentication mode of access point has changed");
|
case ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE:
|
||||||
break;
|
Serial.println("Authentication mode of access point has changed");
|
||||||
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
|
break;
|
||||||
Serial.print("Obtained IP address: ");
|
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
|
||||||
Serial.println(WiFi.localIP());
|
Serial.print("Obtained IP address: ");
|
||||||
break;
|
Serial.println(WiFi.localIP());
|
||||||
case ARDUINO_EVENT_WIFI_STA_LOST_IP:
|
break;
|
||||||
Serial.println("Lost IP address and IP address is reset to 0");
|
case ARDUINO_EVENT_WIFI_STA_LOST_IP:
|
||||||
queueLedEffect(LED_EFFECT_WIFI_CONNECT_ERROR);
|
Serial.println("Lost IP address and IP address is reset to 0");
|
||||||
break;
|
queueLedEffect(LED_EFFECT_WIFI_CONNECT_ERROR);
|
||||||
case ARDUINO_EVENT_WIFI_AP_START:
|
break;
|
||||||
Serial.println("WiFi access point started");
|
case ARDUINO_EVENT_WIFI_AP_START:
|
||||||
break;
|
Serial.println("WiFi access point started");
|
||||||
case ARDUINO_EVENT_WIFI_AP_STOP:
|
break;
|
||||||
Serial.println("WiFi access point stopped");
|
case ARDUINO_EVENT_WIFI_AP_STOP:
|
||||||
break;
|
Serial.println("WiFi access point stopped");
|
||||||
case ARDUINO_EVENT_WIFI_AP_STACONNECTED:
|
break;
|
||||||
Serial.println("Client connected");
|
case ARDUINO_EVENT_WIFI_AP_STACONNECTED:
|
||||||
break;
|
Serial.println("Client connected");
|
||||||
case ARDUINO_EVENT_WIFI_AP_STADISCONNECTED:
|
break;
|
||||||
Serial.println("Client disconnected");
|
case ARDUINO_EVENT_WIFI_AP_STADISCONNECTED:
|
||||||
break;
|
Serial.println("Client disconnected");
|
||||||
case ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED:
|
break;
|
||||||
Serial.println("Assigned IP address to client");
|
case ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED:
|
||||||
break;
|
Serial.println("Assigned IP address to client");
|
||||||
case ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED:
|
break;
|
||||||
Serial.println("Received probe request");
|
case ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED:
|
||||||
break;
|
Serial.println("Received probe request");
|
||||||
case ARDUINO_EVENT_WIFI_AP_GOT_IP6:
|
break;
|
||||||
Serial.println("AP IPv6 is preferred");
|
case ARDUINO_EVENT_WIFI_AP_GOT_IP6:
|
||||||
break;
|
Serial.println("AP IPv6 is preferred");
|
||||||
case ARDUINO_EVENT_WIFI_STA_GOT_IP6:
|
break;
|
||||||
Serial.println("STA IPv6 is preferred");
|
case ARDUINO_EVENT_WIFI_STA_GOT_IP6:
|
||||||
break;
|
Serial.println("STA IPv6 is preferred");
|
||||||
default: break;
|
break;
|
||||||
}}
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -98,6 +98,8 @@ void refreshFromMemory()
|
||||||
|
|
||||||
void setupDisplays()
|
void setupDisplays()
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lockMcp(mcpMutex);
|
||||||
|
|
||||||
for (uint i = 0; i < NUM_SCREENS; i++)
|
for (uint i = 0; i < NUM_SCREENS; i++)
|
||||||
{
|
{
|
||||||
displays[i].init(0, true, 30);
|
displays[i].init(0, true, 30);
|
||||||
|
@ -209,7 +211,12 @@ extern "C" void updateDisplay(void *pvParameters) noexcept
|
||||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(epdMutex[epdIndex]);
|
std::lock_guard<std::mutex> lock(epdMutex[epdIndex]);
|
||||||
displays[epdIndex].init(0, false, 40);
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lockMcp(mcpMutex);
|
||||||
|
|
||||||
|
displays[epdIndex].init(0, false, 40);
|
||||||
|
}
|
||||||
uint count = 0;
|
uint count = 0;
|
||||||
while (EPD_BUSY[epdIndex].digitalRead() == HIGH || count < 10)
|
while (EPD_BUSY[epdIndex].digitalRead() == HIGH || count < 10)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,6 +16,7 @@ void setupOTA()
|
||||||
ArduinoOTA.setMdnsEnabled(false);
|
ArduinoOTA.setMdnsEnabled(false);
|
||||||
ArduinoOTA.setRebootOnSuccess(false);
|
ArduinoOTA.setRebootOnSuccess(false);
|
||||||
ArduinoOTA.begin();
|
ArduinoOTA.begin();
|
||||||
|
//downloadUpdate();
|
||||||
|
|
||||||
xTaskCreate(handleOTATask, "handleOTA", 4096, NULL, tskIDLE_PRIORITY, &taskOtaHandle);
|
xTaskCreate(handleOTATask, "handleOTA", 4096, NULL, tskIDLE_PRIORITY, &taskOtaHandle);
|
||||||
}
|
}
|
||||||
|
@ -78,14 +79,72 @@ void handleOTATask(void *parameter)
|
||||||
|
|
||||||
void downloadUpdate()
|
void downloadUpdate()
|
||||||
{
|
{
|
||||||
|
WiFiClientSecure client;
|
||||||
|
client.setInsecure();
|
||||||
|
HTTPClient http;
|
||||||
|
http.setUserAgent(USER_AGENT);
|
||||||
|
|
||||||
|
// Send HTTP request to CoinGecko API
|
||||||
|
http.useHTTP10(true);
|
||||||
|
|
||||||
|
http.begin(client, "https://api.github.com/repos/btclock/btclock_v3/releases/latest");
|
||||||
|
int httpCode = http.GET();
|
||||||
|
|
||||||
|
if (httpCode == 200)
|
||||||
|
{
|
||||||
|
// WiFiClient * stream = http->getStreamPtr();
|
||||||
|
|
||||||
|
StaticJsonDocument<64> filter;
|
||||||
|
|
||||||
|
JsonObject filter_assets_0 = filter["assets"].createNestedObject();
|
||||||
|
filter_assets_0["name"] = true;
|
||||||
|
filter_assets_0["browser_download_url"] = true;
|
||||||
|
|
||||||
|
SpiRamJsonDocument doc(1536);
|
||||||
|
|
||||||
|
DeserializationError error = deserializeJson(doc, http.getStream(), DeserializationOption::Filter(filter));
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
Serial.print("deserializeJson() failed: ");
|
||||||
|
Serial.println(error.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String downloadUrl;
|
||||||
|
for (JsonObject asset : doc["assets"].as<JsonArray>())
|
||||||
|
{
|
||||||
|
if (asset["name"].as<String>().compareTo("firmware.bin") == 0) {
|
||||||
|
downloadUrl = asset["browser_download_url"].as<String>();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.printf("Download update from %s", downloadUrl);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// esp_http_client_config_t config = {
|
||||||
|
// .url = CONFIG_FIRMWARE_UPGRADE_URL,
|
||||||
|
// };
|
||||||
|
// esp_https_ota_config_t ota_config = {
|
||||||
|
// .http_config = &config,
|
||||||
|
// };
|
||||||
|
// esp_err_t ret = esp_https_ota(&ota_config);
|
||||||
|
// if (ret == ESP_OK)
|
||||||
|
// {
|
||||||
|
// esp_restart();
|
||||||
|
// }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onOTAError(ota_error_t error) {
|
void onOTAError(ota_error_t error)
|
||||||
|
{
|
||||||
Serial.println("\nOTA update error, restarting");
|
Serial.println("\nOTA update error, restarting");
|
||||||
Wire.end();
|
Wire.end();
|
||||||
SPI.end();
|
SPI.end();
|
||||||
delay(1000);
|
delay(1000);
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onOTAComplete()
|
void onOTAComplete()
|
||||||
|
|
|
@ -5,10 +5,13 @@
|
||||||
#include <Adafruit_MCP23X17.h>
|
#include <Adafruit_MCP23X17.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <Preferences.h>
|
#include <Preferences.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
|
|
||||||
extern Adafruit_MCP23X17 mcp;
|
extern Adafruit_MCP23X17 mcp;
|
||||||
extern Preferences preferences;
|
extern Preferences preferences;
|
||||||
|
extern std::mutex mcpMutex;
|
||||||
|
|
||||||
const PROGMEM int SCREEN_BLOCK_HEIGHT = 0;
|
const PROGMEM int SCREEN_BLOCK_HEIGHT = 0;
|
||||||
const PROGMEM int SCREEN_MSCW_TIME = 1;
|
const PROGMEM int SCREEN_MSCW_TIME = 1;
|
||||||
|
|
Loading…
Reference in a new issue