mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-19 05:40:38 +01:00
[ion/display] Add timeout in waitForVBlank
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
void Ion::Display::POSTPushMulticolor(int shift, int tileSize) {
|
||||
}
|
||||
|
||||
void Ion::Display::waitForVBlank() {
|
||||
bool Ion::Display::waitForVBlank() {
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user