@ -20,7 +20,7 @@ static bool drawTimeSinceBoot = false;
static bool drawFrameRate = true ;
/* static bool printInput = true; */
static bool printInput = fals e;
static bool printInput = tru e;
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