Skip to content

Commit f7c33e0

Browse files
committed
Add semaphore protection for lastSetupMenuChange
This should prevent the occasional glitching during button setup
1 parent 61f5ead commit f7c33e0

File tree

3 files changed

+40
-7
lines changed

3 files changed

+40
-7
lines changed

Firmware/RTK_Everywhere/RTK_Everywhere.ino

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,40 @@ uint32_t rtcmLastPacketSent; // Time stamp of RTCM going out (to NTRIP Server, E
872872

873873
uint32_t maxSurveyInWait_s = 60L * 15L; // Re-start survey-in after X seconds
874874

875-
uint32_t lastSetupMenuChange; // Limits how much time is spent in the setup menu
875+
typedef struct {
876+
uint32_t timer;
877+
878+
SemaphoreHandle_t updateSemaphore = NULL;
879+
880+
void setTimerToMillis()
881+
{
882+
if (updateSemaphore == NULL)
883+
updateSemaphore = xSemaphoreCreateMutex();
884+
if (xSemaphoreTake(updateSemaphore, 10 / portTICK_PERIOD_MS) == pdPASS)
885+
{
886+
timer = millis();
887+
xSemaphoreGive(updateSemaphore);
888+
}
889+
}
890+
891+
unsigned long millisSinceUpdate()
892+
{
893+
unsigned long retVal = 0;
894+
if (updateSemaphore == NULL)
895+
updateSemaphore = xSemaphoreCreateMutex();
896+
if (xSemaphoreTake(updateSemaphore, 10 / portTICK_PERIOD_MS) == pdPASS)
897+
{
898+
retVal = millis() - timer;
899+
xSemaphoreGive(updateSemaphore);
900+
}
901+
return retVal;
902+
}
903+
} semaphoreProtectedTimer;
904+
// Needs a mutex because the timer is updated by the button task
905+
// but read by stateUpdate the loop. Prevents a race condition
906+
// and the occasional glitching seen in the button menu
907+
semaphoreProtectedTimer lastSetupMenuChange; // Limits how much time is spent in the setup menu
908+
876909
uint32_t lastTestMenuChange; // Avoids exiting the test menu for at least 1 second
877910
uint8_t setupSelectedButton =
878911
0; // In Display Setup, start displaying at this button. This is the selected (highlighted) button.

Firmware/RTK_Everywhere/States.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ void stateUpdate()
399399
break;
400400

401401
case (STATE_DISPLAY_SETUP): {
402-
if ((millis() - lastSetupMenuChange) > 10000) // Exit Setup after 10s
402+
if (lastSetupMenuChange.millisSinceUpdate() > 10000) // Exit Setup after 10s
403403
{
404404
firstButtonThrownOut = false;
405405
changeState(lastSystemState); // Return to the last system state

Firmware/RTK_Everywhere/Tasks.ino

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2183,7 +2183,7 @@ void buttonCheckTask(void *e)
21832183
else if ((systemState == STATE_BASE_NOT_STARTED) && (firstRoverStart == true) &&
21842184
(buttonPressedFor(500) == true))
21852185
{
2186-
lastSetupMenuChange = millis(); // Prevent a timeout during state change
2186+
lastSetupMenuChange.setTimerToMillis(); // Prevent a timeout during state change
21872187
forceSystemStateUpdate = true;
21882188
requestChangeState(STATE_TEST);
21892189
}
@@ -2216,7 +2216,7 @@ void buttonCheckTask(void *e)
22162216
case STATE_NTPSERVER_SYNC:
22172217
lastSystemState = systemState; // Remember this state to return if needed
22182218
requestChangeState(STATE_DISPLAY_SETUP);
2219-
lastSetupMenuChange = millis();
2219+
lastSetupMenuChange.setTimerToMillis();
22202220
setupSelectedButton = 0; // Highlight the first button
22212221
showMenu = false;
22222222
break;
@@ -2225,7 +2225,7 @@ void buttonCheckTask(void *e)
22252225
// If we are displaying the setup menu, a single tap will cycle through possible system states
22262226
// Exit into new system state on double tap - see below
22272227
// Exit display setup into previous state after ~10s - see updateSystemState()
2228-
lastSetupMenuChange = millis();
2228+
lastSetupMenuChange.setTimerToMillis();
22292229

22302230
forceDisplayUpdate = true; // User is interacting so repaint display quickly
22312231

@@ -2262,7 +2262,7 @@ void buttonCheckTask(void *e)
22622262

22632263
case STATE_TESTING:
22642264
// If we are in testing, return to Base Not Started
2265-
lastSetupMenuChange = millis(); // Prevent a timeout during state change
2265+
lastSetupMenuChange.setTimerToMillis(); // Prevent a timeout during state change
22662266
baseCasterDisableOverride(); // Leave Caster mode
22672267
requestChangeState(STATE_BASE_NOT_STARTED);
22682268
break;
@@ -2287,7 +2287,7 @@ void buttonCheckTask(void *e)
22872287
// If we are displaying the setup menu, a single tap will cycle through possible system states - see
22882288
// above Exit into new system state on double tap Exit display setup into previous state after ~10s
22892289
// - see updateSystemState()
2290-
lastSetupMenuChange = millis(); // Prevent a timeout during state change
2290+
lastSetupMenuChange.setTimerToMillis(); // Prevent a timeout during state change
22912291
uint8_t thisIsButton = 0;
22922292
for (auto it = setupButtons.begin(); it != setupButtons.end(); it = std::next(it))
22932293
{

0 commit comments

Comments
 (0)