Add precise and reliable time measurement (with a resolution of 67MHz).

Splash screens now last 3 seconds after they have been loaded.
The delay after pressing START in the configuration menu is now 2s long.
This commit is contained in:
TuxSH 2016-05-10 01:27:58 +02:00
parent 2fd8c7aace
commit d2f53626ae
6 changed files with 50 additions and 14 deletions

View File

@ -186,5 +186,6 @@ void configureCFW(const char *configPath)
PDN_GPU_CNT = 1;
}
delay(0x1400000);
u64 t0 = chrono();
while(chrono() - t0 < 2 * TICKS_PER_SEC); //wait for 1.5s
}

View File

@ -33,14 +33,15 @@ void clearScreens(void)
memset32(fb->bottom, 0, 0x38400);
}
void loadSplash(void)
u32 loadSplash(void)
{
initScreens();
//Don't delay boot if no splash image is on the SD
if(fileRead(fb->top_left, "/luma/splash.bin") +
fileRead(fb->bottom, "/luma/splashbottom.bin"))
delay(0x1400000);
return 1;
return 0;
}
void drawCharacter(char character, int posX, int posY, u32 color)

View File

@ -19,7 +19,7 @@
#define COLOR_RED 0x0000FF
#define COLOR_BLACK 0x000000
void loadSplash(void);
u32 loadSplash(void);
void clearScreens(void);
void drawCharacter(char character, int posX, int posY, u32 color);
int drawString(const char *string, int posX, int posY, u32 color);

View File

@ -23,6 +23,8 @@ u32 config,
firmSource,
emuOffset;
u64 chronoWhenSplashLoaded = 0;
void main(void)
{
u32 bootType,
@ -34,6 +36,8 @@ void main(void)
newConfig,
emuHeader;
startChrono(0); //Start the chronometer. It shouldn't be reset.
//Detect the console being used
console = PDN_MPCORE_CFG == 7;
@ -145,7 +149,8 @@ void main(void)
loadPayload(pressed);
//If screens are inited or the corresponding option is set, load splash screen
if(PDN_GPU_CNT != 1 || CONFIG(7)) loadSplash();
if(PDN_GPU_CNT != 1 || CONFIG(7)) chronoWhenSplashLoaded = (u64) loadSplash();
if(chronoWhenSplashLoaded) chronoWhenSplashLoaded = chrono();
//If R is pressed, boot the non-updated NAND with the FIRM of the opposite one
if(pressed & BUTTON_R1)
@ -446,6 +451,9 @@ static inline void launchFirm(u32 firstSectionToCopy, u32 bootType)
for(u32 i = firstSectionToCopy; i < 4 && section[i].size; i++)
memcpy(section[i].address, (u8 *)firm + section[i].offset, section[i].size);
while(chronoWhenSplashLoaded && chrono() - chronoWhenSplashLoaded < 3 * TICKS_PER_SEC);
stopChrono();
//Determine the ARM11 entry to use
vu32 *arm11;
if(bootType) arm11 = (u32 *)0x1FFFFFFC;

View File

@ -33,13 +33,34 @@ u32 waitInput(void)
return key;
}
void delay(u64 length)
{
while(length--) __asm("mov r0, r0");
}
void mcuReboot(void)
{
i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2);
while(1);
}
//TODO: add support for TIMER IRQ
void startChrono(u64 initialTicks)
{
//Based on a NATIVE_FIRM disassembly
*(vu16 *)(0x10003002 + 4 * 0) = 0; //67MHz
for(u32 i = 1; i < 4; i++) *(vu16 *)(0x10003002 + 4 * i) = 4; //Count-up
for(u32 i = 0; i < 4; i++) *(vu16 *)(0x10003000 + 4 * i) = (u16)(initialTicks >> (16 * i));
*(vu16 *)(0x10003002 + 4 * 0) = 0x80; //67MHz; enabled
for(u32 i = 1; i < 4; i++) *(vu16 *)(0x10003002 + 4 * i) = 0x84; //Count-up; enabled
}
u64 chrono(void)
{
u64 res = 0;
for(u32 i = 0; i < 4; i++) res |= *(vu16 *)(0x10003000 + 4 * i) << (16 * i);
return res;
}
void stopChrono(void)
{
for(u32 i = 1; i < 4; i++) *(vu16 *)(0x10003002 + 4 * i) &= ~0x80;
}

View File

@ -7,5 +7,10 @@
#include "types.h"
u32 waitInput(void);
void delay(u64 length);
void mcuReboot(void);
#define TICKS_PER_SEC 67027964ULL
void startChrono(u64 initialTicks);
u64 chrono(void);
void stopChrono(void);