summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Schodet2016-08-09 23:17:48 +0200
committerNicolas Schodet2019-10-09 23:05:50 +0200
commitd33f8063e2c4033d767415660ca5ddafd3dd03fc (patch)
tree2a13d8bb178722d04e43ab0b178a6e2566e683c8
parentc5162d97ad6059cfea292beaf3b9a7b67ca8f982 (diff)
ucoo/hal/frame_buffer: enable tearing effect protection
-rw-r--r--ucoo/hal/frame_buffer/dsi.stm32f4.cc31
-rw-r--r--ucoo/hal/frame_buffer/dsi.stm32f4.hh5
2 files changed, 35 insertions, 1 deletions
diff --git a/ucoo/hal/frame_buffer/dsi.stm32f4.cc b/ucoo/hal/frame_buffer/dsi.stm32f4.cc
index 31a71f4..8e13982 100644
--- a/ucoo/hal/frame_buffer/dsi.stm32f4.cc
+++ b/ucoo/hal/frame_buffer/dsi.stm32f4.cc
@@ -57,6 +57,13 @@ enum DsiDataType
PACKED_PIXEL_RGB888 = 0x3e,
};
+enum DcsCommand
+{
+ DCS_SET_TEAR_ON = 0x35,
+};
+
+bool Dsi::refreshing_;
+
Dsi::Dsi (int width, int heigth, int lanes)
: Ltdc (width, heigth, 2, 1, 1, 2, 1, 1), lanes_ (lanes)
{
@@ -139,6 +146,8 @@ Dsi::enable (const Function<void ()> &config)
5, 2); // pllr, pllr_div => 416 MHz / 5 / 2 ~= 41.6 MHz
Ltdc::enable ();
//// Enable DSI Host and DSI wrapper.
+ reg::DSI->WIER = DSI_WIER_ERIE | DSI_WIER_TEIE;
+ interrupt_enable (Irq::DSI);
reg::DSI->CR = DSI_CR_EN;
reg::DSI->WCR = DSI_WCR_DSIEN;
//// Configure display.
@@ -155,6 +164,7 @@ void
Dsi::disable ()
{
// TODO
+ interrupt_disable (Irq::DSI);
reg::DSI->CR = 0;
reg::DSI->WCR = 0;
Ltdc::disable ();
@@ -172,7 +182,10 @@ Dsi::layer_setup (int layer, const Surface &surface, int x, int y)
void
Dsi::refresh ()
{
- ucoo::reg::DSI->WCR |= DSI_WCR_LTDCEN;
+ refreshing_ = true;
+ ucoo::Dsi::write_command ({ DCS_SET_TEAR_ON, 0x00 });
+ while (refreshing_)
+ ucoo::barrier ();
}
void
@@ -215,4 +228,20 @@ Dsi::write_command (std::initializer_list<uint8_t> data)
}
}
+template<>
+void
+interrupt<Irq::DSI> ()
+{
+ if (reg::DSI->WISR & DSI_WISR_TEIF)
+ {
+ reg::DSI->WIFCR = DSI_WIFCR_CTEIF;
+ ucoo::reg::DSI->WCR |= DSI_WCR_LTDCEN;
+ }
+ else if (reg::DSI->WISR & DSI_WISR_ERIF)
+ {
+ reg::DSI->WIFCR = DSI_WIFCR_CERIF;
+ Dsi::refreshing_ = false;
+ }
+}
+
} // namespace ucoo
diff --git a/ucoo/hal/frame_buffer/dsi.stm32f4.hh b/ucoo/hal/frame_buffer/dsi.stm32f4.hh
index bb92d6d..5f785aa 100644
--- a/ucoo/hal/frame_buffer/dsi.stm32f4.hh
+++ b/ucoo/hal/frame_buffer/dsi.stm32f4.hh
@@ -24,6 +24,7 @@
//
// }}}
#include "ucoo/hal/frame_buffer/ltdc.stm32f4.hh"
+#include "ucoo/arch/interrupt.arm.hh"
#include "ucoo/utils/function.hh"
#include <initializer_list>
@@ -49,6 +50,10 @@ class Dsi : public Ltdc
private:
/// Number of data lanes.
int lanes_;
+ /// Refresh is being done.
+ static bool refreshing_;
+ private:
+ friend void interrupt<Irq::DSI> ();
};
} // namespace ucoo