Skip to content

Commit

Permalink
Fix race conditions during sleep/wakeup, where SPI/TWI could be disab…
Browse files Browse the repository at this point in the history
…led while transaction were in progress (#60).
  • Loading branch information
JF002 committed Sep 13, 2020
1 parent d757344 commit 20f5b0f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 18 deletions.
44 changes: 28 additions & 16 deletions src/SystemTask/SystemTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,22 +105,33 @@ void SystemTask::Work() {
Messages message = static_cast<Messages >(msg);
switch(message) {
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);
nimbleController.StartAdvertising();
isSleeping = false;
isWakingUp = false;
break;
case Messages::GoToSleep:
isGoingToSleep = true;
NRF_LOG_INFO("[SystemTask] Going to sleep");
xTimerStop(idleTimer, 0);
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep);
isSleeping = true;
break;
case Messages::OnNewTime:
ReloadIdleTimer();
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateDateTime);
break;
case Messages::OnNewNotification:
if(isSleeping) GoToRunning();
if(isSleeping && !isWakingUp) GoToRunning();
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::NewNotification);
break;
case Messages::BleConnected:
Expand All @@ -130,7 +141,7 @@ void SystemTask::Work() {
break;
case Messages::BleFirmwareUpdateStarted:
doNotGoToSleep = true;
if(isSleeping) GoToRunning();
if(isSleeping && !isWakingUp) GoToRunning();
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::BleFirmwareUpdateStarted);
break;
case Messages::BleFirmwareUpdateFinished:
Expand All @@ -152,6 +163,8 @@ void SystemTask::Work() {

spi.Sleep();
twiMaster.Sleep();
isSleeping = true;
isGoingToSleep = false;
break;
default: break;
}
Expand Down Expand Up @@ -180,31 +193,27 @@ void SystemTask::Work() {
}

void SystemTask::OnButtonPushed() {
if(isGoingToSleep) return;
if(!isSleeping) {
NRF_LOG_INFO("[SystemTask] Button pushed");
PushMessage(Messages::OnButtonEvent);
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::ButtonPushed);
}
else {
NRF_LOG_INFO("[SystemTask] Button pushed, waking up");
GoToRunning();
if(!isWakingUp) {
NRF_LOG_INFO("[SystemTask] Button pushed, waking up");
GoToRunning();
}
}
}

void SystemTask::GoToRunning() {
isWakingUp = true;
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() {
if(isGoingToSleep) return ;
NRF_LOG_INFO("[SystemTask] Touch event");
if(!isSleeping) {
PushMessage(Messages::OnTouchEvent);
Expand All @@ -213,6 +222,9 @@ void SystemTask::OnTouchEvent() {
}

void SystemTask::PushMessage(SystemTask::Messages msg) {
if(msg == Messages::GoToSleep) {
isGoingToSleep = true;
}
BaseType_t xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE;
xQueueSendFromISR(systemTaksMsgQueue, &msg, &xHigherPriorityTaskWoken);
Expand All @@ -229,6 +241,6 @@ void SystemTask::OnIdle() {
}

void SystemTask::ReloadIdleTimer() const {
if(isSleeping) return;
if(isSleeping || isGoingToSleep) return;
xTimerReset(idleTimer, 0);
}
4 changes: 3 additions & 1 deletion src/SystemTask/SystemTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ namespace Pinetime {
Pinetime::Controllers::Ble& bleController;
Pinetime::Controllers::DateTime& dateTimeController;
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::WatchdogView watchdogView;
Pinetime::Controllers::NotificationManager& notificationManager;
Expand Down
4 changes: 3 additions & 1 deletion src/drivers/TwiMaster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,11 @@ void TwiMaster::Write(uint8_t deviceAddress, const uint8_t *data, size_t size, b
}

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(7);
twiBaseAddress->ENABLE = 0;
NRF_LOG_INFO("[TWIMASTER] Sleep");
}

Expand Down

0 comments on commit 20f5b0f

Please sign in to comment.