Unphone improvements (#172)
- Debounce nav button presses: This fixes multiple triggers on a single press to navigate back. Otherwise, more than 1 app would often close at the same time. - Nav button respond to release instead of push down, because these buttons aren't super reliable in general. (I might change this in the future after more testing) - Move single buzz earlier in boot phase, so that we can detect silent boot loops.
This commit is contained in:
parent
72230129bb
commit
2bbd44a8b5
@ -64,24 +64,22 @@ static bool unPhonePowerOn() {
|
|||||||
|
|
||||||
unPhoneFeatures.printInfo();
|
unPhoneFeatures.printInfo();
|
||||||
|
|
||||||
|
// Vibrate once
|
||||||
|
// Note: Do this before power switching logic, to detect silent boot loops
|
||||||
|
unPhoneFeatures.setVibePower(true);
|
||||||
|
tt::kernel::delayMillis(150);
|
||||||
|
unPhoneFeatures.setVibePower(false);
|
||||||
|
|
||||||
|
// Turn off the device if power switch is on off state,
|
||||||
|
// instead of waiting for the Thread to start and continue booting
|
||||||
updatePowerSwitch();
|
updatePowerSwitch();
|
||||||
startPowerSwitchThread();
|
startPowerSwitchThread();
|
||||||
|
|
||||||
unPhoneFeatures.setBacklightPower(false);
|
unPhoneFeatures.setBacklightPower(false);
|
||||||
|
|
||||||
// Init touch screen GPIOs (used for vibe motor)
|
|
||||||
unPhoneFeatures.setVibePower(false);
|
unPhoneFeatures.setVibePower(false);
|
||||||
|
|
||||||
unPhoneFeatures.setIrPower(false);
|
unPhoneFeatures.setIrPower(false);
|
||||||
|
|
||||||
// This will be default LOW implicitly, but this makes it explicit
|
|
||||||
unPhoneFeatures.setExpanderPower(false);
|
unPhoneFeatures.setExpanderPower(false);
|
||||||
|
|
||||||
// Vibrate once
|
|
||||||
unPhoneFeatures.setVibePower(true);
|
|
||||||
tt::kernel::delayMillis(150);
|
|
||||||
unPhoneFeatures.setVibePower(false);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include "UnPhoneFeatures.h"
|
#include "UnPhoneFeatures.h"
|
||||||
#include "FreeRTOS-Kernel/include/FreeRTOS.h"
|
#include "FreeRTOS-Kernel/include/FreeRTOS.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "kernel/Kernel.h"
|
||||||
#include "service/loader/Loader.h"
|
#include "service/loader/Loader.h"
|
||||||
#include <driver/gpio.h>
|
#include <driver/gpio.h>
|
||||||
#include <driver/rtc_io.h>
|
#include <driver/rtc_io.h>
|
||||||
@ -39,10 +40,18 @@ static int32_t buttonHandlingThreadMain(void* context) {
|
|||||||
int pinNumber;
|
int pinNumber;
|
||||||
while (!*interrupted) {
|
while (!*interrupted) {
|
||||||
if (xQueueReceive(interruptQueue, &pinNumber, portMAX_DELAY)) {
|
if (xQueueReceive(interruptQueue, &pinNumber, portMAX_DELAY)) {
|
||||||
|
// The buttons might generate more than 1 click because of how they are built
|
||||||
TT_LOG_I(TAG, "Pressed button %d", pinNumber);
|
TT_LOG_I(TAG, "Pressed button %d", pinNumber);
|
||||||
if (pinNumber == pin::BUTTON1) {
|
if (pinNumber == pin::BUTTON1) {
|
||||||
tt::service::loader::stopApp();
|
tt::service::loader::stopApp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Debounce all events for a short period of time
|
||||||
|
// This is easier than keeping track when each button was last pressed
|
||||||
|
tt::kernel::delayMillis(50);
|
||||||
|
xQueueReset(interruptQueue);
|
||||||
|
tt::kernel::delayMillis(50);
|
||||||
|
xQueueReset(interruptQueue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -56,17 +65,15 @@ UnPhoneFeatures::~UnPhoneFeatures() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool UnPhoneFeatures::initPowerSwitch() {
|
bool UnPhoneFeatures::initPowerSwitch() {
|
||||||
uint64_t power_pin_mask = BIT64(pin::POWER_SWITCH);
|
gpio_config_t config = {
|
||||||
|
.pin_bit_mask = BIT64(pin::POWER_SWITCH),
|
||||||
gpio_config_t power_gpio_config = {
|
|
||||||
.pin_bit_mask = power_pin_mask,
|
|
||||||
.mode = GPIO_MODE_INPUT,
|
.mode = GPIO_MODE_INPUT,
|
||||||
.pull_up_en = GPIO_PULLUP_DISABLE,
|
.pull_up_en = GPIO_PULLUP_DISABLE,
|
||||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||||
.intr_type = GPIO_INTR_POSEDGE,
|
.intr_type = GPIO_INTR_POSEDGE,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (gpio_config(&power_gpio_config) != ESP_OK) {
|
if (gpio_config(&config) != ESP_OK) {
|
||||||
TT_LOG_E(TAG, "Power pin init failed");
|
TT_LOG_E(TAG, "Power pin init failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -81,6 +88,11 @@ bool UnPhoneFeatures::initPowerSwitch() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool UnPhoneFeatures::initNavButtons() {
|
bool UnPhoneFeatures::initNavButtons() {
|
||||||
|
if (!initGpioExpander()) {
|
||||||
|
TT_LOG_E(TAG, "GPIO expander init failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
interruptQueue = xQueueCreate(4, sizeof(int));
|
interruptQueue = xQueueCreate(4, sizeof(int));
|
||||||
|
|
||||||
buttonHandlingThread.setName("unphone_buttons");
|
buttonHandlingThread.setName("unphone_buttons");
|
||||||
@ -89,20 +101,25 @@ bool UnPhoneFeatures::initNavButtons() {
|
|||||||
buttonHandlingThread.setCallback(buttonHandlingThreadMain, &buttonHandlingThreadInterruptRequest);
|
buttonHandlingThread.setCallback(buttonHandlingThreadMain, &buttonHandlingThreadInterruptRequest);
|
||||||
buttonHandlingThread.start();
|
buttonHandlingThread.start();
|
||||||
|
|
||||||
uint64_t input_pin_mask =
|
uint64_t pin_mask =
|
||||||
BIT64(pin::BUTTON1) |
|
BIT64(pin::BUTTON1) |
|
||||||
BIT64(pin::BUTTON2) |
|
BIT64(pin::BUTTON2) |
|
||||||
BIT64(pin::BUTTON3);
|
BIT64(pin::BUTTON3);
|
||||||
|
|
||||||
gpio_config_t input_gpio_config = {
|
gpio_config_t config = {
|
||||||
.pin_bit_mask = input_pin_mask,
|
.pin_bit_mask = pin_mask,
|
||||||
.mode = GPIO_MODE_INPUT,
|
.mode = GPIO_MODE_INPUT,
|
||||||
.pull_up_en = GPIO_PULLUP_ENABLE,
|
.pull_up_en = GPIO_PULLUP_ENABLE,
|
||||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||||
.intr_type = GPIO_INTR_NEGEDGE,
|
/**
|
||||||
|
* We have to listen to the button release (= positive signal).
|
||||||
|
* If we listen to button press, the buttons might create more than 1 signal
|
||||||
|
* when they are continuously pressed.
|
||||||
|
*/
|
||||||
|
.intr_type = GPIO_INTR_POSEDGE,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (gpio_config(&input_gpio_config) != ESP_OK) {
|
if (gpio_config(&config) != ESP_OK) {
|
||||||
TT_LOG_E(TAG, "Nav button pin init failed");
|
TT_LOG_E(TAG, "Nav button pin init failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -125,7 +142,7 @@ bool UnPhoneFeatures::initOutputPins() {
|
|||||||
BIT64(pin::IR_LEDS) |
|
BIT64(pin::IR_LEDS) |
|
||||||
BIT64(pin::LED_RED);
|
BIT64(pin::LED_RED);
|
||||||
|
|
||||||
gpio_config_t output_gpio_config = {
|
gpio_config_t config = {
|
||||||
.pin_bit_mask = output_pin_mask,
|
.pin_bit_mask = output_pin_mask,
|
||||||
.mode = GPIO_MODE_OUTPUT,
|
.mode = GPIO_MODE_OUTPUT,
|
||||||
.pull_up_en = GPIO_PULLUP_DISABLE,
|
.pull_up_en = GPIO_PULLUP_DISABLE,
|
||||||
@ -133,7 +150,7 @@ bool UnPhoneFeatures::initOutputPins() {
|
|||||||
.intr_type = GPIO_INTR_DISABLE,
|
.intr_type = GPIO_INTR_DISABLE,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (gpio_config(&output_gpio_config) != ESP_OK) {
|
if (gpio_config(&config) != ESP_OK) {
|
||||||
TT_LOG_E(TAG, "Output pin init failed");
|
TT_LOG_E(TAG, "Output pin init failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -165,6 +182,11 @@ bool UnPhoneFeatures::initGpioExpander() {
|
|||||||
bool UnPhoneFeatures::init() {
|
bool UnPhoneFeatures::init() {
|
||||||
TT_LOG_I(TAG, "init");
|
TT_LOG_I(TAG, "init");
|
||||||
|
|
||||||
|
if (!initGpioExpander()) {
|
||||||
|
TT_LOG_E(TAG, "GPIO expander init failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!initNavButtons()) {
|
if (!initNavButtons()) {
|
||||||
TT_LOG_E(TAG, "Input pin init failed");
|
TT_LOG_E(TAG, "Input pin init failed");
|
||||||
return false;
|
return false;
|
||||||
@ -180,11 +202,6 @@ bool UnPhoneFeatures::init() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!initGpioExpander()) {
|
|
||||||
TT_LOG_E(TAG, "GPIO expander init failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
- Fix bug in T-Deck/etc: esp_lvgl_port settings has a large stack size (~9kB) to fix an issue where the T-Deck would get a stackoverflow. This sometimes happens when WiFi is auto-enabled and you open the app while it is still connecting.
|
- Fix bug in T-Deck/etc: esp_lvgl_port settings has a large stack size (~9kB) to fix an issue where the T-Deck would get a stackoverflow. This sometimes happens when WiFi is auto-enabled and you open the app while it is still connecting.
|
||||||
- M5Stack Core only shows 4MB of SPIRAM in use
|
- M5Stack Core only shows 4MB of SPIRAM in use
|
||||||
- Try to improve Core2 and CoreS3 performance by setting swap_bytes of display driver to false (this is a software operation on the display buffer!) and use 24 bit colour mode if needed
|
- Try to improve Core2 and CoreS3 performance by setting swap_bytes of display driver to false (this is a software operation on the display buffer!) and use 24 bit colour mode if needed
|
||||||
|
- Files app: When SD card is not mounted, don't show it
|
||||||
|
|
||||||
# TODOs
|
# TODOs
|
||||||
- Boards' CMakeLists.txt manually declare each source folder. Update them all to do a recursive search of all folders.
|
- Boards' CMakeLists.txt manually declare each source folder. Update them all to do a recursive search of all folders.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user