[ion/display] Add timeout in waitForVBlank

This commit is contained in:
Léa Saviot
2019-05-22 15:48:37 +02:00
parent c85358967b
commit 9a1eb3ede9
4 changed files with 43 additions and 11 deletions

View File

@@ -21,7 +21,7 @@ void pushRect(KDRect r, const KDColor * pixels);
void pushRectUniform(KDRect r, KDColor c);
void pullRect(KDRect r, KDColor * pixels);
void waitForVBlank();
bool waitForVBlank();
constexpr int Width = 320;
constexpr int Height = 240;

View File

@@ -11,7 +11,7 @@ void msleep(uint32_t ms);
/* millis is the number of milliseconds ellapsed since a random epoch.
* On the device, epoch is the boot time. */
uint64_t millis();
volatile uint64_t millis();
}
}

View File

@@ -44,15 +44,46 @@ void pullRect(KDRect r, KDColor * pixels) {
pullPixels(pixels, r.width()*r.height());
}
void waitForVBlank() {
// We want to return as soon as the TE line is transitionning from "DOWN" to "UP"
while (Config::TearingEffectPin.group().IDR()->get(Config::TearingEffectPin.pin())) {
// Loop while high, exit when low
// Wait for zero
}
while (!Config::TearingEffectPin.group().IDR()->get(Config::TearingEffectPin.pin())) {
// Loop while low, exit when high
bool waitForVBlank() {
/* Min screen frequency is 40Hz so the maximal period is T = 1/40Hz = 25ms.
* If after T ms, we still do not have a VBlank event, just return. */
constexpr uint64_t timeoutDelta = 50;
uint64_t startTime = Timing::millis();
uint64_t timeout = startTime + timeoutDelta;
/* If current time is big enough, currentTime + timeout wraps aroud the
* uint64_t. We need to take this into account when computing the terminating
* event.
*
* NO WRAP |----------------|++++++++++|------|
* 0 startTime timeout max uint64_t
*
* WRAP |++++|----------------------|++++++|
* 0 timeout startTime max uint64_t
*/
bool noWrap = startTime < timeout;
/* We want to return at the beginning of a high signal, so we wait for the
* signal to be low then high. */
bool wasLow = false;
uint64_t currentTime = startTime;
while (noWrap ?
(currentTime >= startTime && currentTime < timeout) :
(currentTime >= startTime || currentTime < timeout))
{
if (!wasLow) {
wasLow = !Config::TearingEffectPin.group().IDR()->get(Config::TearingEffectPin.pin());
}
if (wasLow) {
if (Config::TearingEffectPin.group().IDR()->get(Config::TearingEffectPin.pin())) {
return true;
}
}
currentTime = Timing::millis();
// TODO: sleep?
}
return false;
}
void POSTPushMulticolor(int shift, int tileSize) {

View File

@@ -3,5 +3,6 @@
void Ion::Display::POSTPushMulticolor(int shift, int tileSize) {
}
void Ion::Display::waitForVBlank() {
bool Ion::Display::waitForVBlank() {
return true;
}