Skip to content

Commit 4eb00cd

Browse files
authored
Merge pull request #233 from ashtf8/OS_dev
Keyboard Softlock Patch 2
2 parents 9e77b80 + 03a3018 commit 4eb00cd

10 files changed

Lines changed: 1199 additions & 1095 deletions

File tree

Code/PocketMage_V3/lib/PocketMage/src/pocketmage_kb.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,13 @@ char PocketmageKB::updateKeypress() {
10521052
}
10531053
}
10541054

1055+
// --- LEVEL-TRIGGER FAILSAFE ---
1056+
// If the physical interrupt pin is STILL held low by the TCA8418 after we processed everything,
1057+
// we missed a falling edge during the I2C transaction. Force the software flag to stay true.
1058+
if (digitalRead(KB_IRQ) == LOW) {
1059+
TCA8418_event_ = true;
1060+
}
1061+
10551062
return 0;
10561063
}
10571064

Code/PocketMage_V3/src/OS_APPS/APPLOADER.cpp

Lines changed: 63 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -667,103 +667,102 @@ void APPLOADER_INIT() {
667667
void processKB_APPLOADER() {
668668
int currentMillis = millis();
669669
String outPath = "";
670+
char inchar = 0;
670671

671672
switch (CurrentAppLoaderState) {
672673
case MENU:
674+
// 1. Drain the hardware buffer continuously at loop speed
675+
inchar = KB().updateKeypress();
676+
677+
// 2. Only process the actual input if the cooldown has expired
673678
if (currentMillis - KBBounceMillis >= KB_COOLDOWN) {
674-
char inchar = KB().updateKeypress();
675-
676679
if (inchar != 0) {
677-
KBBounceMillis = currentMillis;
678-
}
680+
KBBounceMillis = currentMillis;
679681

680-
// HANDLE INPUTS
681-
if (inchar == 0) {
682-
// Do nothing
683-
}
684-
else if (inchar == 12 || inchar == 23) { // Home or App Switcher Kill Signal
682+
// HANDLE INPUTS
683+
if (inchar == 12 || inchar == 23) { // Home or App Switcher Kill Signal
685684
HOME_INIT();
686-
}
687-
else if (inchar == 'a' || inchar == 'A' || inchar == '1') {
685+
}
686+
else if (inchar == 'a' || inchar == 'A' || inchar == '1') {
688687
selectedSlot = 1;
689688
CurrentAppLoaderState = SWAP_OR_EDIT;
690689
KB().setKeyboardState(NORMAL);
691-
}
692-
else if (inchar == 'b' || inchar == 'B' || inchar == '2') {
690+
}
691+
else if (inchar == 'b' || inchar == 'B' || inchar == '2') {
693692
selectedSlot = 2;
694693
CurrentAppLoaderState = SWAP_OR_EDIT;
695694
KB().setKeyboardState(NORMAL);
696-
}
697-
else if (inchar == 'c' || inchar == 'C' || inchar == '3') {
695+
}
696+
else if (inchar == 'c' || inchar == 'C' || inchar == '3') {
698697
selectedSlot = 3;
699698
CurrentAppLoaderState = SWAP_OR_EDIT;
700699
KB().setKeyboardState(NORMAL);
701-
}
702-
else if (inchar == 'd' || inchar == 'D' || inchar == '4') {
700+
}
701+
else if (inchar == 'd' || inchar == 'D' || inchar == '4') {
703702
selectedSlot = 4;
704703
CurrentAppLoaderState = SWAP_OR_EDIT;
705704
KB().setKeyboardState(NORMAL);
705+
}
706+
// All other keys are ignored in the MENU state
706707
}
707-
// All other keys are ignored in the MENU state
708+
}
708709

709-
currentMillis = millis();
710-
// Make sure oled only updates at OLED_MAX_FPS
711-
if (currentMillis - OLEDFPSMillis >= (1000/OLED_MAX_FPS)) {
712-
OLEDFPSMillis = currentMillis;
713-
OLED().oledWord("Choose slot: (A)(B)(C)(D)");
714-
}
710+
// 3. Update OLED at true OLED_MAX_FPS, completely independent of keyboard bounce
711+
currentMillis = millis();
712+
if (currentMillis - OLEDFPSMillis >= (1000/OLED_MAX_FPS)) {
713+
OLEDFPSMillis = currentMillis;
714+
OLED().oledWord("Choose slot: (A)(B)(C)(D)");
715715
}
716716
break;
717717

718718
case SWAP_OR_EDIT:
719-
if (currentMillis - KBBounceMillis >= KB_COOLDOWN) {
720-
char inchar = KB().updateKeypress();
719+
// 1. Drain the hardware buffer continuously at loop speed
720+
inchar = KB().updateKeypress();
721721

722+
// 2. Only process the actual input if the cooldown has expired
723+
if (currentMillis - KBBounceMillis >= KB_COOLDOWN) {
722724
if (inchar != 0) {
723-
KBBounceMillis = currentMillis;
724-
}
725+
KBBounceMillis = currentMillis;
725726

726-
if (inchar == 0) {
727-
// Do nothing
728-
}
729-
else if (inchar == 12 || inchar == 23) { // Home or App Switcher Kill Signal
730-
selectedSlot = 0;
731-
CurrentAppLoaderState = MENU;
732-
newState = true; // Trigger e-ink redraw of the menu
733-
}
734-
else if (inchar == 'S' || inchar == 's' || inchar == '!') {
735-
CurrentAppLoaderState = SWAP;
736-
}
737-
else if (inchar == 'D' || inchar == 'd' || inchar == '$') {
738-
// Clear the slot
739-
prefs.begin("PocketMage", false);
740-
prefs.remove(("OTA" + String(selectedSlot)).c_str());
741-
prefs.end();
742-
743-
const esp_partition_t *partition =
744-
esp_partition_find_first(ESP_PARTITION_TYPE_APP,
745-
(esp_partition_subtype_t)(ESP_PARTITION_SUBTYPE_APP_OTA_MIN + selectedSlot),
746-
nullptr);
747-
748-
if (partition) {
749-
esp_err_t err = esp_partition_erase_range(partition, 0, partition->size);
750-
if (err == ESP_OK) {
751-
Serial.printf("OTA_%d erased\n", selectedSlot);
752-
}
727+
if (inchar == 12 || inchar == 23) { // Home or App Switcher Kill Signal
728+
selectedSlot = 0;
729+
CurrentAppLoaderState = MENU;
730+
newState = true; // Trigger e-ink redraw of the menu
731+
}
732+
else if (inchar == 'S' || inchar == 's' || inchar == '!') {
733+
CurrentAppLoaderState = SWAP;
753734
}
735+
else if (inchar == 'D' || inchar == 'd' || inchar == '$') {
736+
// Clear the slot
737+
prefs.begin("PocketMage", false);
738+
prefs.remove(("OTA" + String(selectedSlot)).c_str());
739+
prefs.end();
740+
741+
const esp_partition_t *partition =
742+
esp_partition_find_first(ESP_PARTITION_TYPE_APP,
743+
(esp_partition_subtype_t)(ESP_PARTITION_SUBTYPE_APP_OTA_MIN + selectedSlot),
744+
nullptr);
745+
746+
if (partition) {
747+
esp_err_t err = esp_partition_erase_range(partition, 0, partition->size);
748+
if (err == ESP_OK) {
749+
Serial.printf("OTA_%d erased\n", selectedSlot);
750+
}
751+
}
754752

755-
OLED().sysMessage("App removed", 2000);
753+
OLED().sysMessage("App removed", 2000);
756754

757-
newState = true;
758-
CurrentAppLoaderState = MENU;
755+
newState = true;
756+
CurrentAppLoaderState = MENU;
757+
}
759758
}
759+
}
760760

761-
currentMillis = millis();
762-
// Make sure oled only updates at OLED_MAX_FPS
763-
if (currentMillis - OLEDFPSMillis >= (1000/OLED_MAX_FPS)) {
764-
OLEDFPSMillis = currentMillis;
765-
OLED().oledWord("(S)wap app or (D)elete app");
766-
}
761+
// 3. Update OLED at true OLED_MAX_FPS, completely independent of keyboard bounce
762+
currentMillis = millis();
763+
if (currentMillis - OLEDFPSMillis >= (1000/OLED_MAX_FPS)) {
764+
OLEDFPSMillis = currentMillis;
765+
OLED().oledWord("(S)wap app or (D)elete app");
767766
}
768767
break;
769768

0 commit comments

Comments
 (0)