Fix race conditions during sleep/wakeup, where SPI/TWI could be disabled while transaction were in progress (https://github.com/JF002/Pinetime/issues/60).
This commit is contained in:
parent
d757344f1b
commit
20f5b0ffba
3 changed files with 34 additions and 18 deletions
|
@ -105,22 +105,33 @@ void SystemTask::Work() {
|
||||||
Messages message = static_cast<Messages >(msg);
|
Messages message = static_cast<Messages >(msg);
|
||||||
switch(message) {
|
switch(message) {
|
||||||
case Messages::GoToRunning:
|
case Messages::GoToRunning:
|
||||||
isSleeping = false;
|
spi.Wakeup();
|
||||||
|
twiMaster.Wakeup();
|
||||||
|
|
||||||
|
spiNorFlash.Wakeup();
|
||||||
|
lcd.Wakeup();
|
||||||
|
touchPanel.Wakeup();
|
||||||
|
|
||||||
|
displayApp->PushMessage(Applications::DisplayApp::Messages::GoToRunning);
|
||||||
|
displayApp->PushMessage(Applications::DisplayApp::Messages::UpdateBatteryLevel);
|
||||||
|
|
||||||
xTimerStart(idleTimer, 0);
|
xTimerStart(idleTimer, 0);
|
||||||
nimbleController.StartAdvertising();
|
nimbleController.StartAdvertising();
|
||||||
|
isSleeping = false;
|
||||||
|
isWakingUp = false;
|
||||||
break;
|
break;
|
||||||
case Messages::GoToSleep:
|
case Messages::GoToSleep:
|
||||||
|
isGoingToSleep = true;
|
||||||
NRF_LOG_INFO("[SystemTask] Going to sleep");
|
NRF_LOG_INFO("[SystemTask] Going to sleep");
|
||||||
xTimerStop(idleTimer, 0);
|
xTimerStop(idleTimer, 0);
|
||||||
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep);
|
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep);
|
||||||
isSleeping = true;
|
|
||||||
break;
|
break;
|
||||||
case Messages::OnNewTime:
|
case Messages::OnNewTime:
|
||||||
ReloadIdleTimer();
|
ReloadIdleTimer();
|
||||||
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateDateTime);
|
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateDateTime);
|
||||||
break;
|
break;
|
||||||
case Messages::OnNewNotification:
|
case Messages::OnNewNotification:
|
||||||
if(isSleeping) GoToRunning();
|
if(isSleeping && !isWakingUp) GoToRunning();
|
||||||
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::NewNotification);
|
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::NewNotification);
|
||||||
break;
|
break;
|
||||||
case Messages::BleConnected:
|
case Messages::BleConnected:
|
||||||
|
@ -130,7 +141,7 @@ void SystemTask::Work() {
|
||||||
break;
|
break;
|
||||||
case Messages::BleFirmwareUpdateStarted:
|
case Messages::BleFirmwareUpdateStarted:
|
||||||
doNotGoToSleep = true;
|
doNotGoToSleep = true;
|
||||||
if(isSleeping) GoToRunning();
|
if(isSleeping && !isWakingUp) GoToRunning();
|
||||||
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::BleFirmwareUpdateStarted);
|
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::BleFirmwareUpdateStarted);
|
||||||
break;
|
break;
|
||||||
case Messages::BleFirmwareUpdateFinished:
|
case Messages::BleFirmwareUpdateFinished:
|
||||||
|
@ -152,6 +163,8 @@ void SystemTask::Work() {
|
||||||
|
|
||||||
spi.Sleep();
|
spi.Sleep();
|
||||||
twiMaster.Sleep();
|
twiMaster.Sleep();
|
||||||
|
isSleeping = true;
|
||||||
|
isGoingToSleep = false;
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
@ -180,31 +193,27 @@ void SystemTask::Work() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemTask::OnButtonPushed() {
|
void SystemTask::OnButtonPushed() {
|
||||||
|
if(isGoingToSleep) return;
|
||||||
if(!isSleeping) {
|
if(!isSleeping) {
|
||||||
NRF_LOG_INFO("[SystemTask] Button pushed");
|
NRF_LOG_INFO("[SystemTask] Button pushed");
|
||||||
PushMessage(Messages::OnButtonEvent);
|
PushMessage(Messages::OnButtonEvent);
|
||||||
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::ButtonPushed);
|
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::ButtonPushed);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if(!isWakingUp) {
|
||||||
NRF_LOG_INFO("[SystemTask] Button pushed, waking up");
|
NRF_LOG_INFO("[SystemTask] Button pushed, waking up");
|
||||||
GoToRunning();
|
GoToRunning();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SystemTask::GoToRunning() {
|
void SystemTask::GoToRunning() {
|
||||||
|
isWakingUp = true;
|
||||||
PushMessage(Messages::GoToRunning);
|
PushMessage(Messages::GoToRunning);
|
||||||
spi.Wakeup();
|
|
||||||
twiMaster.Wakeup();
|
|
||||||
|
|
||||||
spiNorFlash.Wakeup();
|
|
||||||
lcd.Wakeup();
|
|
||||||
touchPanel.Wakeup();
|
|
||||||
|
|
||||||
displayApp->PushMessage(Applications::DisplayApp::Messages::GoToRunning);
|
|
||||||
displayApp->PushMessage(Applications::DisplayApp::Messages::UpdateBatteryLevel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemTask::OnTouchEvent() {
|
void SystemTask::OnTouchEvent() {
|
||||||
|
if(isGoingToSleep) return ;
|
||||||
NRF_LOG_INFO("[SystemTask] Touch event");
|
NRF_LOG_INFO("[SystemTask] Touch event");
|
||||||
if(!isSleeping) {
|
if(!isSleeping) {
|
||||||
PushMessage(Messages::OnTouchEvent);
|
PushMessage(Messages::OnTouchEvent);
|
||||||
|
@ -213,6 +222,9 @@ void SystemTask::OnTouchEvent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemTask::PushMessage(SystemTask::Messages msg) {
|
void SystemTask::PushMessage(SystemTask::Messages msg) {
|
||||||
|
if(msg == Messages::GoToSleep) {
|
||||||
|
isGoingToSleep = true;
|
||||||
|
}
|
||||||
BaseType_t xHigherPriorityTaskWoken;
|
BaseType_t xHigherPriorityTaskWoken;
|
||||||
xHigherPriorityTaskWoken = pdFALSE;
|
xHigherPriorityTaskWoken = pdFALSE;
|
||||||
xQueueSendFromISR(systemTaksMsgQueue, &msg, &xHigherPriorityTaskWoken);
|
xQueueSendFromISR(systemTaksMsgQueue, &msg, &xHigherPriorityTaskWoken);
|
||||||
|
@ -229,6 +241,6 @@ void SystemTask::OnIdle() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemTask::ReloadIdleTimer() const {
|
void SystemTask::ReloadIdleTimer() const {
|
||||||
if(isSleeping) return;
|
if(isSleeping || isGoingToSleep) return;
|
||||||
xTimerReset(idleTimer, 0);
|
xTimerReset(idleTimer, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,9 @@ namespace Pinetime {
|
||||||
Pinetime::Controllers::Ble& bleController;
|
Pinetime::Controllers::Ble& bleController;
|
||||||
Pinetime::Controllers::DateTime& dateTimeController;
|
Pinetime::Controllers::DateTime& dateTimeController;
|
||||||
QueueHandle_t systemTaksMsgQueue;
|
QueueHandle_t systemTaksMsgQueue;
|
||||||
bool isSleeping = false;
|
std::atomic<bool> isSleeping{false};
|
||||||
|
std::atomic<bool> isGoingToSleep{false};
|
||||||
|
std::atomic<bool> isWakingUp{false};
|
||||||
Pinetime::Drivers::Watchdog watchdog;
|
Pinetime::Drivers::Watchdog watchdog;
|
||||||
Pinetime::Drivers::WatchdogView watchdogView;
|
Pinetime::Drivers::WatchdogView watchdogView;
|
||||||
Pinetime::Controllers::NotificationManager& notificationManager;
|
Pinetime::Controllers::NotificationManager& notificationManager;
|
||||||
|
|
|
@ -140,9 +140,11 @@ void TwiMaster::Write(uint8_t deviceAddress, const uint8_t *data, size_t size, b
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwiMaster::Sleep() {
|
void TwiMaster::Sleep() {
|
||||||
|
while(twiBaseAddress->ENABLE != 0) {
|
||||||
|
twiBaseAddress->ENABLE = (TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos);
|
||||||
|
}
|
||||||
nrf_gpio_cfg_default(6);
|
nrf_gpio_cfg_default(6);
|
||||||
nrf_gpio_cfg_default(7);
|
nrf_gpio_cfg_default(7);
|
||||||
twiBaseAddress->ENABLE = 0;
|
|
||||||
NRF_LOG_INFO("[TWIMASTER] Sleep");
|
NRF_LOG_INFO("[TWIMASTER] Sleep");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue