From de1bf7d26b58ab0202a23b3977a455a2cf0a5434 Mon Sep 17 00:00:00 2001 From: Macoy Madson Date: Thu, 5 Nov 2020 22:06:58 -0800 Subject: [PATCH] Fixed sleep mode issues * Main loop now has simple state machine for easier flow understanding * Expose GPIO pin button mappings in input.h * Ignore potential wake input until all buttons released * Monitor all buttons for wake * Add more cases for wakeup reason * Reset input to what Odroid_PollInput() expects after waking * Removed commented tile draw code --- app/src/main.c | 462 ++++++++++++++--------------------------- app/src/odroid/input.c | 16 +- app/src/odroid/input.h | 11 + app/src/odroid/sleep.c | 57 ++++- 4 files changed, 229 insertions(+), 317 deletions(-) diff --git a/app/src/main.c b/app/src/main.c index 73fb9ba..225ae17 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -20,7 +20,7 @@ static bool drawTimeSinceBoot = false; static bool drawFrameRate = true; /* static bool printInput = true; */ -static bool printInput = false; +static bool printInput = true; static bool enableLowFrameRate = true; @@ -38,137 +38,22 @@ static uint16_t gFramebuffer[LCD_WIDTH * LCD_HEIGHT]; /* 0x0000, */ /* }; */ -static const uint16_t darkPalette[4] = -{ - 0x0000, - 0xAA52, - 0x55AD, - 0xFFFF, +static const uint16_t darkPalette[4] = { + 0x0000, + 0xAA52, + 0x55AD, + 0xFFFF, }; static const uint16_t* palette = darkPalette; -static const uint8_t tiles[][16*16] = -{ - // White - { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - }, - - // Light Grey - { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, - 0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - }, - - // Dark Grey - { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0, - 0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - }, - - // Black - { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,3,3,3,3,3,3,3,3,3,3,3,3,0,0, - 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, - 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, - 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, - 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, - 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, - 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, - 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, - 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, - 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, - 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, - 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, - 0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0, - 0,0,3,3,3,3,3,3,3,3,3,3,3,3,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - }, -}; - -static int tileBuffer[15][40] = -{ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0}, - {0, 0, 3, 0, 0, 0, 3, 3, 3, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0}, - {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, -}; - -void DrawTile(int index, int x, int y) +void updateBatteryIndicator() { - int startX = x * 16; - int startY = y * 16; - - for (int row = 0; row < 16; ++row) - { - for (int col = 0; col < 16; ++col) - { - uint8_t paletteIndex = tiles[index][row * 16 + col]; - - int screenY = startY + row; - int screenX = startX + col; - - uint16_t color = palette[paletteIndex]; - - gFramebuffer[screenY * LCD_WIDTH + screenX] = color; - } - } + float batteryPercentage = Odroid_ReadBatteryLevelPercentage(); + if (batteryPercentage < 15.f) + Odroid_EnableBatteryLight(); + else + Odroid_DisableBatteryLight(); } void app_main(void) @@ -184,7 +69,6 @@ void app_main(void) /* uint8_t frameIndex = 0; */ /* char snapFilename[20]; */ - /* int xLeft = 0; */ bool timerRunning = false; int64_t timerStartMicroSecs = 0; @@ -197,213 +81,189 @@ void app_main(void) Odroid_Input lastFrameInput = {0}; - bool sleepMode = false; - bool backlightOn = true; - bool waitForSleepActivateRelease = false; + typedef enum AppState + { + Sleeping, + Awake_WaitingForWakeButtonRelease, + Awake, + } AppState; + AppState state = Awake; while (true) { - memset(gFramebuffer, palette[0], 320 * 240 * 2); - + if (state == Awake || state == Awake_WaitingForWakeButtonRelease) { - float batteryPercentage = Odroid_ReadBatteryLevelPercentage(); - if (batteryPercentage < 15.f) - Odroid_EnableBatteryLight(); - else - Odroid_DisableBatteryLight(); - } + memset(gFramebuffer, palette[0], 320 * 240 * 2); - int64_t currentTimeMicroSecs = esp_timer_get_time(); + updateBatteryIndicator(); - Odroid_Input input = Odroid_PollInput(); - bool hasInputsThisFrame = Odroid_HasAnyInput(&input); - if (hasInputsThisFrame) - timeSinceLastInputMicroSecs = esp_timer_get_time(); + int64_t currentTimeMicroSecs = esp_timer_get_time(); - if (printInput) - Odroid_PrintInputState(&input); + Odroid_Input input = Odroid_PollInput(); + bool hasInputsThisFrame = Odroid_HasAnyInput(&input); + if (hasInputsThisFrame) + timeSinceLastInputMicroSecs = esp_timer_get_time(); - // Sleep mode - if (sleepMode) - { - // Try to save battery while still listening to inputs - while (Odroid_EnterLightSleep(lightSleepMicroseconds)) + if (printInput) + Odroid_PrintInputState(&input); + + if (state == Awake_WaitingForWakeButtonRelease) { - float batteryPercentage = Odroid_ReadBatteryLevelPercentage(); - if (batteryPercentage < 15.f) - Odroid_EnableBatteryLight(); - else - Odroid_DisableBatteryLight(); + if (!hasInputsThisFrame) + { + state = Awake; + lastFrameInput = input; + } } - sleepMode = false; - timeSinceLastInputMicroSecs = esp_timer_get_time(); + bool buttonPressedForSleepMode = false; - continue; - } - - if (!sleepMode && !backlightOn) - { - Odroid_BacklightInit(); - backlightOn = true; - } - - if (input.a && !lastFrameInput.a) - { - printf("Pause timer\n"); - timerRunning = !timerRunning; + // Only take inputs after wake button released + if (state == Awake) + { + if (input.a && !lastFrameInput.a) + { + printf("Toggle timer\n"); + timerRunning = !timerRunning; + + if (timerRunning) + timerStartMicroSecs = currentTimeMicroSecs; + else + timerTotalMicroSecsPrePause += currentTimeMicroSecs - timerStartMicroSecs; + } + + if (input.start && !lastFrameInput.start) + { + printf("Reset timer\n"); + + timerRunning = false; + timerTotalMicroSecsPrePause = 0; + } + + buttonPressedForSleepMode = (lastFrameInput.b && !input.b); + } - if (timerRunning) - timerStartMicroSecs = currentTimeMicroSecs; - else - timerTotalMicroSecsPrePause += currentTimeMicroSecs - timerStartMicroSecs; + bool noInputsSleepMode = + currentTimeMicroSecs - timeSinceLastInputMicroSecs > autoSleepModeMicroseconds; + if (noInputsSleepMode || buttonPressedForSleepMode) + { + state = Sleeping; + + printf("Entering sleep reason: "); + if (noInputsSleepMode) + printf("No inputs in %lld seconds ", autoSleepModeMicroseconds / 1000000); + if (buttonPressedForSleepMode) + printf("Sleep button pressed "); + printf("\n"); + } - /* esp_err_t err = ledc_stop(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 0); */ - /* if (err != ESP_OK) */ - /* { */ - /* printf("%s: ledc_stop failed.\n", __func__); */ - /* } */ - } + // Timer + { + char string[18]; + int64_t currentTimeMicroSecs = esp_timer_get_time(); + float timerSeconds = timerRunning ? + ((timerTotalMicroSecsPrePause + + (currentTimeMicroSecs - timerStartMicroSecs)) / + 1000000.f) : + timerTotalMicroSecsPrePause / 1000000.f; + snprintf(string, ArraySize(string), "%d:%.2d", (int)timerSeconds / 60, + (int)timerSeconds % 60); + DrawText(gFramebuffer, string, ArraySize(string), 3, 5, palette[3]); + + if (!timerRunning) + { + snprintf(string, ArraySize(string), "Paused"); + DrawText(gFramebuffer, string, ArraySize(string), 3, 6, palette[3]); + } + } - if (input.start && !lastFrameInput.start) - { - printf("Reset timer\n"); + // Battery + if (drawBatteryPercent) + { + char string[10]; + snprintf(string, ArraySize(string), "B: %.0f", Odroid_ReadBatteryLevelPercentage()); + DrawText(gFramebuffer, string, ArraySize(string), 0, 0, palette[3]); + } - timerRunning = false; - timerTotalMicroSecsPrePause = 0; - } + if (drawBatteryVoltage) + { + char string[10]; + snprintf(string, ArraySize(string), "B: %03d", Odroid_ReadBatteryLevel()); + DrawText(gFramebuffer, string, ArraySize(string), 0, 3, palette[3]); + } - bool sleepModeActivate = - currentTimeMicroSecs - timeSinceLastInputMicroSecs > autoSleepModeMicroseconds || - (input.b && !lastFrameInput.b); - if (sleepModeActivate) - { - if (backlightOn) + // Time since boot + if (drawTimeSinceBoot) { - // TODO: Tell LCD driver to enter sleep - // TODO: Use esp light sleep mode - Odroid_BacklightDeinit(); + char string[10]; + int64_t timeSinceBoot = esp_timer_get_time(); + snprintf(string, ArraySize(string), "%lld", timeSinceBoot); + DrawText(gFramebuffer, string, ArraySize(string), 0, 1, palette[3]); } - else - Odroid_BacklightInit(); - backlightOn = !backlightOn; - sleepMode = !sleepMode; - } + // Frame time + if (drawFrameRate) + { + char string[10]; + int64_t currentTimeMicroSecs = esp_timer_get_time(); + int64_t frameTimeMicroSecs = currentTimeMicroSecs - lastFrameTimeMicroSecs; + snprintf(string, ArraySize(string), "%.2f HZ", 1000000.f / frameTimeMicroSecs); + DrawText(gFramebuffer, string, ArraySize(string), 12, 0, palette[3]); + lastFrameTimeMicroSecs = currentTimeMicroSecs; + } - // Movement - /* if (input.left) */ - /* { */ - /* xLeft -= 1; */ - - /* if (xLeft < 0) */ - /* { */ - /* xLeft = 39; */ - /* } */ - /* } */ - - /* else if (input.right) */ - /* { */ - /* xLeft += 1; */ - - /* if (xLeft > 39) */ - /* { */ - /* xLeft = 0; */ - /* } */ - /* } */ - - // Tile drawing - /* for (int tileY = 0; tileY < 15; ++tileY) */ - /* { */ - /* for (int tileX = xLeft; tileX < xLeft + 20; ++tileX) */ - /* { */ - /* int tile = tileX % 40; */ - - /* int tileIndex = tileBuffer[tileY][tile]; */ - - /* DrawTile(tileIndex, tileX - xLeft, tileY); */ - /* } */ - /* } */ - - // Battery - if (drawBatteryPercent) - { - char string[10]; - snprintf(string, ArraySize(string), "B: %.0f", Odroid_ReadBatteryLevelPercentage()); - DrawText(gFramebuffer, string, ArraySize(string), 0, 0, palette[3]); - } + Odroid_DrawFrame(gFramebuffer); - if (drawBatteryVoltage) - { - char string[10]; - snprintf(string, ArraySize(string), "B: %03d", Odroid_ReadBatteryLevel()); - DrawText(gFramebuffer, string, ArraySize(string), 0, 3, palette[3]); - } + // Just high enough that button presses feel responsive + if (enableLowFrameRate) + vTaskDelay(5); - // Time since boot - if (drawTimeSinceBoot) - { - char string[10]; - int64_t timeSinceBoot = esp_timer_get_time(); - snprintf(string, ArraySize(string), "%lld", timeSinceBoot); - DrawText(gFramebuffer, string, ArraySize(string), 0, 1, palette[3]); - } + lastFrameInput = input; - // Frame time - if (drawFrameRate) - { - char string[10]; - int64_t currentTimeMicroSecs = esp_timer_get_time(); - int64_t frameTimeMicroSecs = currentTimeMicroSecs - lastFrameTimeMicroSecs; - snprintf(string, ArraySize(string), "%.2f HZ", 1000000.f / frameTimeMicroSecs); - DrawText(gFramebuffer, string, ArraySize(string), 12, 0, palette[3]); - lastFrameTimeMicroSecs = currentTimeMicroSecs; - } + // Save screenshots for making gifs + /* if (input.menu) */ + /* { */ + /* snprintf(snapFilename, 20, "/sdcard/frame%02d", frameIndex); */ - // Timer - { - char string[18]; - int64_t currentTimeMicroSecs = esp_timer_get_time(); - float timerSeconds = - timerRunning ? - ((timerTotalMicroSecsPrePause + (currentTimeMicroSecs - timerStartMicroSecs)) / - 1000000.f) : - timerTotalMicroSecsPrePause / 1000000.f; - snprintf(string, ArraySize(string), "%d:%.2d", (int)timerSeconds / 60, - (int)timerSeconds % 60); - DrawText(gFramebuffer, string, ArraySize(string), 3, 5, palette[3]); - - if (!timerRunning) - { - snprintf(string, ArraySize(string), "Paused"); - DrawText(gFramebuffer, string, ArraySize(string), 3, 6, palette[3]); - } - } + /* ESP_LOGI(LOG_TAG, "Writing snapshot to %s", snapFilename); */ - // Save screenshots for making gifs - /* if (input.menu) */ - /* { */ - /* snprintf(snapFilename, 20, "/sdcard/frame%02d", frameIndex); */ + /* FILE* snapFile = fopen(snapFilename, "wb"); */ + /* assert(snapFile); */ - /* ESP_LOGI(LOG_TAG, "Writing snapshot to %s", snapFilename); */ + /* fwrite(gFramebuffer, 1, LCD_WIDTH * LCD_HEIGHT * sizeof(gFramebuffer[0]), + * snapFile); */ - /* FILE* snapFile = fopen(snapFilename, "wb"); */ - /* assert(snapFile); */ + /* fclose(snapFile); */ - /* fwrite(gFramebuffer, 1, LCD_WIDTH * LCD_HEIGHT * sizeof(gFramebuffer[0]), snapFile); */ + /* ++frameIndex; */ + /* } */ + } - /* fclose(snapFile); */ + if (state == Sleeping) + { + // Enter sleep + { + // TODO: Tell LCD driver to enter sleep + Odroid_BacklightDeinit(); + } - /* ++frameIndex; */ - /* } */ + // Try to save battery while still listening to inputs + // This loop is exited only if wake button is pressed + while (!Odroid_EnterLightSleep(lightSleepMicroseconds)) + { + updateBatteryIndicator(); + } - Odroid_DrawFrame(gFramebuffer); + // Exit sleep + { + // Count this input so sleep isn't immediately entered + timeSinceLastInputMicroSecs = esp_timer_get_time(); - // Just high enough that button presses feel responsive - if (enableLowFrameRate) - vTaskDelay(5); + Odroid_BacklightInit(); - lastFrameInput = input; + state = Awake_WaitingForWakeButtonRelease; + } + } } // Should never get here diff --git a/app/src/odroid/input.c b/app/src/odroid/input.c index ab0d46a..f21f2eb 100644 --- a/app/src/odroid/input.c +++ b/app/src/odroid/input.c @@ -7,14 +7,14 @@ static const char* LOG_TAG = "OdroidInput"; -static const gpio_num_t BUTTON_PIN_A = GPIO_NUM_32; -static const gpio_num_t BUTTON_PIN_B = GPIO_NUM_33; -static const gpio_num_t BUTTON_PIN_START = GPIO_NUM_39; -static const gpio_num_t BUTTON_PIN_SELECT = GPIO_NUM_27; -static const gpio_num_t BUTTON_PIN_VOLUME = GPIO_NUM_0; -static const gpio_num_t BUTTON_PIN_MENU = GPIO_NUM_13; -static const adc1_channel_t DPAD_PIN_X_AXIS = ADC1_GPIO34_CHANNEL; -static const adc1_channel_t DPAD_PIN_Y_AXIS = ADC1_GPIO35_CHANNEL; +const gpio_num_t BUTTON_PIN_A = GPIO_NUM_32; +const gpio_num_t BUTTON_PIN_B = GPIO_NUM_33; +const gpio_num_t BUTTON_PIN_START = GPIO_NUM_39; +const gpio_num_t BUTTON_PIN_SELECT = GPIO_NUM_27; +const gpio_num_t BUTTON_PIN_VOLUME = GPIO_NUM_0; +const gpio_num_t BUTTON_PIN_MENU = GPIO_NUM_13; +const adc1_channel_t DPAD_PIN_X_AXIS = ADC1_GPIO34_CHANNEL; +const adc1_channel_t DPAD_PIN_Y_AXIS = ADC1_GPIO35_CHANNEL; void Odroid_InitializeInput() diff --git a/app/src/odroid/input.h b/app/src/odroid/input.h index 0e477ae..7adf134 100644 --- a/app/src/odroid/input.h +++ b/app/src/odroid/input.h @@ -2,6 +2,8 @@ #include +#include +#include typedef struct { @@ -21,3 +23,12 @@ void Odroid_InitializeInput(void); Odroid_Input Odroid_PollInput(void); void Odroid_PrintInputState(Odroid_Input* input); int Odroid_HasAnyInput(Odroid_Input* input); + +extern const gpio_num_t BUTTON_PIN_A; +extern const gpio_num_t BUTTON_PIN_B; +extern const gpio_num_t BUTTON_PIN_START; +extern const gpio_num_t BUTTON_PIN_SELECT; +extern const gpio_num_t BUTTON_PIN_VOLUME; +extern const gpio_num_t BUTTON_PIN_MENU; +extern const adc1_channel_t DPAD_PIN_X_AXIS; +extern const adc1_channel_t DPAD_PIN_Y_AXIS; diff --git a/app/src/odroid/sleep.c b/app/src/odroid/sleep.c index 2055db3..e1ca440 100644 --- a/app/src/odroid/sleep.c +++ b/app/src/odroid/sleep.c @@ -10,9 +10,9 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" -// Button B -#define BUTTON_GPIO_NUM_DEFAULT GPIO_NUM_32 -#define BUTTON_WAKEUP_LEVEL_DEFAULT 1 +#include "input.h" + +#define BUTTON_WAKEUP_LEVEL_DEFAULT 0 // Returns whether button was pressed to wake // See Dependencies/esp-idf/examples/system/light_sleep/main/light_sleep_example_main.c @@ -20,12 +20,22 @@ bool Odroid_EnterLightSleep(int64_t timerAutoWakeupMicroSecs) { esp_sleep_enable_timer_wakeup(timerAutoWakeupMicroSecs); - const int button_gpio_num = BUTTON_GPIO_NUM_DEFAULT; const int wakeup_level = BUTTON_WAKEUP_LEVEL_DEFAULT; - gpio_config_t config = {.pin_bit_mask = BIT64(button_gpio_num), .mode = GPIO_MODE_INPUT}; + gpio_config_t config = {.pin_bit_mask = (1ULL << BUTTON_PIN_A) | (1ULL << BUTTON_PIN_B) | + (1ULL << BUTTON_PIN_START) | + (1ULL << BUTTON_PIN_SELECT) | + (1ULL << BUTTON_PIN_VOLUME) | (1ULL << BUTTON_PIN_MENU), + .mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_ENABLE}; ESP_ERROR_CHECK(gpio_config(&config)); - gpio_wakeup_enable(button_gpio_num, - wakeup_level == 0 ? GPIO_INTR_LOW_LEVEL : GPIO_INTR_HIGH_LEVEL); + + gpio_num_t buttonsToWatch[] = {BUTTON_PIN_A, BUTTON_PIN_B, BUTTON_PIN_START, + BUTTON_PIN_SELECT, BUTTON_PIN_VOLUME, BUTTON_PIN_MENU}; + for (int i = 0; i < sizeof(buttonsToWatch) / sizeof(buttonsToWatch[0]); ++i) + { + gpio_wakeup_enable(buttonsToWatch[i], + wakeup_level == 0 ? GPIO_INTR_LOW_LEVEL : GPIO_INTR_HIGH_LEVEL); + } esp_sleep_enable_gpio_wakeup(); printf("Entering light sleep\n"); @@ -49,8 +59,31 @@ bool Odroid_EnterLightSleep(int64_t timerAutoWakeupMicroSecs) case ESP_SLEEP_WAKEUP_TIMER: wakeup_reason = "timer"; break; + case ESP_SLEEP_WAKEUP_UNDEFINED: + wakeup_reason = "undefined"; + break; + case ESP_SLEEP_WAKEUP_ALL: + wakeup_reason = + "Not a wakeup cause, used to disable all wakeup sources with " + "esp_sleep_disable_wakeup_source."; + break; + case ESP_SLEEP_WAKEUP_EXT0: + wakeup_reason = "external signal using RTC_IO."; + break; + case ESP_SLEEP_WAKEUP_EXT1: + wakeup_reason = "external signal using RTC_CNTL."; + break; + case ESP_SLEEP_WAKEUP_TOUCHPAD: + wakeup_reason = "touchpad"; + break; + case ESP_SLEEP_WAKEUP_ULP: + wakeup_reason = "ULP program"; + break; case ESP_SLEEP_WAKEUP_GPIO: - wakeup_reason = "pin"; + wakeup_reason = "GPIO (light sleep only)"; + break; + case ESP_SLEEP_WAKEUP_UART: + wakeup_reason = "UART (light sleep only)"; break; default: wakeup_reason = "other"; @@ -60,5 +93,13 @@ bool Odroid_EnterLightSleep(int64_t timerAutoWakeupMicroSecs) printf("Returned from light sleep, reason: %s, t=%lld ms, slept for %lld ms\n", wakeup_reason, t_after_us / 1000, (t_after_us - t_before_us) / 1000); + for (int i = 0; i < sizeof(buttonsToWatch) / sizeof(buttonsToWatch[0]); ++i) + { + gpio_wakeup_disable(buttonsToWatch[i]); + } + + /// Reconfigure GPIO to our desired settings + Odroid_InitializeInput(); + return cause == ESP_SLEEP_WAKEUP_GPIO; }