forked from btclock/btclock_v3
Fix button handling
This commit is contained in:
parent
8a818c66a0
commit
4fdd6b6b4f
3 changed files with 66 additions and 45 deletions
|
@ -19,41 +19,52 @@ TickType_t lastDebounceTime = 0;
|
||||||
void buttonTask(void *parameter) {
|
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) {
|
||||||
lastDebounceTime = currentTime;
|
lastDebounceTime = currentTime;
|
||||||
|
|
||||||
if (!digitalRead(MCP_INT_PIN)) {
|
std::lock_guard<std::mutex> lock(mcpMutex);
|
||||||
uint pin = mcp1.getInterruptFlagRegister();
|
|
||||||
|
|
||||||
switch (pin) {
|
if (!digitalRead(MCP_INT_PIN)) {
|
||||||
case BTN_1:
|
uint16_t intFlags = mcp1.getInterruptFlagRegister();
|
||||||
toggleTimerActive();
|
uint16_t intCap = mcp1.getInterruptCaptureRegister();
|
||||||
break;
|
|
||||||
case BTN_2:
|
// Check each button individually
|
||||||
nextScreen();
|
if (intFlags & BTN_1) handleButton1();
|
||||||
break;
|
if (intFlags & BTN_2) handleButton2();
|
||||||
case BTN_3:
|
if (intFlags & BTN_3) handleButton3();
|
||||||
previousScreen();
|
if (intFlags & BTN_4) handleButton4();
|
||||||
break;
|
|
||||||
case BTN_4:
|
|
||||||
showSystemStatusScreen();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mcp1.getInterruptCaptureRegister();
|
|
||||||
} else {
|
|
||||||
}
|
}
|
||||||
// Very ugly, but for some reason this is necessary
|
|
||||||
|
// Clear interrupt state
|
||||||
while (!digitalRead(MCP_INT_PIN)) {
|
while (!digitalRead(MCP_INT_PIN)) {
|
||||||
|
std::lock_guard<std::mutex> lock(mcpMutex);
|
||||||
mcp1.getInterruptCaptureRegister();
|
mcp1.getInterruptCaptureRegister();
|
||||||
|
delay(1); // Small delay to prevent tight loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper functions to handle each button
|
||||||
|
void handleButton1() {
|
||||||
|
toggleTimerActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleButton2() {
|
||||||
|
nextScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleButton3() {
|
||||||
|
previousScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleButton4() {
|
||||||
|
showSystemStatusScreen();
|
||||||
|
}
|
||||||
|
|
||||||
void IRAM_ATTR handleButtonInterrupt() {
|
void IRAM_ATTR handleButtonInterrupt() {
|
||||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
xTaskNotifyFromISR(buttonTaskHandle, 0, eNoAction, &xHigherPriorityTaskWoken);
|
xTaskNotifyFromISR(buttonTaskHandle, 0, eNoAction, &xHigherPriorityTaskWoken);
|
||||||
|
@ -67,4 +78,5 @@ void setupButtonTask() {
|
||||||
&buttonTaskHandle); // Create the FreeRTOS task
|
&buttonTaskHandle); // Create the FreeRTOS task
|
||||||
// Use interrupt instead of task
|
// Use interrupt instead of task
|
||||||
attachInterrupt(MCP_INT_PIN, handleButtonInterrupt, CHANGE);
|
attachInterrupt(MCP_INT_PIN, handleButtonInterrupt, CHANGE);
|
||||||
|
Serial.printf("Button task created\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,13 @@
|
||||||
|
|
||||||
extern TaskHandle_t buttonTaskHandle;
|
extern TaskHandle_t buttonTaskHandle;
|
||||||
|
|
||||||
|
// Task and setup functions
|
||||||
void buttonTask(void *pvParameters);
|
void buttonTask(void *pvParameters);
|
||||||
void IRAM_ATTR handleButtonInterrupt();
|
void IRAM_ATTR handleButtonInterrupt();
|
||||||
void setupButtonTask();
|
void setupButtonTask();
|
||||||
|
|
||||||
|
// Individual button handlers
|
||||||
|
void handleButton1();
|
||||||
|
void handleButton2();
|
||||||
|
void handleButton3();
|
||||||
|
void handleButton4();
|
||||||
|
|
|
@ -466,32 +466,34 @@ void setupHardware()
|
||||||
|
|
||||||
Wire.begin(I2C_SDA_PIN, I2C_SCK_PIN, 400000);
|
Wire.begin(I2C_SDA_PIN, I2C_SCK_PIN, 400000);
|
||||||
|
|
||||||
if (!mcp1.begin())
|
if (!mcp1.begin()) {
|
||||||
{
|
|
||||||
Serial.println(F("Error MCP23017 1"));
|
Serial.println(F("Error MCP23017 1"));
|
||||||
|
} else {
|
||||||
// while (1)
|
|
||||||
// ;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pinMode(MCP_INT_PIN, INPUT_PULLUP);
|
pinMode(MCP_INT_PIN, INPUT_PULLUP);
|
||||||
// mcp1.setupInterrupts(false, false, LOW);
|
|
||||||
mcp1.enableControlRegister(MCP23x17_IOCR_ODR);
|
|
||||||
|
|
||||||
mcp1.mirrorInterrupts(true);
|
// Enable mirrored interrupts (both INTA and INTB pins signal any interrupt)
|
||||||
|
if (!mcp1.mirrorInterrupts(true)) {
|
||||||
|
Serial.println(F("Error setting up mirrored interrupts"));
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
// Configure all 4 button pins as inputs with pullups and interrupts
|
||||||
{
|
for (int i = 0; i < 4; i++) {
|
||||||
mcp1.pinMode1(i, INPUT_PULLUP);
|
if (!mcp1.pinMode1(i, INPUT_PULLUP)) {
|
||||||
mcp1.enableInterrupt(i, LOW);
|
Serial.printf("Error setting pin %d to input pull up\n", i);
|
||||||
|
}
|
||||||
|
// Enable interrupt on CHANGE for each pin
|
||||||
|
if (!mcp1.enableInterrupt(i, CHANGE)) {
|
||||||
|
Serial.printf("Error enabling interrupt for pin %d\n", i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifndef IS_BTCLOCK_V8
|
|
||||||
for (int i = 8; i <= 14; i++)
|
// Set interrupt pins as open drain with active-low polarity
|
||||||
{
|
if (!mcp1.setInterruptPolarity(2)) { // 2 = Open drain
|
||||||
mcp1.pinMode1(i, OUTPUT);
|
Serial.println(F("Error setting interrupt polarity"));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
// Clear any pending interrupts
|
||||||
|
mcp1.getInterruptCaptureRegister();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef IS_HW_REV_B
|
#ifdef IS_HW_REV_B
|
||||||
|
|
Loading…
Reference in a new issue