diff --git a/mxgui/drivers/display_stm32f4discovery.cpp b/mxgui/drivers/display_stm32f4discovery.cpp
index 23b0a9d36d04e3bb6f11abde6c6c5bcc5f3362c1..3194f1829c8d154410218a7e955506d752133809 100644
--- a/mxgui/drivers/display_stm32f4discovery.cpp
+++ b/mxgui/drivers/display_stm32f4discovery.cpp
@@ -47,1456 +47,1457 @@ using namespace miosix;
     defined(_BOARD_STM32F429ZI_SKYWARD_GS_PARAFOIL) ||     \
     defined(_BOARD_STM32F429ZI_HRE_TEST_STAND) ||          \
     defined(_BOARD_STM32F429ZI_SKYWARD_PYXIS_AUXILIARY) || \
-    defined(_BOARD_STM32F429ZI_SKYWARD_PARAFOIL)
+    defined(_BOARD_STM32F429ZI_SKYWARD_PARAFOIL) ||        \
+    defined(_BOARD_STM32F429ZI_SKYWARD_RIG)
 
 namespace mxgui
 {
 
-// Control interface
-typedef Gpio<GPIOF_BASE, 7> scl;   // SPI SCK
-typedef Gpio<GPIOF_BASE, 9> sda;   // SPI MOSI
-typedef Gpio<GPIOC_BASE, 2> csx;   // SPI CS
-typedef Gpio<GPIOD_BASE, 13> dcx;  // Data/command
-typedef Gpio<GPIOD_BASE, 12> rdx;  // Used only un parallel mode
-typedef Gpio<GPIOD_BASE, 11> te;   // Tearing effect output from display, unused
-// Pixel sync interface
-typedef Gpio<GPIOF_BASE, 10> en;
-typedef Gpio<GPIOG_BASE, 7> dotclk;
-typedef Gpio<GPIOA_BASE, 4> vsync;
-typedef Gpio<GPIOC_BASE, 6> hsync;
-// Pixel data bus
-typedef Gpio<GPIOC_BASE, 10> r0;  // r2
-typedef Gpio<GPIOB_BASE, 0> r1;   // r3
-typedef Gpio<GPIOA_BASE, 11> r2;  // r4
-typedef Gpio<GPIOA_BASE, 12> r3;  // r5
-typedef Gpio<GPIOB_BASE, 1> r4;   // r6
-typedef Gpio<GPIOG_BASE, 6> r5;   // r7
-typedef Gpio<GPIOA_BASE, 6> g0;   // g2
-typedef Gpio<GPIOG_BASE, 10> g1;  // g3
-typedef Gpio<GPIOB_BASE, 10> g2;  // g4
-typedef Gpio<GPIOB_BASE, 11> g3;  // g5
-typedef Gpio<GPIOC_BASE, 7> g4;   // g6
-typedef Gpio<GPIOD_BASE, 3> g5;   // g7
-typedef Gpio<GPIOD_BASE, 6> b0;   // b2
-typedef Gpio<GPIOG_BASE, 11> b1;  // b3
-typedef Gpio<GPIOG_BASE, 12> b2;  // b4
-typedef Gpio<GPIOA_BASE, 3> b3;   // b5
-typedef Gpio<GPIOB_BASE, 8> b4;   // b6
-typedef Gpio<GPIOB_BASE, 9> b5;   // b7
-
-/**
- * Send and receive a byte through SPI5
- * \param c byte to send
- * \return byte received
- */
-static unsigned char spi5sendRev(unsigned char c = 0)
-{
-    SPI5->DR = c;
-    while ((SPI5->SR & SPI_SR_RXNE) == 0)
-        ;
-    return SPI5->DR;
-}
-
-/**
- * Send a command to the ILI9341 display controller
- * \param cmd command
- * \param len length of the (optional) argument, or 0 for commands without
- * arguments.
- */
-static void sendCmd(unsigned char cmd, int len, ...)
-{
-    dcx::low();
-    csx::low();
-    spi5sendRev(cmd);
-    csx::high();
-    delayUs(1);
-    dcx::high();
-    va_list arg;
-    va_start(arg, len);
-    for (int i = 0; i < len; i++)
+    // Control interface
+    typedef Gpio<GPIOF_BASE, 7> scl;  // SPI SCK
+    typedef Gpio<GPIOF_BASE, 9> sda;  // SPI MOSI
+    typedef Gpio<GPIOC_BASE, 2> csx;  // SPI CS
+    typedef Gpio<GPIOD_BASE, 13> dcx; // Data/command
+    typedef Gpio<GPIOD_BASE, 12> rdx; // Used only un parallel mode
+    typedef Gpio<GPIOD_BASE, 11> te;  // Tearing effect output from display, unused
+    // Pixel sync interface
+    typedef Gpio<GPIOF_BASE, 10> en;
+    typedef Gpio<GPIOG_BASE, 7> dotclk;
+    typedef Gpio<GPIOA_BASE, 4> vsync;
+    typedef Gpio<GPIOC_BASE, 6> hsync;
+    // Pixel data bus
+    typedef Gpio<GPIOC_BASE, 10> r0; // r2
+    typedef Gpio<GPIOB_BASE, 0> r1;  // r3
+    typedef Gpio<GPIOA_BASE, 11> r2; // r4
+    typedef Gpio<GPIOA_BASE, 12> r3; // r5
+    typedef Gpio<GPIOB_BASE, 1> r4;  // r6
+    typedef Gpio<GPIOG_BASE, 6> r5;  // r7
+    typedef Gpio<GPIOA_BASE, 6> g0;  // g2
+    typedef Gpio<GPIOG_BASE, 10> g1; // g3
+    typedef Gpio<GPIOB_BASE, 10> g2; // g4
+    typedef Gpio<GPIOB_BASE, 11> g3; // g5
+    typedef Gpio<GPIOC_BASE, 7> g4;  // g6
+    typedef Gpio<GPIOD_BASE, 3> g5;  // g7
+    typedef Gpio<GPIOD_BASE, 6> b0;  // b2
+    typedef Gpio<GPIOG_BASE, 11> b1; // b3
+    typedef Gpio<GPIOG_BASE, 12> b2; // b4
+    typedef Gpio<GPIOA_BASE, 3> b3;  // b5
+    typedef Gpio<GPIOB_BASE, 8> b4;  // b6
+    typedef Gpio<GPIOB_BASE, 9> b5;  // b7
+
+    /**
+     * Send and receive a byte through SPI5
+     * \param c byte to send
+     * \return byte received
+     */
+    static unsigned char spi5sendRev(unsigned char c = 0)
+    {
+        SPI5->DR = c;
+        while ((SPI5->SR & SPI_SR_RXNE) == 0)
+            ;
+        return SPI5->DR;
+    }
+
+    /**
+     * Send a command to the ILI9341 display controller
+     * \param cmd command
+     * \param len length of the (optional) argument, or 0 for commands without
+     * arguments.
+     */
+    static void sendCmd(unsigned char cmd, int len, ...)
     {
+        dcx::low();
         csx::low();
-        spi5sendRev(va_arg(arg, int));
+        spi5sendRev(cmd);
         csx::high();
         delayUs(1);
+        dcx::high();
+        va_list arg;
+        va_start(arg, len);
+        for (int i = 0; i < len; i++)
+        {
+            csx::low();
+            spi5sendRev(va_arg(arg, int));
+            csx::high();
+            delayUs(1);
+        }
+        va_end(arg);
     }
-    va_end(arg);
-}
 
-void registerDisplayHook(DisplayManager &dm)
-{
-    dm.registerDisplay(&DisplayImpl::instance());
-}
+    void registerDisplayHook(DisplayManager &dm)
+    {
+        dm.registerDisplay(&DisplayImpl::instance());
+    }
 
-//
-// class DisplayImpl
-//
+    //
+    // class DisplayImpl
+    //
 
-DisplayImpl &DisplayImpl::instance()
-{
-    static DisplayImpl instance;
-    return instance;
-}
+    DisplayImpl &DisplayImpl::instance()
+    {
+        static DisplayImpl instance;
+        return instance;
+    }
 
-void DisplayImpl::doTurnOn()
-{
-    LTDC->GCR |= LTDC_GCR_LTDCEN;
-    Thread::sleep(40);
-    sendCmd(0x29, 0);  // LCD_DISPLAY_ON
-}
+    void DisplayImpl::doTurnOn()
+    {
+        LTDC->GCR |= LTDC_GCR_LTDCEN;
+        Thread::sleep(40);
+        sendCmd(0x29, 0); // LCD_DISPLAY_ON
+    }
 
-void DisplayImpl::doTurnOff()
-{
-    sendCmd(0x28, 0);  // LCD_DISPLAY_OFF
-    LTDC->GCR &= ~LTDC_GCR_LTDCEN;
-}
+    void DisplayImpl::doTurnOff()
+    {
+        sendCmd(0x28, 0); // LCD_DISPLAY_OFF
+        LTDC->GCR &= ~LTDC_GCR_LTDCEN;
+    }
 
-void DisplayImpl::doSetBrightness(int brt) {}
+    void DisplayImpl::doSetBrightness(int brt) {}
 
-pair<short int, short int> DisplayImpl::doGetSize() const
-{
-    return make_pair(height, width);
-}
+    pair<short int, short int> DisplayImpl::doGetSize() const
+    {
+        return make_pair(height, width);
+    }
 
-void DisplayImpl::write(Point p, const char *text)
-{
-    font.draw(*this, textColor, p, text);
-}
+    void DisplayImpl::write(Point p, const char *text)
+    {
+        font.draw(*this, textColor, p, text);
+    }
 
-void DisplayImpl::clippedWrite(Point p, Point a, Point b, const char *text)
-{
-    font.clippedDraw(*this, textColor, p, a, b, text);
-}
+    void DisplayImpl::clippedWrite(Point p, Point a, Point b, const char *text)
+    {
+        font.clippedDraw(*this, textColor, p, a, b, text);
+    }
 
-void DisplayImpl::clear(Color color)
-{
-    clear(Point(0, 0), Point(width - 1, height - 1), color);
-}
+    void DisplayImpl::clear(Color color)
+    {
+        clear(Point(0, 0), Point(width - 1, height - 1), color);
+    }
 
-void DisplayImpl::clear(Point p1, Point p2, Color color)
-{
-    if (p1.x() < 0 || p2.x() < p1.x() || p2.x() >= width || p1.y() < 0 ||
-        p2.y() < p1.y() || p2.y() >= height)
-        return;
-    if ((color & 0xff) == (color >> 8))
+    void DisplayImpl::clear(Point p1, Point p2, Color color)
     {
-        // Can use memset
-        if (p1.x() == 0 && p2.x() == width - 1)
-        {
-            // Can merge lines
-            memset(framebuffer1 + p1.y() * width, color,
-                   (p2.y() - p1.y() + 1) * width * bpp);
-        }
-        else
+        if (p1.x() < 0 || p2.x() < p1.x() || p2.x() >= width || p1.y() < 0 ||
+            p2.y() < p1.y() || p2.y() >= height)
+            return;
+        if ((color & 0xff) == (color >> 8))
         {
-            // Can't merge lines
-            Color *ptr = framebuffer1 + p1.x() + width * p1.y();
-            short len  = p2.x() - p1.x() + 1;
-            for (short i = p1.y(); i <= p2.y(); i++)
+            // Can use memset
+            if (p1.x() == 0 && p2.x() == width - 1)
             {
-                memset(ptr, color, len * bpp);
-                ptr += width;
+                // Can merge lines
+                memset(framebuffer1 + p1.y() * width, color,
+                       (p2.y() - p1.y() + 1) * width * bpp);
             }
-        }
-    }
-    else
-    {
-        // Can't use memset
-        if (p1.x() == 0 && p2.x() == width - 1)
-        {
-            // Can merge lines
-            Color *ptr    = framebuffer1 + p1.y() * width;
-            int numPixels = (p2.y() - p1.y() + 1) * width;
-            // This loop is worth unrolling
-            for (int i = 0; i < numPixels / 4; i++)
+            else
             {
-                *ptr++ = color;
-                *ptr++ = color;
-                *ptr++ = color;
-                *ptr++ = color;
+                // Can't merge lines
+                Color *ptr = framebuffer1 + p1.x() + width * p1.y();
+                short len = p2.x() - p1.x() + 1;
+                for (short i = p1.y(); i <= p2.y(); i++)
+                {
+                    memset(ptr, color, len * bpp);
+                    ptr += width;
+                }
             }
-            for (int i = 0; i < (numPixels & 3); i++)
-                *ptr++ = color;
         }
         else
         {
-            // Can't merge lines
-            Color *ptr = framebuffer1 + p1.x() + width * p1.y();
-            short len  = p2.x() - p1.x() + 1;
-            for (short i = p1.y(); i <= p2.y(); i++)
+            // Can't use memset
+            if (p1.x() == 0 && p2.x() == width - 1)
             {
-                for (short j = 0; j < len; j++)
+                // Can merge lines
+                Color *ptr = framebuffer1 + p1.y() * width;
+                int numPixels = (p2.y() - p1.y() + 1) * width;
+                // This loop is worth unrolling
+                for (int i = 0; i < numPixels / 4; i++)
+                {
+                    *ptr++ = color;
+                    *ptr++ = color;
                     *ptr++ = color;
-                ptr += width - len;
+                    *ptr++ = color;
+                }
+                for (int i = 0; i < (numPixels & 3); i++)
+                    *ptr++ = color;
+            }
+            else
+            {
+                // Can't merge lines
+                Color *ptr = framebuffer1 + p1.x() + width * p1.y();
+                short len = p2.x() - p1.x() + 1;
+                for (short i = p1.y(); i <= p2.y(); i++)
+                {
+                    for (short j = 0; j < len; j++)
+                        *ptr++ = color;
+                    ptr += width - len;
+                }
             }
         }
     }
-}
 
-void DisplayImpl::beginPixel() {}
-
-void DisplayImpl::setPixel(Point p, Color color)
-{
-    int offset = p.x() + p.y() * width;
-    if (offset < 0 || offset >= numPixels)
-        return;
-    *(framebuffer1 + offset) = color;
-}
+    void DisplayImpl::beginPixel() {}
 
-void DisplayImpl::line(Point a, Point b, Color color)
-{
-    // Horizontal line speed optimization
-    if (a.y() == b.y())
+    void DisplayImpl::setPixel(Point p, Color color)
     {
-        short minx = min(a.x(), b.x());
-        short maxx = max(a.x(), b.x());
-        if (minx < 0 || maxx >= width || a.y() < 0 || a.y() >= height)
+        int offset = p.x() + p.y() * width;
+        if (offset < 0 || offset >= numPixels)
             return;
-        Color *ptr = framebuffer1 + minx + width * a.y();
-        for (short i = minx; i <= maxx; i++)
-            *ptr++ = color;
-        return;
+        *(framebuffer1 + offset) = color;
     }
-    // Vertical line speed optimization
-    if (a.x() == b.x())
+
+    void DisplayImpl::line(Point a, Point b, Color color)
     {
-        short miny = min(a.y(), b.y());
-        short maxy = max(a.y(), b.y());
-        if (a.x() < 0 || a.x() >= width || miny < 0 || maxy >= height)
+        // Horizontal line speed optimization
+        if (a.y() == b.y())
+        {
+            short minx = min(a.x(), b.x());
+            short maxx = max(a.x(), b.x());
+            if (minx < 0 || maxx >= width || a.y() < 0 || a.y() >= height)
+                return;
+            Color *ptr = framebuffer1 + minx + width * a.y();
+            for (short i = minx; i <= maxx; i++)
+                *ptr++ = color;
             return;
-        Color *ptr = framebuffer1 + a.x() + width * miny;
-        for (short i = miny; i <= maxy; i++)
+        }
+        // Vertical line speed optimization
+        if (a.x() == b.x())
         {
-            *ptr = color;
-            ptr += width;
+            short miny = min(a.y(), b.y());
+            short maxy = max(a.y(), b.y());
+            if (a.x() < 0 || a.x() >= width || miny < 0 || maxy >= height)
+                return;
+            Color *ptr = framebuffer1 + a.x() + width * miny;
+            for (short i = miny; i <= maxy; i++)
+            {
+                *ptr = color;
+                ptr += width;
+            }
+            return;
         }
-        return;
+        // General case
+        Line::draw(*this, a, b, color);
     }
-    // General case
-    Line::draw(*this, a, b, color);
-}
 
-void DisplayImpl::scanLine(Point p, const Color *colors, unsigned short length)
-{
-    if (p.x() < 0 ||
-        static_cast<int>(p.x()) + static_cast<int>(length) > width ||
-        p.y() < 0 || p.y() >= height)
-        return;
-    Color *ptr = framebuffer1 + p.x() + p.y() * width;
-    memcpy(ptr, colors, length * bpp);
-}
+    void DisplayImpl::scanLine(Point p, const Color *colors, unsigned short length)
+    {
+        if (p.x() < 0 ||
+            static_cast<int>(p.x()) + static_cast<int>(length) > width ||
+            p.y() < 0 || p.y() >= height)
+            return;
+        Color *ptr = framebuffer1 + p.x() + p.y() * width;
+        memcpy(ptr, colors, length * bpp);
+    }
 
-Color *DisplayImpl::getScanLineBuffer() { return buffer; }
+    Color *DisplayImpl::getScanLineBuffer() { return buffer; }
 
-void DisplayImpl::scanLineBuffer(Point p, unsigned short length)
-{
-    int offset = p.x() + p.y() * width;
-    if (offset < 0 || offset >= numPixels)
-        return;
-    memcpy(framebuffer1 + offset, buffer, length * bpp);
-}
+    void DisplayImpl::scanLineBuffer(Point p, unsigned short length)
+    {
+        int offset = p.x() + p.y() * width;
+        if (offset < 0 || offset >= numPixels)
+            return;
+        memcpy(framebuffer1 + offset, buffer, length * bpp);
+    }
 
-void DisplayImpl::drawImage(Point p, const ImageBase &img)
-{
-    short int xEnd = p.x() + img.getWidth() - 1;
-    short int yEnd = p.y() + img.getHeight() - 1;
-    if (p.x() < 0 || p.y() < 0 || xEnd < p.x() || yEnd < p.y() ||
-        xEnd >= width || yEnd >= height)
-        return;
+    void DisplayImpl::drawImage(Point p, const ImageBase &img)
+    {
+        short int xEnd = p.x() + img.getWidth() - 1;
+        short int yEnd = p.y() + img.getHeight() - 1;
+        if (p.x() < 0 || p.y() < 0 || xEnd < p.x() || yEnd < p.y() ||
+            xEnd >= width || yEnd >= height)
+            return;
 
-    //    const unsigned short *imgData=img.getData();
-    //    if(imgData!=0)
-    //    {
-    //        //TODO Optimized version for in-memory images
-    //    } else
-    img.draw(*this, p);
-}
+        //    const unsigned short *imgData=img.getData();
+        //    if(imgData!=0)
+        //    {
+        //        //TODO Optimized version for in-memory images
+        //    } else
+        img.draw(*this, p);
+    }
 
-void DisplayImpl::clippedDrawImage(Point p, Point a, Point b,
-                                   const ImageBase &img)
-{
-    //    if(img.getData()==0)
-    //    {
-    img.clippedDraw(*this, p, a, b);
-    return;
-    //    } //else optimized version for memory-loaded images
-    //        //TODO: optimize
-    //    }
-}
-
-void DisplayImpl::drawRectangle(Point a, Point b, Color c)
-{
-    line(a, Point(b.x(), a.y()), c);
-    line(Point(b.x(), a.y()), b, c);
-    line(b, Point(a.x(), b.y()), c);
-    line(Point(a.x(), b.y()), a, c);
-}
-
-DisplayImpl::pixel_iterator DisplayImpl::begin(Point p1, Point p2,
-                                               IteratorDirection d)
-{
-    bool fail = false;
-    if (p1.x() < 0 || p1.y() < 0 || p2.x() < 0 || p2.y() < 0)
-        fail = true;
-    if (p1.x() >= width || p1.y() >= height || p2.x() >= width ||
-        p2.y() >= height)
-        fail = true;
-    if (p2.x() < p1.x() || p2.y() < p1.y())
-        fail = true;
-    if (fail)
+    void DisplayImpl::clippedDrawImage(Point p, Point a, Point b,
+                                       const ImageBase &img)
     {
-        // Return invalid (dummy) iterators
-        this->last = pixel_iterator();
-        return this->last;
+        //    if(img.getData()==0)
+        //    {
+        img.clippedDraw(*this, p, a, b);
+        return;
+        //    } //else optimized version for memory-loaded images
+        //        //TODO: optimize
+        //    }
     }
 
-    // Set the last iterator to a suitable one-past-the last value
-    if (d == DR)
-        this->last = pixel_iterator(Point(p2.x() + 1, p1.y()), p2, d, this);
-    else
-        this->last = pixel_iterator(Point(p1.x(), p2.y() + 1), p2, d, this);
+    void DisplayImpl::drawRectangle(Point a, Point b, Color c)
+    {
+        line(a, Point(b.x(), a.y()), c);
+        line(Point(b.x(), a.y()), b, c);
+        line(b, Point(a.x(), b.y()), c);
+        line(Point(a.x(), b.y()), a, c);
+    }
 
-    return pixel_iterator(p1, p2, d, this);
-}
+    DisplayImpl::pixel_iterator DisplayImpl::begin(Point p1, Point p2,
+                                                   IteratorDirection d)
+    {
+        bool fail = false;
+        if (p1.x() < 0 || p1.y() < 0 || p2.x() < 0 || p2.y() < 0)
+            fail = true;
+        if (p1.x() >= width || p1.y() >= height || p2.x() >= width ||
+            p2.y() >= height)
+            fail = true;
+        if (p2.x() < p1.x() || p2.y() < p1.y())
+            fail = true;
+        if (fail)
+        {
+            // Return invalid (dummy) iterators
+            this->last = pixel_iterator();
+            return this->last;
+        }
 
-DisplayImpl::~DisplayImpl() {}
+        // Set the last iterator to a suitable one-past-the last value
+        if (d == DR)
+            this->last = pixel_iterator(Point(p2.x() + 1, p1.y()), p2, d, this);
+        else
+            this->last = pixel_iterator(Point(p1.x(), p2.y() + 1), p2, d, this);
 
-DisplayImpl::DisplayImpl()
-    : framebuffer1(reinterpret_cast<unsigned short *>(0xd0600000)),
-      buffer(framebuffer1 + numPixels)
-{
-    {
-        FastInterruptDisableLock dLock;
-        // PLLSAI runs @ 192MHz, both Q and R outputs are divided by 4 so 48MHz
-        RCC->PLLSAICFGR = 4 << 28 | 4 << 24 | 192 << 6;
-        // PLLSAI R output divided by 8 resulting in a 6MHz LTDC clock
-        RCC->DCKCFGR = 2 << 16;
-        RCC->CR |= RCC_CR_PLLSAION;
+        return pixel_iterator(p1, p2, d, this);
     }
 
-    while ((RCC->CR & RCC_CR_PLLSAIRDY) == 0)
-        ;
+    DisplayImpl::~DisplayImpl() {}
 
+    DisplayImpl::DisplayImpl()
+        : framebuffer1(reinterpret_cast<unsigned short *>(0xd0600000)),
+          buffer(framebuffer1 + numPixels)
     {
-        FastInterruptDisableLock dLock;
+        {
+            FastInterruptDisableLock dLock;
+            // PLLSAI runs @ 192MHz, both Q and R outputs are divided by 4 so 48MHz
+            RCC->PLLSAICFGR = 4 << 28 | 4 << 24 | 192 << 6;
+            // PLLSAI R output divided by 8 resulting in a 6MHz LTDC clock
+            RCC->DCKCFGR = 2 << 16;
+            RCC->CR |= RCC_CR_PLLSAION;
+        }
 
-        scl::mode(Mode::ALTERNATE);
-        scl::alternateFunction(5);  // SPI5
-        sda::mode(Mode::ALTERNATE);
-        sda::alternateFunction(5);
-        csx::mode(Mode::OUTPUT);
-        csx::high();
-        dcx::mode(Mode::OUTPUT);
-        rdx::mode(Mode::OUTPUT);
-        rdx::low();  // Original fw seems to leave it low
-
-        en::mode(Mode::ALTERNATE);
-        en::alternateFunction(14);
-        dotclk::mode(Mode::ALTERNATE);
-        dotclk::alternateFunction(14);
-        vsync::mode(Mode::ALTERNATE);
-        vsync::alternateFunction(14);
-        hsync::mode(Mode::ALTERNATE);
-        hsync::alternateFunction(14);
-        r0::mode(Mode::ALTERNATE);
-        r0::alternateFunction(14);
-        r1::mode(Mode::ALTERNATE);
-        r1::alternateFunction(14);
-        r2::mode(Mode::ALTERNATE);
-        r2::alternateFunction(14);
-        r3::mode(Mode::ALTERNATE);
-        r3::alternateFunction(14);
-        r4::mode(Mode::ALTERNATE);
-        r4::alternateFunction(14);
-        r5::mode(Mode::ALTERNATE);
-        r5::alternateFunction(14);
-        g0::mode(Mode::ALTERNATE);
-        g0::alternateFunction(14);
-        g1::mode(Mode::ALTERNATE);
-        g1::alternateFunction(14);
-        g2::mode(Mode::ALTERNATE);
-        g2::alternateFunction(14);
-        g3::mode(Mode::ALTERNATE);
-        g3::alternateFunction(14);
-        g4::mode(Mode::ALTERNATE);
-        g4::alternateFunction(14);
-        g5::mode(Mode::ALTERNATE);
-        g5::alternateFunction(14);
-        b0::mode(Mode::ALTERNATE);
-        b0::alternateFunction(14);
-        b1::mode(Mode::ALTERNATE);
-        b1::alternateFunction(14);
-        b2::mode(Mode::ALTERNATE);
-        b2::alternateFunction(14);
-        b3::mode(Mode::ALTERNATE);
-        b3::alternateFunction(14);
-        b4::mode(Mode::ALTERNATE);
-        b4::alternateFunction(14);
-        b5::mode(Mode::ALTERNATE);
-        b5::alternateFunction(14);
-
-        RCC->APB2ENR |= RCC_APB2ENR_LTDCEN | RCC_APB2ENR_SPI5EN;
-        RCC_SYNC();
-    }
+        while ((RCC->CR & RCC_CR_PLLSAIRDY) == 0)
+            ;
 
-    SPI5->CR1 = SPI_CR1_SSM      // Sowtware CS
-                | SPI_CR1_SSI    // Software CS high
-                | SPI_CR1_SPE    // SPI enabled
-                | (3 << 3)       // Divide input clock by 16: 84/16=5.25MHz
-                | SPI_CR1_MSTR;  // Master mode
-    Thread::sleep(1);
+        {
+            FastInterruptDisableLock dLock;
+
+            scl::mode(Mode::ALTERNATE);
+            scl::alternateFunction(5); // SPI5
+            sda::mode(Mode::ALTERNATE);
+            sda::alternateFunction(5);
+            csx::mode(Mode::OUTPUT);
+            csx::high();
+            dcx::mode(Mode::OUTPUT);
+            rdx::mode(Mode::OUTPUT);
+            rdx::low(); // Original fw seems to leave it low
+
+            en::mode(Mode::ALTERNATE);
+            en::alternateFunction(14);
+            dotclk::mode(Mode::ALTERNATE);
+            dotclk::alternateFunction(14);
+            vsync::mode(Mode::ALTERNATE);
+            vsync::alternateFunction(14);
+            hsync::mode(Mode::ALTERNATE);
+            hsync::alternateFunction(14);
+            r0::mode(Mode::ALTERNATE);
+            r0::alternateFunction(14);
+            r1::mode(Mode::ALTERNATE);
+            r1::alternateFunction(14);
+            r2::mode(Mode::ALTERNATE);
+            r2::alternateFunction(14);
+            r3::mode(Mode::ALTERNATE);
+            r3::alternateFunction(14);
+            r4::mode(Mode::ALTERNATE);
+            r4::alternateFunction(14);
+            r5::mode(Mode::ALTERNATE);
+            r5::alternateFunction(14);
+            g0::mode(Mode::ALTERNATE);
+            g0::alternateFunction(14);
+            g1::mode(Mode::ALTERNATE);
+            g1::alternateFunction(14);
+            g2::mode(Mode::ALTERNATE);
+            g2::alternateFunction(14);
+            g3::mode(Mode::ALTERNATE);
+            g3::alternateFunction(14);
+            g4::mode(Mode::ALTERNATE);
+            g4::alternateFunction(14);
+            g5::mode(Mode::ALTERNATE);
+            g5::alternateFunction(14);
+            b0::mode(Mode::ALTERNATE);
+            b0::alternateFunction(14);
+            b1::mode(Mode::ALTERNATE);
+            b1::alternateFunction(14);
+            b2::mode(Mode::ALTERNATE);
+            b2::alternateFunction(14);
+            b3::mode(Mode::ALTERNATE);
+            b3::alternateFunction(14);
+            b4::mode(Mode::ALTERNATE);
+            b4::alternateFunction(14);
+            b5::mode(Mode::ALTERNATE);
+            b5::alternateFunction(14);
+
+            RCC->APB2ENR |= RCC_APB2ENR_LTDCEN | RCC_APB2ENR_SPI5EN;
+            RCC_SYNC();
+        }
 
-    //
-    // ILI9341 power up sequence -- begin
-    //
-    sendCmd(0xca, 3, 0xc3, 0x08, 0x50);              // undocumented command
-    sendCmd(0xcf, 3, 0x00, 0xc1, 0x30);              // LCD_POWERB
-    sendCmd(0xed, 4, 0x64, 0x03, 0x12, 0x81);        // LCD_POWER_SEQ
-    sendCmd(0xe8, 3, 0x85, 0x00, 0x78);              // LCD_DTCA
-    sendCmd(0xcb, 5, 0x39, 0x2c, 0x00, 0x34, 0x02);  // LCD_POWERA
-    sendCmd(0xf7, 1, 0x20);                          // LCD_PRC
-    sendCmd(0xea, 2, 0x00, 0x00);                    // LCD_DTCB
-    sendCmd(0xb1, 2, 0x00, 0x1b);                    // LCD_FRMCTR1
-    sendCmd(0xb6, 2, 0x0a, 0xa2);                    // LCD_DFC
-    sendCmd(0xc0, 1, 0x10);                          // LCD_POWER1
-    sendCmd(0xc1, 1, 0x10);                          // LCD_POWER2
-    sendCmd(0xc5, 2, 0x45, 0x15);                    // LCD_VCOM1
-    sendCmd(0xc7, 1, 0x90);                          // LCD_VCOM2
-    sendCmd(0x36, 1, 0xc8);                          // LCD_MAC
-    sendCmd(0xf2, 1, 0x00);                          // LCD_3GAMMA_EN
-    sendCmd(0xb0, 1, 0xc2);                          // LCD_RGB_INTERFACE
-    sendCmd(0xb6, 4, 0x0a, 0xa7, 0x27, 0x04);        // LCD_DFC
-    sendCmd(0x2a, 4, 0x00, 0x00, 0x00, 0xef);        // LCD_COLUMN_ADDR
-    sendCmd(0x2b, 4, 0x00, 0x00, 0x01, 0x3f);        // LCD_PAGE_ADDR
-    sendCmd(0xf6, 3, 0x01, 0x00, 0x06);              // LCD_INTERFACE
-    sendCmd(0x2c, 0);                                // LCD_GRAM
-    Thread::sleep(200);
-    sendCmd(0x26, 1, 0x01);  // LCD_GAMMA
-    sendCmd(0xe0, 15, 0x0f, 0x29, 0x24, 0x0c, 0x0e, 0x09, 0x4e, 0x78, 0x3c,
-            0x09, 0x13, 0x05, 0x17, 0x11, 0x00);  // LCD_PGAMMA
-    sendCmd(0xe1, 15, 0x00, 0x16, 0x1b, 0x04, 0x11, 0x07, 0x31, 0x33, 0x42,
-            0x05, 0x0c, 0x0a, 0x28, 0x2f, 0x0f);  // LCD_NGAMMA
-    sendCmd(0x11, 0);                             // LCD_SLEEP_OUT
-    Thread::sleep(200);
-    sendCmd(0x29, 0);  // LCD_DISPLAY_ON
-    sendCmd(0x2c, 0);  // LCD_GRAM
-    //
-    // ILI9341 power up sequence -- end
-    //
+        SPI5->CR1 = SPI_CR1_SSM     // Sowtware CS
+                    | SPI_CR1_SSI   // Software CS high
+                    | SPI_CR1_SPE   // SPI enabled
+                    | (3 << 3)      // Divide input clock by 16: 84/16=5.25MHz
+                    | SPI_CR1_MSTR; // Master mode
+        Thread::sleep(1);
+
+        //
+        // ILI9341 power up sequence -- begin
+        //
+        sendCmd(0xca, 3, 0xc3, 0x08, 0x50);             // undocumented command
+        sendCmd(0xcf, 3, 0x00, 0xc1, 0x30);             // LCD_POWERB
+        sendCmd(0xed, 4, 0x64, 0x03, 0x12, 0x81);       // LCD_POWER_SEQ
+        sendCmd(0xe8, 3, 0x85, 0x00, 0x78);             // LCD_DTCA
+        sendCmd(0xcb, 5, 0x39, 0x2c, 0x00, 0x34, 0x02); // LCD_POWERA
+        sendCmd(0xf7, 1, 0x20);                         // LCD_PRC
+        sendCmd(0xea, 2, 0x00, 0x00);                   // LCD_DTCB
+        sendCmd(0xb1, 2, 0x00, 0x1b);                   // LCD_FRMCTR1
+        sendCmd(0xb6, 2, 0x0a, 0xa2);                   // LCD_DFC
+        sendCmd(0xc0, 1, 0x10);                         // LCD_POWER1
+        sendCmd(0xc1, 1, 0x10);                         // LCD_POWER2
+        sendCmd(0xc5, 2, 0x45, 0x15);                   // LCD_VCOM1
+        sendCmd(0xc7, 1, 0x90);                         // LCD_VCOM2
+        sendCmd(0x36, 1, 0xc8);                         // LCD_MAC
+        sendCmd(0xf2, 1, 0x00);                         // LCD_3GAMMA_EN
+        sendCmd(0xb0, 1, 0xc2);                         // LCD_RGB_INTERFACE
+        sendCmd(0xb6, 4, 0x0a, 0xa7, 0x27, 0x04);       // LCD_DFC
+        sendCmd(0x2a, 4, 0x00, 0x00, 0x00, 0xef);       // LCD_COLUMN_ADDR
+        sendCmd(0x2b, 4, 0x00, 0x00, 0x01, 0x3f);       // LCD_PAGE_ADDR
+        sendCmd(0xf6, 3, 0x01, 0x00, 0x06);             // LCD_INTERFACE
+        sendCmd(0x2c, 0);                               // LCD_GRAM
+        Thread::sleep(200);
+        sendCmd(0x26, 1, 0x01); // LCD_GAMMA
+        sendCmd(0xe0, 15, 0x0f, 0x29, 0x24, 0x0c, 0x0e, 0x09, 0x4e, 0x78, 0x3c,
+                0x09, 0x13, 0x05, 0x17, 0x11, 0x00); // LCD_PGAMMA
+        sendCmd(0xe1, 15, 0x00, 0x16, 0x1b, 0x04, 0x11, 0x07, 0x31, 0x33, 0x42,
+                0x05, 0x0c, 0x0a, 0x28, 0x2f, 0x0f); // LCD_NGAMMA
+        sendCmd(0x11, 0);                            // LCD_SLEEP_OUT
+        Thread::sleep(200);
+        sendCmd(0x29, 0); // LCD_DISPLAY_ON
+        sendCmd(0x2c, 0); // LCD_GRAM
+        //
+        // ILI9341 power up sequence -- end
+        //
+
+        memset(framebuffer1, 0, height * width * bpp);
+
+        const unsigned int hsync = 10; // hsync timing
+        const unsigned int vsync = 2;  // vsync timing
+        const unsigned int hbp = 20;   // horizontal back porch
+        const unsigned int vbp = 2;    // vertical back porch
+        const unsigned int hfp = 10;   // horizontal front porch
+        const unsigned int vfp = 4;    // vertical front porch
+        enum
+        {
+            ARGB8888 = 0,
+            RGB888 = 1,
+            RGB565 = 2,
+            ARGB1555 = 3,
+            ARGB4444 = 4,
+            L8 = 5,
+            AL44 = 6,
+            AL88 = 7
+        };
+        // Configure timings
+        LTDC->SSCR = (hsync - 1) << 16 | (vsync - 1);
+        LTDC->BPCR = (hsync + hbp - 1) << 16 | (vsync + vbp - 1);
+        LTDC->AWCR = (hsync + hbp + width - 1) << 16 | (vsync + vbp + height - 1);
+        LTDC->TWCR = (hfp + hsync + hbp + width - 1) << 16 |
+                     (vfp + vsync + vbp + height - 1);
+        // Configre background color (black))
+        LTDC->BCCR = 0;
+        // Enable layer 2
+        LTDC_Layer2->CR = 0                // Disable palette mode
+                          | 0              // Disable color keying
+                          | LTDC_LxCR_LEN; // Enable layer
+        LTDC_Layer2->WHPCR = (hsync + hbp + width - 1) << 16 | (hsync + hbp);
+        LTDC_Layer2->WVPCR = (vsync + vbp + height - 1) << 16 | (vsync + vbp);
+        LTDC_Layer2->CKCR = 0;
+        LTDC_Layer2->PFCR = RGB565;
+        LTDC_Layer2->CACR = 0xff; // Alpha=1
+        LTDC_Layer2->DCCR = 0;
+        LTDC_Layer2->CFBAR = reinterpret_cast<unsigned int>(framebuffer1);
+        LTDC_Layer2->CFBLR =
+            (width * bpp) << 16 | (width * bpp + 3); // Packed lines
+        LTDC_Layer2->CFBLNR = height;
+        // Write to shadow registers
+        LTDC->SRCR = LTDC_SRCR_IMR;
+        // Finally enable the display
+        LTDC->GCR = 0                  // hsync active low
+                    | 0                // vsync active low
+                    | 0                // enable active low
+                    | 0                // input pixel clock
+                    | 0                // no dithering
+                    | LTDC_GCR_LTDCEN; // Display enabled
+
+        setFont(droid11);
+        setTextColor(make_pair(Color(0xffff), Color(0x0000)));
+        clear(black);
+    }
 
-    memset(framebuffer1, 0, height * width * bpp);
+    Color DisplayImpl::pixel_iterator::dummy;
 
-    const unsigned int hsync = 10;  // hsync timing
-    const unsigned int vsync = 2;   // vsync timing
-    const unsigned int hbp   = 20;  // horizontal back porch
-    const unsigned int vbp   = 2;   // vertical back porch
-    const unsigned int hfp   = 10;  // horizontal front porch
-    const unsigned int vfp   = 4;   // vertical front porch
-    enum
-    {
-        ARGB8888 = 0,
-        RGB888   = 1,
-        RGB565   = 2,
-        ARGB1555 = 3,
-        ARGB4444 = 4,
-        L8       = 5,
-        AL44     = 6,
-        AL88     = 7
-    };
-    // Configure timings
-    LTDC->SSCR = (hsync - 1) << 16 | (vsync - 1);
-    LTDC->BPCR = (hsync + hbp - 1) << 16 | (vsync + vbp - 1);
-    LTDC->AWCR = (hsync + hbp + width - 1) << 16 | (vsync + vbp + height - 1);
-    LTDC->TWCR = (hfp + hsync + hbp + width - 1) << 16 |
-                 (vfp + vsync + vbp + height - 1);
-    // Configre background color (black))
-    LTDC->BCCR = 0;
-    // Enable layer 2
-    LTDC_Layer2->CR = 0                 // Disable palette mode
-                      | 0               // Disable color keying
-                      | LTDC_LxCR_LEN;  // Enable layer
-    LTDC_Layer2->WHPCR = (hsync + hbp + width - 1) << 16 | (hsync + hbp);
-    LTDC_Layer2->WVPCR = (vsync + vbp + height - 1) << 16 | (vsync + vbp);
-    LTDC_Layer2->CKCR  = 0;
-    LTDC_Layer2->PFCR  = RGB565;
-    LTDC_Layer2->CACR  = 0xff;  // Alpha=1
-    LTDC_Layer2->DCCR  = 0;
-    LTDC_Layer2->CFBAR = reinterpret_cast<unsigned int>(framebuffer1);
-    LTDC_Layer2->CFBLR =
-        (width * bpp) << 16 | (width * bpp + 3);  // Packed lines
-    LTDC_Layer2->CFBLNR = height;
-    // Write to shadow registers
-    LTDC->SRCR = LTDC_SRCR_IMR;
-    // Finally enable the display
-    LTDC->GCR = 0                   // hsync active low
-                | 0                 // vsync active low
-                | 0                 // enable active low
-                | 0                 // input pixel clock
-                | 0                 // no dithering
-                | LTDC_GCR_LTDCEN;  // Display enabled
-
-    setFont(droid11);
-    setTextColor(make_pair(Color(0xffff), Color(0x0000)));
-    clear(black);
-}
-
-Color DisplayImpl::pixel_iterator::dummy;
-
-}  // namespace mxgui
-
-#endif  //_BOARD_STM32F429ZI_STM32F4DISCOVERY
+} // namespace mxgui
+
+#endif //_BOARD_STM32F429ZI_STM32F4DISCOVERY
 
 #ifdef _BOARD_STM32F469NI_STM32F469I_DISCO
 
 namespace mxgui
 {
 
-// Control interface
-
-// Pixel sync interface
-typedef Gpio<GPIOF_BASE, 10> en;
-typedef Gpio<GPIOG_BASE, 7> dotclk;
-typedef Gpio<GPIOA_BASE, 4> vsync;
-typedef Gpio<GPIOC_BASE, 6> hsync;
-// Pixel data bus
-typedef Gpio<GPIOC_BASE, 10> r0;  // r2
-typedef Gpio<GPIOJ_BASE, 2> r1;   // r3
-typedef Gpio<GPIOA_BASE, 11> r2;  // r4
-typedef Gpio<GPIOA_BASE, 12> r3;  // r5
-typedef Gpio<GPIOJ_BASE, 5> r4;   // r6
-typedef Gpio<GPIOA_BASE, 6> g0;   // g2
-typedef Gpio<GPIOG_BASE, 10> g1;  // g3 AF9
-typedef Gpio<GPIOJ_BASE, 13> g2;  // g4 AF9
-typedef Gpio<GPIOH_BASE, 4> g3;   // g5 AF9
-typedef Gpio<GPIOC_BASE, 7> g4;   // g6
-typedef Gpio<GPIOD_BASE, 3> g5;   // g7
-typedef Gpio<GPIOD_BASE, 6> b0;   // b2
-typedef Gpio<GPIOG_BASE, 11> b1;  // b3
-typedef Gpio<GPIOG_BASE, 12> b2;  // b4 AF9
-typedef Gpio<GPIOA_BASE, 3> b3;   // b5
-typedef Gpio<GPIOB_BASE, 8> b4;   // b6
-
-void shortWrite(uint8_t param0, uint8_t param1)
-{
-    // Command FIFO Empty
-    while ((DSI->GPSR & DSI_GPSR_CMDFE) == 0)
-        ;
+    // Control interface
+
+    // Pixel sync interface
+    typedef Gpio<GPIOF_BASE, 10> en;
+    typedef Gpio<GPIOG_BASE, 7> dotclk;
+    typedef Gpio<GPIOA_BASE, 4> vsync;
+    typedef Gpio<GPIOC_BASE, 6> hsync;
+    // Pixel data bus
+    typedef Gpio<GPIOC_BASE, 10> r0; // r2
+    typedef Gpio<GPIOJ_BASE, 2> r1;  // r3
+    typedef Gpio<GPIOA_BASE, 11> r2; // r4
+    typedef Gpio<GPIOA_BASE, 12> r3; // r5
+    typedef Gpio<GPIOJ_BASE, 5> r4;  // r6
+    typedef Gpio<GPIOA_BASE, 6> g0;  // g2
+    typedef Gpio<GPIOG_BASE, 10> g1; // g3 AF9
+    typedef Gpio<GPIOJ_BASE, 13> g2; // g4 AF9
+    typedef Gpio<GPIOH_BASE, 4> g3;  // g5 AF9
+    typedef Gpio<GPIOC_BASE, 7> g4;  // g6
+    typedef Gpio<GPIOD_BASE, 3> g5;  // g7
+    typedef Gpio<GPIOD_BASE, 6> b0;  // b2
+    typedef Gpio<GPIOG_BASE, 11> b1; // b3
+    typedef Gpio<GPIOG_BASE, 12> b2; // b4 AF9
+    typedef Gpio<GPIOA_BASE, 3> b3;  // b5
+    typedef Gpio<GPIOB_BASE, 8> b4;  // b6
+
+    void shortWrite(uint8_t param0, uint8_t param1)
+    {
+        // Command FIFO Empty
+        while ((DSI->GPSR & DSI_GPSR_CMDFE) == 0)
+            ;
 
-    DSI->GHCR = (0x15 |      // DSI_DCS_SHORT_PKT_WRITE_P1
-                 (0 << 6) |  // Virtual Channel ID
-                 (param0 << 8) | (param1 << 16));
-}
+        DSI->GHCR = (0x15 |     // DSI_DCS_SHORT_PKT_WRITE_P1
+                     (0 << 6) | // Virtual Channel ID
+                     (param0 << 8) | (param1 << 16));
+    }
 
-void longWrite(uint32_t numParams, uint32_t param0, uint8_t *pParams)
-{
-    // Command FIFO Empty
-    while ((DSI->GPSR & DSI_GPSR_CMDFE) == 0)
-        ;
+    void longWrite(uint32_t numParams, uint32_t param0, uint8_t *pParams)
+    {
+        // Command FIFO Empty
+        while ((DSI->GPSR & DSI_GPSR_CMDFE) == 0)
+            ;
+
+        uint32_t uicounter = 0;
+        while (uicounter < numParams)
+        {
+            if (uicounter == 0x00)
+            {
+                DSI->GPDR = (param0 | ((*(pParams + uicounter)) << 8) |
+                             ((*(pParams + uicounter + 1)) << 16) |
+                             ((*(pParams + uicounter + 2)) << 24));
+                uicounter += 3;
+            }
+            else
+            {
+                DSI->GPDR = ((*(pParams + uicounter)) |
+                             ((*(pParams + uicounter + 1)) << 8) |
+                             ((*(pParams + uicounter + 2)) << 16) |
+                             ((*(pParams + uicounter + 3)) << 24));
+                uicounter += 4;
+            }
+        }
 
-    uint32_t uicounter = 0;
-    while (uicounter < numParams)
+        DSI->GHCR = (0x39 |     // DSI_DCS_LONG_PKT_WRITE
+                     (0 << 6) | // Virtual Channel Id
+                     (((numParams + 1) & 0x00FF) << 8) |
+                     ((((numParams + 1) & 0xFF00) >> 8) << 16));
+    }
+
+    void sendCmd(uint32_t numParams, uint8_t *pParams)
     {
-        if (uicounter == 0x00)
+        if (numParams <= 1)
         {
-            DSI->GPDR = (param0 | ((*(pParams + uicounter)) << 8) |
-                         ((*(pParams + uicounter + 1)) << 16) |
-                         ((*(pParams + uicounter + 2)) << 24));
-            uicounter += 3;
+            shortWrite(pParams[0], pParams[1]);
         }
         else
         {
-            DSI->GPDR = ((*(pParams + uicounter)) |
-                         ((*(pParams + uicounter + 1)) << 8) |
-                         ((*(pParams + uicounter + 2)) << 16) |
-                         ((*(pParams + uicounter + 3)) << 24));
-            uicounter += 4;
+            longWrite(numParams, pParams[numParams], pParams);
         }
     }
 
-    DSI->GHCR = (0x39 |      // DSI_DCS_LONG_PKT_WRITE
-                 (0 << 6) |  // Virtual Channel Id
-                 (((numParams + 1) & 0x00FF) << 8) |
-                 ((((numParams + 1) & 0xFF00) >> 8) << 16));
-}
-
-void sendCmd(uint32_t numParams, uint8_t *pParams)
-{
-    if (numParams <= 1)
+    void registerDisplayHook(DisplayManager &dm)
     {
-        shortWrite(pParams[0], pParams[1]);
+        dm.registerDisplay(&DisplayImpl::instance());
     }
-    else
-    {
-        longWrite(numParams, pParams[numParams], pParams);
-    }
-}
-
-void registerDisplayHook(DisplayManager &dm)
-{
-    dm.registerDisplay(&DisplayImpl::instance());
-}
 
-//
-// class DisplayImpl
-//
+    //
+    // class DisplayImpl
+    //
 
-DisplayImpl &DisplayImpl::instance()
-{
-    static DisplayImpl instance;
-    return instance;
-}
+    DisplayImpl &DisplayImpl::instance()
+    {
+        static DisplayImpl instance;
+        return instance;
+    }
 
-void DisplayImpl::doTurnOn()
-{
-    LTDC->GCR |= LTDC_GCR_LTDCEN;
-    Thread::sleep(40);
-    uint8_t set_display_on[] = {0x29, 0x00};
-    sendCmd(0, set_display_on);
-}
+    void DisplayImpl::doTurnOn()
+    {
+        LTDC->GCR |= LTDC_GCR_LTDCEN;
+        Thread::sleep(40);
+        uint8_t set_display_on[] = {0x29, 0x00};
+        sendCmd(0, set_display_on);
+    }
 
-void DisplayImpl::doTurnOff()
-{
-    uint8_t set_display_off[] = {0x28, 0x00};
-    sendCmd(0, set_display_off);
-    LTDC->GCR &= ~LTDC_GCR_LTDCEN;
-}
+    void DisplayImpl::doTurnOff()
+    {
+        uint8_t set_display_off[] = {0x28, 0x00};
+        sendCmd(0, set_display_off);
+        LTDC->GCR &= ~LTDC_GCR_LTDCEN;
+    }
 
-void DisplayImpl::doSetBrightness(int brt) {}
+    void DisplayImpl::doSetBrightness(int brt) {}
 
-pair<short int, short int> DisplayImpl::doGetSize() const
-{
-    return make_pair(height, width);
-}
+    pair<short int, short int> DisplayImpl::doGetSize() const
+    {
+        return make_pair(height, width);
+    }
 
-void DisplayImpl::write(Point p, const char *text)
-{
-    font.draw(*this, textColor, p, text);
-}
+    void DisplayImpl::write(Point p, const char *text)
+    {
+        font.draw(*this, textColor, p, text);
+    }
 
-void DisplayImpl::clippedWrite(Point p, Point a, Point b, const char *text)
-{
-    font.clippedDraw(*this, textColor, p, a, b, text);
-}
+    void DisplayImpl::clippedWrite(Point p, Point a, Point b, const char *text)
+    {
+        font.clippedDraw(*this, textColor, p, a, b, text);
+    }
 
-void DisplayImpl::clear(Color color)
-{
-    clear(Point(0, 0), Point(width - 1, height - 1), color);
-}
+    void DisplayImpl::clear(Color color)
+    {
+        clear(Point(0, 0), Point(width - 1, height - 1), color);
+    }
 
-void DisplayImpl::clear(Point p1, Point p2, Color color)
-{
-    if (p1.x() < 0 || p2.x() < p1.x() || p2.x() >= width || p1.y() < 0 ||
-        p2.y() < p1.y() || p2.y() >= height)
-        return;
-    if ((color & 0xff) == (color >> 8))
+    void DisplayImpl::clear(Point p1, Point p2, Color color)
     {
-        // Can use memset
-        if (p1.x() == 0 && p2.x() == width - 1)
-        {
-            // Can merge lines
-            memset(framebuffer1 + p1.y() * width, color,
-                   (p2.y() - p1.y() + 1) * width * bpp);
-        }
-        else
+        if (p1.x() < 0 || p2.x() < p1.x() || p2.x() >= width || p1.y() < 0 ||
+            p2.y() < p1.y() || p2.y() >= height)
+            return;
+        if ((color & 0xff) == (color >> 8))
         {
-            // Can't merge lines
-            Color *ptr = framebuffer1 + p1.x() + width * p1.y();
-            short len  = p2.x() - p1.x() + 1;
-            for (short i = p1.y(); i <= p2.y(); i++)
+            // Can use memset
+            if (p1.x() == 0 && p2.x() == width - 1)
             {
-                memset(ptr, color, len * bpp);
-                ptr += width;
+                // Can merge lines
+                memset(framebuffer1 + p1.y() * width, color,
+                       (p2.y() - p1.y() + 1) * width * bpp);
             }
-        }
-    }
-    else
-    {
-        // Can't use memset
-        if (p1.x() == 0 && p2.x() == width - 1)
-        {
-            // Can merge lines
-            Color *ptr    = framebuffer1 + p1.y() * width;
-            int numPixels = (p2.y() - p1.y() + 1) * width;
-            // This loop is worth unrolling
-            for (int i = 0; i < numPixels / 4; i++)
+            else
             {
-                *ptr++ = color;
-                *ptr++ = color;
-                *ptr++ = color;
-                *ptr++ = color;
+                // Can't merge lines
+                Color *ptr = framebuffer1 + p1.x() + width * p1.y();
+                short len = p2.x() - p1.x() + 1;
+                for (short i = p1.y(); i <= p2.y(); i++)
+                {
+                    memset(ptr, color, len * bpp);
+                    ptr += width;
+                }
             }
-            for (int i = 0; i < (numPixels & 3); i++)
-                *ptr++ = color;
         }
         else
         {
-            // Can't merge lines
-            Color *ptr = framebuffer1 + p1.x() + width * p1.y();
-            short len  = p2.x() - p1.x() + 1;
-            for (short i = p1.y(); i <= p2.y(); i++)
+            // Can't use memset
+            if (p1.x() == 0 && p2.x() == width - 1)
             {
-                for (short j = 0; j < len; j++)
+                // Can merge lines
+                Color *ptr = framebuffer1 + p1.y() * width;
+                int numPixels = (p2.y() - p1.y() + 1) * width;
+                // This loop is worth unrolling
+                for (int i = 0; i < numPixels / 4; i++)
+                {
+                    *ptr++ = color;
+                    *ptr++ = color;
                     *ptr++ = color;
-                ptr += width - len;
+                    *ptr++ = color;
+                }
+                for (int i = 0; i < (numPixels & 3); i++)
+                    *ptr++ = color;
+            }
+            else
+            {
+                // Can't merge lines
+                Color *ptr = framebuffer1 + p1.x() + width * p1.y();
+                short len = p2.x() - p1.x() + 1;
+                for (short i = p1.y(); i <= p2.y(); i++)
+                {
+                    for (short j = 0; j < len; j++)
+                        *ptr++ = color;
+                    ptr += width - len;
+                }
             }
         }
     }
-}
 
-void DisplayImpl::beginPixel() {}
-
-void DisplayImpl::setPixel(Point p, Color color)
-{
-    int offset = p.x() + p.y() * width;
-    if (offset < 0 || offset >= numPixels)
-        return;
-    *(framebuffer1 + offset) = color;
-}
+    void DisplayImpl::beginPixel() {}
 
-void DisplayImpl::line(Point a, Point b, Color color)
-{
-    // Horizontal line speed optimization
-    if (a.y() == b.y())
+    void DisplayImpl::setPixel(Point p, Color color)
     {
-        short minx = min(a.x(), b.x());
-        short maxx = max(a.x(), b.x());
-        if (minx < 0 || maxx >= width || a.y() < 0 || a.y() >= height)
+        int offset = p.x() + p.y() * width;
+        if (offset < 0 || offset >= numPixels)
             return;
-        Color *ptr = framebuffer1 + minx + width * a.y();
-        for (short i = minx; i <= maxx; i++)
-            *ptr++ = color;
-        return;
+        *(framebuffer1 + offset) = color;
     }
-    // Vertical line speed optimization
-    if (a.x() == b.x())
+
+    void DisplayImpl::line(Point a, Point b, Color color)
     {
-        short miny = min(a.y(), b.y());
-        short maxy = max(a.y(), b.y());
-        if (a.x() < 0 || a.x() >= width || miny < 0 || maxy >= height)
+        // Horizontal line speed optimization
+        if (a.y() == b.y())
+        {
+            short minx = min(a.x(), b.x());
+            short maxx = max(a.x(), b.x());
+            if (minx < 0 || maxx >= width || a.y() < 0 || a.y() >= height)
+                return;
+            Color *ptr = framebuffer1 + minx + width * a.y();
+            for (short i = minx; i <= maxx; i++)
+                *ptr++ = color;
             return;
-        Color *ptr = framebuffer1 + a.x() + width * miny;
-        for (short i = miny; i <= maxy; i++)
+        }
+        // Vertical line speed optimization
+        if (a.x() == b.x())
         {
-            *ptr = color;
-            ptr += width;
+            short miny = min(a.y(), b.y());
+            short maxy = max(a.y(), b.y());
+            if (a.x() < 0 || a.x() >= width || miny < 0 || maxy >= height)
+                return;
+            Color *ptr = framebuffer1 + a.x() + width * miny;
+            for (short i = miny; i <= maxy; i++)
+            {
+                *ptr = color;
+                ptr += width;
+            }
+            return;
         }
-        return;
+        // General case
+        Line::draw(*this, a, b, color);
     }
-    // General case
-    Line::draw(*this, a, b, color);
-}
 
-void DisplayImpl::scanLine(Point p, const Color *colors, unsigned short length)
-{
-    if (p.x() < 0 ||
-        static_cast<int>(p.x()) + static_cast<int>(length) > width ||
-        p.y() < 0 || p.y() >= height)
-        return;
-    Color *ptr = framebuffer1 + p.x() + p.y() * width;
-    memcpy(ptr, colors, length * bpp);
-}
-
-Color *DisplayImpl::getScanLineBuffer() { return buffer; }
+    void DisplayImpl::scanLine(Point p, const Color *colors, unsigned short length)
+    {
+        if (p.x() < 0 ||
+            static_cast<int>(p.x()) + static_cast<int>(length) > width ||
+            p.y() < 0 || p.y() >= height)
+            return;
+        Color *ptr = framebuffer1 + p.x() + p.y() * width;
+        memcpy(ptr, colors, length * bpp);
+    }
 
-void DisplayImpl::scanLineBuffer(Point p, unsigned short length)
-{
-    int offset = p.x() + p.y() * width;
-    if (offset < 0 || offset >= numPixels)
-        return;
-    memcpy(framebuffer1 + offset, buffer, length * bpp);
-}
+    Color *DisplayImpl::getScanLineBuffer() { return buffer; }
 
-void DisplayImpl::drawImage(Point p, const ImageBase &img)
-{
-    short int xEnd = p.x() + img.getWidth() - 1;
-    short int yEnd = p.y() + img.getHeight() - 1;
-    if (p.x() < 0 || p.y() < 0 || xEnd < p.x() || yEnd < p.y() ||
-        xEnd >= width || yEnd >= height)
-        return;
+    void DisplayImpl::scanLineBuffer(Point p, unsigned short length)
+    {
+        int offset = p.x() + p.y() * width;
+        if (offset < 0 || offset >= numPixels)
+            return;
+        memcpy(framebuffer1 + offset, buffer, length * bpp);
+    }
 
-    //    const unsigned short *imgData=img.getData();
-    //    if(imgData!=0)
-    //    {
-    //        //TODO Optimized version for in-memory images
-    //    } else
-    img.draw(*this, p);
-}
+    void DisplayImpl::drawImage(Point p, const ImageBase &img)
+    {
+        short int xEnd = p.x() + img.getWidth() - 1;
+        short int yEnd = p.y() + img.getHeight() - 1;
+        if (p.x() < 0 || p.y() < 0 || xEnd < p.x() || yEnd < p.y() ||
+            xEnd >= width || yEnd >= height)
+            return;
 
-void DisplayImpl::clippedDrawImage(Point p, Point a, Point b,
-                                   const ImageBase &img)
-{
-    //    if(img.getData()==0)
-    //    {
-    img.clippedDraw(*this, p, a, b);
-    return;
-    //    } //else optimized version for memory-loaded images
-    //        //TODO: optimize
-    //    }
-}
-
-void DisplayImpl::drawRectangle(Point a, Point b, Color c)
-{
-    line(a, Point(b.x(), a.y()), c);
-    line(Point(b.x(), a.y()), b, c);
-    line(b, Point(a.x(), b.y()), c);
-    line(Point(a.x(), b.y()), a, c);
-}
+        //    const unsigned short *imgData=img.getData();
+        //    if(imgData!=0)
+        //    {
+        //        //TODO Optimized version for in-memory images
+        //    } else
+        img.draw(*this, p);
+    }
 
-void DisplayImpl::update() { DSI->WCR |= DSI_WCR_LTDCEN; }
+    void DisplayImpl::clippedDrawImage(Point p, Point a, Point b,
+                                       const ImageBase &img)
+    {
+        //    if(img.getData()==0)
+        //    {
+        img.clippedDraw(*this, p, a, b);
+        return;
+        //    } //else optimized version for memory-loaded images
+        //        //TODO: optimize
+        //    }
+    }
 
-DisplayImpl::pixel_iterator DisplayImpl::begin(Point p1, Point p2,
-                                               IteratorDirection d)
-{
-    bool fail = false;
-    if (p1.x() < 0 || p1.y() < 0 || p2.x() < 0 || p2.y() < 0)
-        fail = true;
-    if (p1.x() >= width || p1.y() >= height || p2.x() >= width ||
-        p2.y() >= height)
-        fail = true;
-    if (p2.x() < p1.x() || p2.y() < p1.y())
-        fail = true;
-    if (fail)
+    void DisplayImpl::drawRectangle(Point a, Point b, Color c)
     {
-        // Return invalid (dummy) iterators
-        this->last = pixel_iterator();
-        return this->last;
+        line(a, Point(b.x(), a.y()), c);
+        line(Point(b.x(), a.y()), b, c);
+        line(b, Point(a.x(), b.y()), c);
+        line(Point(a.x(), b.y()), a, c);
     }
 
-    // Set the last iterator to a suitable one-past-the last value
-    if (d == DR)
-        this->last = pixel_iterator(Point(p2.x() + 1, p1.y()), p2, d, this);
-    else
-        this->last = pixel_iterator(Point(p1.x(), p2.y() + 1), p2, d, this);
+    void DisplayImpl::update() { DSI->WCR |= DSI_WCR_LTDCEN; }
 
-    return pixel_iterator(p1, p2, d, this);
-}
+    DisplayImpl::pixel_iterator DisplayImpl::begin(Point p1, Point p2,
+                                                   IteratorDirection d)
+    {
+        bool fail = false;
+        if (p1.x() < 0 || p1.y() < 0 || p2.x() < 0 || p2.y() < 0)
+            fail = true;
+        if (p1.x() >= width || p1.y() >= height || p2.x() >= width ||
+            p2.y() >= height)
+            fail = true;
+        if (p2.x() < p1.x() || p2.y() < p1.y())
+            fail = true;
+        if (fail)
+        {
+            // Return invalid (dummy) iterators
+            this->last = pixel_iterator();
+            return this->last;
+        }
 
-DisplayImpl::~DisplayImpl() {}
+        // Set the last iterator to a suitable one-past-the last value
+        if (d == DR)
+            this->last = pixel_iterator(Point(p2.x() + 1, p1.y()), p2, d, this);
+        else
+            this->last = pixel_iterator(Point(p1.x(), p2.y() + 1), p2, d, this);
 
-DisplayImpl::DisplayImpl()
-    : framebuffer1(reinterpret_cast<unsigned short *>(0xc0c00000)),
-      buffer(framebuffer1 + numPixels)
-{
-    /* This driver uses DSI interface in command mode, but it was firstly
-     * programmed in video mode. For this reason some instructions are still
-     * there but they don't actually affect the driver. For example these timing
-     * parameters are important in video mode, but in command mode they can take
-     * any value and the display still works.
-     */
-    const unsigned int hsync = 12;   // hsync timing
-    const unsigned int vsync = 120;  // vsync timing
-    const unsigned int hbp   = 12;   // horizontal back porch
-    const unsigned int vbp   = 120;  // vertical back porch
-    const unsigned int hfp   = 12;   // horizontal front porch
-    const unsigned int vfp   = 120;  // vertical front porch
-    enum
+        return pixel_iterator(p1, p2, d, this);
+    }
+
+    DisplayImpl::~DisplayImpl() {}
+
+    DisplayImpl::DisplayImpl()
+        : framebuffer1(reinterpret_cast<unsigned short *>(0xc0c00000)),
+          buffer(framebuffer1 + numPixels)
     {
-        ARGB8888 = 0,
-        RGB888   = 1,
-        RGB565   = 2,
-        ARGB1555 = 3,
-        ARGB4444 = 4,
-        L8       = 5,
-        AL44     = 6,
-        AL88     = 7
-    };
+        /* This driver uses DSI interface in command mode, but it was firstly
+         * programmed in video mode. For this reason some instructions are still
+         * there but they don't actually affect the driver. For example these timing
+         * parameters are important in video mode, but in command mode they can take
+         * any value and the display still works.
+         */
+        const unsigned int hsync = 12;  // hsync timing
+        const unsigned int vsync = 120; // vsync timing
+        const unsigned int hbp = 12;    // horizontal back porch
+        const unsigned int vbp = 120;   // vertical back porch
+        const unsigned int hfp = 12;    // horizontal front porch
+        const unsigned int vfp = 120;   // vertical front porch
+        enum
+        {
+            ARGB8888 = 0,
+            RGB888 = 1,
+            RGB565 = 2,
+            ARGB1555 = 3,
+            ARGB4444 = 4,
+            L8 = 5,
+            AL44 = 6,
+            AL88 = 7
+        };
 
 // Parameters for DSI PLL
 // These values assume HSE oscillator is 8 MHz and system clock is 168 MHz
 #if HSE_VALUE != 8000000
 #error The display driver requires an HSE oscillator running at 8 MHz
 #endif
-    const unsigned int IDF  = 4;    // must be in the range 1..7
-    const unsigned int ODF  = 1;    // must be in the set {1, 2, 4, 8}
-    const unsigned int NDIV = 125;  // must be in the range 10..125
-    const unsigned int F_VCO =
-        (HSE_VALUE / IDF) * 2 *
-        NDIV;  // 500 MHz - must be between 500 and 1000 MHz
-    const unsigned int F_PHY_MHz =
-        (F_VCO / (2 * ODF)) /
-        1000000;  // 250 MHz - HS clock for D-PHY must be between 80 and 500 MHz
-    const unsigned int lane_byte_clk =
-        F_VCO / (2 * ODF * 8);  // 31,25 MHz - must be no more than 62,5 MHz
-    const unsigned int TXECLKDIV =
-        2;  // must be at least 2 and ensure lane_byte_clk/TXECLKDIV <= 20 MHz
-    const unsigned int pixel_clock = F_VCO / bpp;  // 31,25 MHz
-    const unsigned int clock_ratio = lane_byte_clk / pixel_clock;
-
-    memset(framebuffer1, 0, height * width * bpp);
-
-    // Reset of screen by active low on GPIO PH7
-    typedef Gpio<GPIOH_BASE, 7> reset;
-    reset::mode(Mode::OUTPUT);
-    reset::speed(Speed::_100MHz);
-    reset::low();
-    Thread::sleep(20);
-    reset::high();
-    Thread::sleep(10);
-
-    // Enable clock for DSI and LTDC then force their reset
-    {
-        FastInterruptDisableLock dLock;
-
-        en::mode(Mode::ALTERNATE);
-        en::alternateFunction(14);
-        en::speed(Speed::_100MHz);
-        dotclk::mode(Mode::ALTERNATE);
-        dotclk::alternateFunction(14);
-        dotclk::speed(Speed::_100MHz);
-        vsync::mode(Mode::ALTERNATE);
-        vsync::alternateFunction(14);
-        vsync::speed(Speed::_100MHz);
-        hsync::mode(Mode::ALTERNATE);
-        hsync::alternateFunction(14);
-        hsync::speed(Speed::_100MHz);
-        r0::mode(Mode::ALTERNATE);
-        r0::alternateFunction(14);
-        r0::speed(Speed::_100MHz);
-        r1::mode(Mode::ALTERNATE);
-        r1::alternateFunction(14);
-        r1::speed(Speed::_100MHz);
-        r2::mode(Mode::ALTERNATE);
-        r2::alternateFunction(14);
-        r2::speed(Speed::_100MHz);
-        r3::mode(Mode::ALTERNATE);
-        r3::alternateFunction(14);
-        r3::speed(Speed::_100MHz);
-        r4::mode(Mode::ALTERNATE);
-        r4::alternateFunction(14);
-        r4::speed(Speed::_100MHz);
-        g0::mode(Mode::ALTERNATE);
-        g0::alternateFunction(14);
-        g0::speed(Speed::_100MHz);
-        g1::mode(Mode::ALTERNATE);
-        g1::alternateFunction(9);
-        g1::speed(Speed::_100MHz);
-        g2::mode(Mode::ALTERNATE);
-        g2::alternateFunction(9);
-        g2::speed(Speed::_100MHz);
-        g3::mode(Mode::ALTERNATE);
-        g3::alternateFunction(9);
-        g3::speed(Speed::_100MHz);
-        g4::mode(Mode::ALTERNATE);
-        g4::alternateFunction(14);
-        g4::speed(Speed::_100MHz);
-        g5::mode(Mode::ALTERNATE);
-        g5::alternateFunction(14);
-        g5::speed(Speed::_100MHz);
-        b0::mode(Mode::ALTERNATE);
-        b0::alternateFunction(14);
-        b0::speed(Speed::_100MHz);
-        b1::mode(Mode::ALTERNATE);
-        b1::alternateFunction(14);
-        b1::speed(Speed::_100MHz);
-        b2::mode(Mode::ALTERNATE);
-        b2::alternateFunction(9);
-        b2::speed(Speed::_100MHz);
-        b3::mode(Mode::ALTERNATE);
-        b3::alternateFunction(14);
-        b3::speed(Speed::_100MHz);
-        b4::mode(Mode::ALTERNATE);
-        b4::alternateFunction(14);
-        b4::speed(Speed::_100MHz);
-
-        RCC->APB2ENR |= RCC_APB2ENR_LTDCEN;
-        RCC_SYNC();
-        RCC->APB2ENR |= RCC_APB2ENR_DSIEN;
-        RCC_SYNC();
-
-        RCC->APB2RSTR |= RCC_APB2RSTR_LTDCRST;
-        RCC->APB2RSTR &= ~RCC_APB2RSTR_LTDCRST;
-
-        RCC->APB2RSTR |= RCC_APB2RSTR_DSIRST;
-        RCC->APB2RSTR &= ~RCC_APB2RSTR_DSIRST;
-    }
-
-    // Configure PLLSAI for LTDC, turn it ON and wait for its lock
-    {
-        FastInterruptDisableLock dLock;
-
-        // LTDC clock depends on PLL_M which is fixed at boot with value 8
-        // It also depends on PLLSAI which can be freely configured
-        const unsigned int PLLSAI_N = 384;
-        const unsigned int PLLSAI_R = 7;
-        // const unsigned int PLLSAI_DIVR = 0;
-
-        // Input VCO Frequency = HSE_VALUE/PPL_M must be between 1 and 2 MHz, so
-        // 8/8 = 1 MHz N must be in the range 50..432 and ensure a frequency
-        // between 100 and 432 MHz if N = 384 then 1 MHz * 384 = 384 MHz R must
-        // be in the range 2..7, we choose R = 7 so 384/7 = 54,857 MHz and then
-        // we divide it by 2 (setting DIVR to 0) to obtain 27,428 Mhz
-
-        // Read PLLSAI_P and PLLSAI_Q values from PLLSAICFGR register
-        uint32_t PLLSAI_P = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> 16);
-        uint32_t PLLSAI_Q = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24);
-        // PLLSAI_VCO_Input  = PLL_SOURCE/PLL_M
-        // PLLSAI_VCO_Output = PLLSAI_VCO_Input * PLLSAI_N
-        // LTDC_CLK(first level) = PLLSAI_VCO_Output/PLLSAI_R
-        RCC->PLLSAICFGR = (PLLSAI_N << 6) | (PLLSAI_P << 16) |
-                          (PLLSAI_Q << 24) | (PLLSAI_R << 28);
-        // LTDC_CLK = LTDC_CLK(first level)/PLLSAI_DIVR
-        RCC->DCKCFGR = RCC->DCKCFGR & ~RCC_DCKCFGR_PLLSAIDIVR;
-
-        RCC->CR |= RCC_CR_PLLSAION;
-    }
-    while ((RCC->CR & RCC_CR_PLLSAIRDY) == 0)
-        ;
-
-    /* Start LTDC configuration */
-    // Configure timings
-    LTDC->SSCR = (hsync - 1) << 16 | (vsync - 1);
-    LTDC->BPCR = (hsync + hbp - 1) << 16 | (vsync + vbp - 1);
-    LTDC->AWCR = (hsync + hbp + width - 1) << 16 | (vsync + vbp + height - 1);
-    LTDC->TWCR = (hsync + hbp + width + hfp - 1) << 16 |
-                 (vsync + vbp + height + vfp - 1);
-
-    // Configure polarities (everything active high except data enabled)
-    LTDC->GCR |=
-        (LTDC_GCR_HSPOL | LTDC_GCR_VSPOL | LTDC_GCR_DEPOL | LTDC_GCR_PCPOL);
-    LTDC->GCR &= ~LTDC_GCR_DEPOL;
-
-    // Configure background color
-    LTDC->BCCR = 0;
-
-    // Configure the layer
-    // Horizontal start and stop position
-    LTDC_Layer1->WHPCR &= ~(LTDC_LxWHPCR_WHSTPOS | LTDC_LxWHPCR_WHSPPOS);
-    LTDC_Layer1->WHPCR = ((hsync + hbp + width - 1) << 16) | (hsync + hbp);
-    // Vertical start and stop position
-    LTDC_Layer1->WVPCR &= ~(LTDC_LxWVPCR_WVSTPOS | LTDC_LxWVPCR_WVSPPOS);
-    LTDC_Layer1->WVPCR = ((vsync + vbp + height - 1) << 16) | (vsync + vbp);
-    // Pixel format
-    LTDC_Layer1->PFCR &= ~(LTDC_LxPFCR_PF);
-    LTDC_Layer1->PFCR |= RGB565;
-    // Color frame buffer start address
-    LTDC_Layer1->CFBAR &= ~(LTDC_LxCFBAR_CFBADD);
-    LTDC_Layer1->CFBAR = reinterpret_cast<unsigned int>(framebuffer1);
-    // Color frame buffer pitch in byte (multiply by 2 for RGB565)
-    LTDC_Layer1->CFBLR &= ~(LTDC_LxCFBLR_CFBP | LTDC_LxCFBLR_CFBLL);
-    LTDC_Layer1->CFBLR = (width * 2) << 16 | (width * 2 + 3);
-    // Frame buffer line number
-    LTDC_Layer1->CFBLNR &= ~(LTDC_LxCFBLNR_CFBLNBR);
-    LTDC_Layer1->CFBLNR = height;
-    // Default color values (black with no alpha)
-    LTDC_Layer1->DCCR &= ~(LTDC_LxDCCR_DCBLUE | LTDC_LxDCCR_DCGREEN |
-                           LTDC_LxDCCR_DCRED | LTDC_LxDCCR_DCALPHA);
-    LTDC_Layer1->DCCR = 0;
-    // Specifies the constant alpha value
-    LTDC_Layer1->CACR &= ~(LTDC_LxCACR_CONSTA);
-    LTDC_Layer1->CACR = 255;
-    // Blending factors (constant alpha)
-    LTDC_Layer1->BFCR &= ~(LTDC_LxBFCR_BF2 | LTDC_LxBFCR_BF1);
-    LTDC_Layer1->BFCR = (0x400 | 0x5);
-    // Enable layer
-    LTDC_Layer1->CR |= LTDC_LxCR_LEN;
-
-    // If needed enable dithering and color keying
-    LTDC_Layer1->CKCR = 0;
-
-    // Reload shadow registers
-    LTDC->SRCR |= LTDC_SRCR_IMR;
-
-    // Finally enable the display
-    LTDC->GCR |= LTDC_GCR_LTDCEN;
-    /* End LTDC configuration */
-
-    /* Start DSI configuration */
-    // Turn on the DSI regulator and wait for the regulator ready
-    DSI->WRPCR |= DSI_WRPCR_REGEN;
-    while ((DSI->WISR & DSI_WISR_RRS) == 0)
-        ;
-
-    // Configure the DSI PLL, turn it ON and wait for its lock
-    // F_VCO = (HSE_VALUE / IDF) * 2 * NDIV
-    // Lane_Byte_CLK = F_VCO / (2 * ODF * 8)
-    // F_VCO must be in the range from 500 MHz to 1 GHz
-    // To obtain 500 Mbit/s rate, Lane_Byte_CLK must be 31,25 MHz
-    // Since HSE_VALUE = 8 MHz this is possible with NDIV = 125, IDF = 4, ODF =
-    // 1
-    DSI->WRPCR &= ~(DSI_WRPCR_PLL_NDIV | DSI_WRPCR_PLL_IDF | DSI_WRPCR_PLL_ODF);
-    DSI->WRPCR |= ((NDIV << 2) | (IDF << 11) | (ODF << 16));
-    DSI->WRPCR |= DSI_WRPCR_PLLEN;
-    while ((DSI->WISR & DSI_WISR_PLLLS) == 0)
-        ;
-
-    // Configure the D-PHY parameters
-    // Calculate the bit period in high-speed mode in unit of 0.25 ns (UIX4)
-    // The equation is: UIX4 = IntegerPart( (1000/F_PHY_MHz) * 4 )
-    // Where: F_PHY_MHz = (NDIV * HSE_MHz) / (IDF * ODF)
-    DSI->WPCR[0] &= ~DSI_WPCR0_UIX4;
-    DSI->WPCR[0] |= (1000 / F_PHY_MHz) * 4;
-    // Disable all error interrupts and reset the Error Mask
-    DSI->IER[0] = 0;
-    DSI->IER[1] = 0;
-    // Configure the number of active data lanes (just one out of two for 16
-    // bpp)
-    DSI->PCONFR &= ~DSI_PCONFR_NL;
-    DSI->PCONFR |= 1;
-    // Set automatic clock lane control
-    DSI->CLCR |= (DSI_CLCR_DPCC | DSI_CLCR_ACR);
-    // Time for LP/HS and HS/LP transitions for both clock lane and data lanes
-    DSI->CLTCR |= (40 << 16)     // HS to LP
-                  | (40 << 0);   // LP to HS
-    DSI->DLTCR |= (20 << 24)     // HS to LP
-                  | (20 << 16);  // HS to LP
-    // Stop wait time (don't know how much should it be, random high number in 8
-    // bit)
-    DSI->PCONFR &= ~DSI_PCONFR_SW_TIME;
-    DSI->PCONFR |= (100 << 8);
-
-    // Configure the DSI Host timing
-    // DSI->CCR |= (... << 8); // timeout clock configuration non dice nulla...
-    // Configure clock speed for low-power mode
-    DSI->CCR &= ~DSI_CCR_TXECKDIV;
-    DSI->CCR |= TXECLKDIV;
-
-    // Configure the DSI Host flow control and DBI interface
-    DSI->PCR &= ~(DSI_PCR_CRCRXE | DSI_PCR_ECCRXE | DSI_PCR_BTAE |
-                  DSI_PCR_ETRXE | DSI_PCR_ETTXE);
-    DSI->GVCIDR &=
-        ~DSI_GVCIDR_VCID;  // set Virtual Channel ID = 0 for the display
-
-    // Configure the DSI Host LTDC interface
-    DSI->LVCIDR &= ~3;  // Virtual channel ID for LTDC interface traffic
-    DSI->LCOLCR &= ~DSI_LCOLCR_COLC;
-    DSI->LCOLCR |= RGB565;  // Color coding for the host
-    DSI->WCFGR &= ~DSI_WCFGR_COLMUX;
-    DSI->WCFGR |= RGB565 << 1;  // Color coding for the wrapper
-    DSI->LPCR &= ~(DSI_LPCR_DEP | DSI_LPCR_VSP | DSI_LPCR_HSP);
-    DSI->LPCR |=
-        (DSI_LPCR_DEP | 0 |
-         0);  // Polarity of control signals: same of LTDC except for DE
-    DSI->WCFGR |= DSI_WCFGR_VSPOL;  // LTDC halts at VSYNC rising edge
-
-    // Configure the DSI Host for command mode
-    // Select command mode by setting CMDM and DSIM bits
-    DSI->MCR |= DSI_MCR_CMDM;
-    DSI->WCFGR |= DSI_WCFGR_DSIM;
-    // Configure the maximum allowed size for write memory command
-    DSI->LCCR &= ~DSI_LCCR_CMDSIZE;
-    DSI->LCCR |= width;
-
-    DSI->VMCR |= 0x3f << 8;         // LP allowed in all video periods
-    DSI->VMCR &= ~DSI_VMCR_FBTAAE;  // Do not request acknowledge at end of
-                                    // frame (at this time)
-    DSI->VMCR |= DSI_VMCR_LPCE;     // Allow commands in LP
-    DSI->VPCR |= width;             // Video packet size
-    DSI->VCCR = 0;  // Chunks number to be transmitted through the DSI link
-    DSI->VNPCR |= 0xFFF;  // Size of the null packet
-    // Timings in lane byte clock cycles
-    DSI->VLCR |= (hsync + hbp + width + hfp) * clock_ratio;
-    DSI->VHSACR |= hsync * clock_ratio;
-    DSI->VHBPCR |= hbp * clock_ratio;
-    DSI->VVSACR |= vsync;
-    DSI->VVBPCR |= vbp;
-    DSI->VVFPCR |= vfp;
-    DSI->VVACR |= height;
-    DSI->LPMCR |= (64 << 16);  // Low power largest packet size
-    DSI->LPMCR |= 64;          // Low power VACT largest packet size
-    // Command trasmission only in low power mode
-    DSI->CMCR |=
-        (DSI_CMCR_GSW0TX | DSI_CMCR_GSW1TX | DSI_CMCR_GSW2TX | DSI_CMCR_GSR0TX |
-         DSI_CMCR_GSR1TX | DSI_CMCR_GSR2TX | DSI_CMCR_GLWTX | DSI_CMCR_DSW0TX |
-         DSI_CMCR_DSW1TX | DSI_CMCR_DSR0TX | DSI_CMCR_DLWTX | DSI_CMCR_MRDPS);
-
-    // Configure the acknowledge request after each packet transmission
-    DSI->CMCR |= DSI_CMCR_ARE;
-
-    // Enable the D-PHY data lane
-    DSI->PCTLR |= DSI_PCTLR_DEN;
-
-    // Enable the D-PHY clock lane
-    DSI->PCTLR |= DSI_PCTLR_CKE;
-
-    // Enable the DSI Host
-    DSI->CR |= DSI_CR_EN;
-
-    // Enable the DSI wrapper
-    DSI->WCR |= DSI_WCR_DSIEN;
-    /* End DSI configuration */
-
-    // Send DCS commands through the APB generic interface to configure the
-    // display
-    /* OTM8009A power up sequence */
-    const uint8_t lcdRegData1[]  = {0x80, 0x09, 0x01, 0xFF};
-    const uint8_t lcdRegData2[]  = {0x80, 0x09, 0xFF};
-    const uint8_t lcdRegData3[]  = {0x00, 0x09, 0x0F, 0x0E, 0x07, 0x10,
-                                    0x0B, 0x0A, 0x04, 0x07, 0x0B, 0x08,
-                                    0x0F, 0x10, 0x0A, 0x01, 0xE1};
-    const uint8_t lcdRegData4[]  = {0x00, 0x09, 0x0F, 0x0E, 0x07, 0x10,
-                                    0x0B, 0x0A, 0x04, 0x07, 0x0B, 0x08,
-                                    0x0F, 0x10, 0x0A, 0x01, 0xE2};
-    const uint8_t lcdRegData5[]  = {0x79, 0x79, 0xD8};
-    const uint8_t lcdRegData6[]  = {0x00, 0x01, 0xB3};
-    const uint8_t lcdRegData7[]  = {0x85, 0x01, 0x00, 0x84, 0x01, 0x00, 0xCE};
-    const uint8_t lcdRegData8[]  = {0x18, 0x04, 0x03, 0x39, 0x00,
-                                    0x00, 0x00, 0x18, 0x03, 0x03,
-                                    0x3A, 0x00, 0x00, 0x00, 0xCE};
-    const uint8_t lcdRegData9[]  = {0x18, 0x02, 0x03, 0x3B, 0x00,
-                                    0x00, 0x00, 0x18, 0x01, 0x03,
-                                    0x3C, 0x00, 0x00, 0x00, 0xCE};
-    const uint8_t lcdRegData10[] = {0x01, 0x01, 0x20, 0x20, 0x00, 0x00,
-                                    0x01, 0x02, 0x00, 0x00, 0xCF};
-    const uint8_t lcdRegData11[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                    0x00, 0x00, 0x00, 0x00, 0xCB};
-    const uint8_t lcdRegData12[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                    0x00, 0x00, 0x00, 0xCB};
-    const uint8_t lcdRegData13[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                    0x00, 0x00, 0x00, 0xCB};
-    const uint8_t lcdRegData14[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                    0x00, 0x00, 0x00, 0x00, 0xCB};
-    const uint8_t lcdRegData15[] = {0x00, 0x04, 0x04, 0x04, 0x04, 0x04,
-                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                    0x00, 0x00, 0x00, 0xCB};
-    const uint8_t lcdRegData16[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                    0x04, 0x04, 0x04, 0x04, 0x04, 0x00,
-                                    0x00, 0x00, 0x00, 0xCB};
-    const uint8_t lcdRegData17[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                    0x00, 0x00, 0x00, 0x00, 0xCB};
-    const uint8_t lcdRegData18[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-                                    0xFF, 0xFF, 0xFF, 0xFF, 0xCB};
-    const uint8_t lcdRegData19[] = {0x00, 0x26, 0x09, 0x0B, 0x01, 0x25,
-                                    0x00, 0x00, 0x00, 0x00, 0xCC};
-    const uint8_t lcdRegData20[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x26,
-                                    0x0A, 0x0C, 0x02, 0xCC};
-    const uint8_t lcdRegData21[] = {0x25, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                    0x00, 0x00, 0x00, 0xCC};
-    const uint8_t lcdRegData22[] = {0x00, 0x25, 0x0C, 0x0A, 0x02, 0x26,
-                                    0x00, 0x00, 0x00, 0x00, 0xCC};
-    const uint8_t lcdRegData23[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x25,
-                                    0x0B, 0x09, 0x01, 0xCC};
-    const uint8_t lcdRegData24[] = {0x26, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                                    0x00, 0x00, 0x00, 0xCC};
-    const uint8_t lcdRegData25[] = {0xFF, 0xFF, 0xFF, 0xFF};
-
-    /*
-     * CASET value (Column Address Set): X direction LCD GRAM boundaries
-     * depending on LCD orientation mode PASET value (Page Address Set): Y
-     * direction LCD GRAM boundaries depending on LCD orientation mode
-     *
-     * XS[15:0] = 0x000 = 0, XE[15:0] = 0x31F = 799 for landscape mode: apply to
-     * CASET YS[15:0] = 0x000 = 0, YE[15:0] = 0x31F = 799 for portrait mode:
-     * apply to PASET
-     *
-     * XS[15:0] = 0x000 = 0, XE[15:0] = 0x1DF = 479 for portrait mode: apply to
-     * CASET YS[15:0] = 0x000 = 0, YE[15:0] = 0x1DF = 479 for landscape mode:
-     * apply to PASET
-     */
+        const unsigned int IDF = 4;    // must be in the range 1..7
+        const unsigned int ODF = 1;    // must be in the set {1, 2, 4, 8}
+        const unsigned int NDIV = 125; // must be in the range 10..125
+        const unsigned int F_VCO =
+            (HSE_VALUE / IDF) * 2 *
+            NDIV; // 500 MHz - must be between 500 and 1000 MHz
+        const unsigned int F_PHY_MHz =
+            (F_VCO / (2 * ODF)) /
+            1000000; // 250 MHz - HS clock for D-PHY must be between 80 and 500 MHz
+        const unsigned int lane_byte_clk =
+            F_VCO / (2 * ODF * 8); // 31,25 MHz - must be no more than 62,5 MHz
+        const unsigned int TXECLKDIV =
+            2;                                        // must be at least 2 and ensure lane_byte_clk/TXECLKDIV <= 20 MHz
+        const unsigned int pixel_clock = F_VCO / bpp; // 31,25 MHz
+        const unsigned int clock_ratio = lane_byte_clk / pixel_clock;
+
+        memset(framebuffer1, 0, height * width * bpp);
+
+        // Reset of screen by active low on GPIO PH7
+        typedef Gpio<GPIOH_BASE, 7> reset;
+        reset::mode(Mode::OUTPUT);
+        reset::speed(Speed::_100MHz);
+        reset::low();
+        Thread::sleep(20);
+        reset::high();
+        Thread::sleep(10);
+
+        // Enable clock for DSI and LTDC then force their reset
+        {
+            FastInterruptDisableLock dLock;
+
+            en::mode(Mode::ALTERNATE);
+            en::alternateFunction(14);
+            en::speed(Speed::_100MHz);
+            dotclk::mode(Mode::ALTERNATE);
+            dotclk::alternateFunction(14);
+            dotclk::speed(Speed::_100MHz);
+            vsync::mode(Mode::ALTERNATE);
+            vsync::alternateFunction(14);
+            vsync::speed(Speed::_100MHz);
+            hsync::mode(Mode::ALTERNATE);
+            hsync::alternateFunction(14);
+            hsync::speed(Speed::_100MHz);
+            r0::mode(Mode::ALTERNATE);
+            r0::alternateFunction(14);
+            r0::speed(Speed::_100MHz);
+            r1::mode(Mode::ALTERNATE);
+            r1::alternateFunction(14);
+            r1::speed(Speed::_100MHz);
+            r2::mode(Mode::ALTERNATE);
+            r2::alternateFunction(14);
+            r2::speed(Speed::_100MHz);
+            r3::mode(Mode::ALTERNATE);
+            r3::alternateFunction(14);
+            r3::speed(Speed::_100MHz);
+            r4::mode(Mode::ALTERNATE);
+            r4::alternateFunction(14);
+            r4::speed(Speed::_100MHz);
+            g0::mode(Mode::ALTERNATE);
+            g0::alternateFunction(14);
+            g0::speed(Speed::_100MHz);
+            g1::mode(Mode::ALTERNATE);
+            g1::alternateFunction(9);
+            g1::speed(Speed::_100MHz);
+            g2::mode(Mode::ALTERNATE);
+            g2::alternateFunction(9);
+            g2::speed(Speed::_100MHz);
+            g3::mode(Mode::ALTERNATE);
+            g3::alternateFunction(9);
+            g3::speed(Speed::_100MHz);
+            g4::mode(Mode::ALTERNATE);
+            g4::alternateFunction(14);
+            g4::speed(Speed::_100MHz);
+            g5::mode(Mode::ALTERNATE);
+            g5::alternateFunction(14);
+            g5::speed(Speed::_100MHz);
+            b0::mode(Mode::ALTERNATE);
+            b0::alternateFunction(14);
+            b0::speed(Speed::_100MHz);
+            b1::mode(Mode::ALTERNATE);
+            b1::alternateFunction(14);
+            b1::speed(Speed::_100MHz);
+            b2::mode(Mode::ALTERNATE);
+            b2::alternateFunction(9);
+            b2::speed(Speed::_100MHz);
+            b3::mode(Mode::ALTERNATE);
+            b3::alternateFunction(14);
+            b3::speed(Speed::_100MHz);
+            b4::mode(Mode::ALTERNATE);
+            b4::alternateFunction(14);
+            b4::speed(Speed::_100MHz);
+
+            RCC->APB2ENR |= RCC_APB2ENR_LTDCEN;
+            RCC_SYNC();
+            RCC->APB2ENR |= RCC_APB2ENR_DSIEN;
+            RCC_SYNC();
+
+            RCC->APB2RSTR |= RCC_APB2RSTR_LTDCRST;
+            RCC->APB2RSTR &= ~RCC_APB2RSTR_LTDCRST;
+
+            RCC->APB2RSTR |= RCC_APB2RSTR_DSIRST;
+            RCC->APB2RSTR &= ~RCC_APB2RSTR_DSIRST;
+        }
 
-    //     #if defined MXGUI_ORIENTATION_VERTICAL
-    //     const uint8_t lcdRegData27[] = {0x00, 0x00, 0x03, 0x1F, 0x2B};
-    //     const uint8_t lcdRegData28[] = {0x00, 0x00, 0x01, 0xDF, 0x2A};
-    //     #elif defined MXGUI_ORIENTATION_HORIZONTAL
-    //     const uint8_t lcdRegData27[] = {0x00, 0x00, 0x03, 0x1F, 0x2A};
-    //     const uint8_t lcdRegData28[] = {0x00, 0x00, 0x01, 0xDF, 0x2B};
-    //     #endif
-
-    const uint8_t ShortRegData1[]  = {0x00, 0x00};
-    const uint8_t ShortRegData2[]  = {0x00, 0x80};
-    const uint8_t ShortRegData3[]  = {0xC4, 0x30};
-    const uint8_t ShortRegData4[]  = {0x00, 0x8A};
-    const uint8_t ShortRegData5[]  = {0xC4, 0x40};
-    const uint8_t ShortRegData6[]  = {0x00, 0xB1};
-    const uint8_t ShortRegData7[]  = {0xC5, 0xA9};
-    const uint8_t ShortRegData8[]  = {0x00, 0x91};
-    const uint8_t ShortRegData9[]  = {0xC5, 0x34};
-    const uint8_t ShortRegData10[] = {0x00, 0xB4};
-    const uint8_t ShortRegData11[] = {0xC0, 0x50};
-    const uint8_t ShortRegData12[] = {0xD9, 0x4E};
-    const uint8_t ShortRegData13[] = {0x00, 0x81};
-    const uint8_t ShortRegData14[] = {0xC1, 0x66};
-    const uint8_t ShortRegData15[] = {0x00, 0xA1};
-    const uint8_t ShortRegData16[] = {0xC1, 0x08};
-    const uint8_t ShortRegData17[] = {0x00, 0x92};
-    const uint8_t ShortRegData18[] = {0xC5, 0x01};
-    const uint8_t ShortRegData19[] = {0x00, 0x95};
-    const uint8_t ShortRegData20[] = {0x00, 0x94};
-    const uint8_t ShortRegData21[] = {0xC5, 0x33};
-    const uint8_t ShortRegData22[] = {0x00, 0xA3};
-    const uint8_t ShortRegData23[] = {0xC0, 0x1B};
-    const uint8_t ShortRegData24[] = {0x00, 0x82};
-    const uint8_t ShortRegData25[] = {0xC5, 0x83};
-    const uint8_t ShortRegData26[] = {0xC4, 0x83};
-    const uint8_t ShortRegData27[] = {0xC1, 0x0E};
-    const uint8_t ShortRegData28[] = {0x00, 0xA6};
-    const uint8_t ShortRegData29[] = {0x00, 0xA0};
-    const uint8_t ShortRegData30[] = {0x00, 0xB0};
-    const uint8_t ShortRegData31[] = {0x00, 0xC0};
-    const uint8_t ShortRegData32[] = {0x00, 0xD0};
-    const uint8_t ShortRegData33[] = {0x00, 0x90};
-    const uint8_t ShortRegData34[] = {0x00, 0xE0};
-    const uint8_t ShortRegData35[] = {0x00, 0xF0};
-    const uint8_t ShortRegData36[] = {0x11, 0x00};
-    const uint8_t ShortRegData37[] = {0x3A, 0x55};
-    //     const uint8_t ShortRegData38[] = {0x3A, 0x77};
-
-    //     #if defined MXGUI_ORIENTATION_VERTICAL
-    //     const uint8_t ShortRegData39[] = {0x36, 0x00};
-    //     #elif defined MXGUI_ORIENTATION_HORIZONTAL
-    //     const uint8_t ShortRegData39[] = {0x36, 0x60};
-    //     #endif
-
-    const uint8_t ShortRegData40[] = {
-        0x51, 0xFF}; /* Draupner: Brightness changed from 0x7F */
-    const uint8_t ShortRegData41[] = {0x53, 0x2C};
-    const uint8_t ShortRegData42[] = {0x55, 0x02};
-    const uint8_t ShortRegData43[] = {0x5E, 0xFF};
-    const uint8_t ShortRegData44[] = {0x29, 0x00};
-    const uint8_t ShortRegData45[] = {0x2C, 0x00};
-    const uint8_t ShortRegData46[] = {0xCF, 0x00};
-    const uint8_t ShortRegData47[] = {0xC5, 0x66};
-    const uint8_t ShortRegData48[] = {0x00, 0xB6};
-    const uint8_t ShortRegData49[] = {0xF5, 0x06};
-
-    sendCmd(0, (uint8_t *)ShortRegData1);
-    sendCmd(3, (uint8_t *)lcdRegData1);
-    sendCmd(0, (uint8_t *)ShortRegData2);
-    sendCmd(2, (uint8_t *)lcdRegData2);
-    sendCmd(0, (uint8_t *)ShortRegData2);
-    sendCmd(0, (uint8_t *)ShortRegData3);
-    Thread::sleep(10);
-    sendCmd(0, (uint8_t *)ShortRegData4);
-    sendCmd(0, (uint8_t *)ShortRegData5);
-    Thread::sleep(10);
-    sendCmd(0, (uint8_t *)ShortRegData6);
-    sendCmd(0, (uint8_t *)ShortRegData7);
-    sendCmd(0, (uint8_t *)ShortRegData8);
-    sendCmd(0, (uint8_t *)ShortRegData9);
-    sendCmd(0, (uint8_t *)ShortRegData10);
-    sendCmd(0, (uint8_t *)ShortRegData11);
-    sendCmd(0, (uint8_t *)ShortRegData1);
-    sendCmd(0, (uint8_t *)ShortRegData12);
-    sendCmd(0, (uint8_t *)ShortRegData13);
-    sendCmd(0, (uint8_t *)ShortRegData14);
-    sendCmd(0, (uint8_t *)ShortRegData15);
-    sendCmd(0, (uint8_t *)ShortRegData16);
-    sendCmd(0, (uint8_t *)ShortRegData17);
-    sendCmd(0, (uint8_t *)ShortRegData18);
-    sendCmd(0, (uint8_t *)ShortRegData19);
-    sendCmd(0, (uint8_t *)ShortRegData9);
-    sendCmd(0, (uint8_t *)ShortRegData1);
-    sendCmd(2, (uint8_t *)lcdRegData5);
-    sendCmd(0, (uint8_t *)ShortRegData20);
-    sendCmd(0, (uint8_t *)ShortRegData21);
-    sendCmd(0, (uint8_t *)ShortRegData22);
-    sendCmd(0, (uint8_t *)ShortRegData23);
-    sendCmd(0, (uint8_t *)ShortRegData24);
-    sendCmd(0, (uint8_t *)ShortRegData25);
-    sendCmd(0, (uint8_t *)ShortRegData13);
-    sendCmd(0, (uint8_t *)ShortRegData26);
-    sendCmd(0, (uint8_t *)ShortRegData15);
-    sendCmd(0, (uint8_t *)ShortRegData27);
-    sendCmd(0, (uint8_t *)ShortRegData28);
-    sendCmd(2, (uint8_t *)lcdRegData6);
-    sendCmd(0, (uint8_t *)ShortRegData2);
-    sendCmd(6, (uint8_t *)lcdRegData7);
-    sendCmd(0, (uint8_t *)ShortRegData29);
-    sendCmd(14, (uint8_t *)lcdRegData8);
-    sendCmd(0, (uint8_t *)ShortRegData30);
-    sendCmd(14, (uint8_t *)lcdRegData9);
-    sendCmd(0, (uint8_t *)ShortRegData31);
-    sendCmd(10, (uint8_t *)lcdRegData10);
-    sendCmd(0, (uint8_t *)ShortRegData32);
-    sendCmd(0, (uint8_t *)ShortRegData46);
-    sendCmd(0, (uint8_t *)ShortRegData2);
-    sendCmd(10, (uint8_t *)lcdRegData11);
-    sendCmd(0, (uint8_t *)ShortRegData33);
-    sendCmd(15, (uint8_t *)lcdRegData12);
-    sendCmd(0, (uint8_t *)ShortRegData29);
-    sendCmd(15, (uint8_t *)lcdRegData13);
-    sendCmd(0, (uint8_t *)ShortRegData30);
-    sendCmd(10, (uint8_t *)lcdRegData14);
-    sendCmd(0, (uint8_t *)ShortRegData31);
-    sendCmd(15, (uint8_t *)lcdRegData15);
-    sendCmd(0, (uint8_t *)ShortRegData32);
-    sendCmd(15, (uint8_t *)lcdRegData16);
-    sendCmd(0, (uint8_t *)ShortRegData34);
-    sendCmd(10, (uint8_t *)lcdRegData17);
-    sendCmd(0, (uint8_t *)ShortRegData35);
-    sendCmd(10, (uint8_t *)lcdRegData18);
-    sendCmd(0, (uint8_t *)ShortRegData2);
-    sendCmd(10, (uint8_t *)lcdRegData19);
-    sendCmd(0, (uint8_t *)ShortRegData33);
-    sendCmd(15, (uint8_t *)lcdRegData20);
-    sendCmd(0, (uint8_t *)ShortRegData29);
-    sendCmd(15, (uint8_t *)lcdRegData21);
-    sendCmd(0, (uint8_t *)ShortRegData30);
-    sendCmd(10, (uint8_t *)lcdRegData22);
-    sendCmd(0, (uint8_t *)ShortRegData31);
-    sendCmd(15, (uint8_t *)lcdRegData23);
-    sendCmd(0, (uint8_t *)ShortRegData32);
-    sendCmd(15, (uint8_t *)lcdRegData24);
-    sendCmd(0, (uint8_t *)ShortRegData13);
-    sendCmd(0, (uint8_t *)ShortRegData47);
-    sendCmd(0, (uint8_t *)ShortRegData48);
-    sendCmd(0, (uint8_t *)ShortRegData49);
-    sendCmd(0, (uint8_t *)ShortRegData1);
-    sendCmd(3, (uint8_t *)lcdRegData25);
-    sendCmd(0, (uint8_t *)ShortRegData1);
-    sendCmd(0, (uint8_t *)ShortRegData1);
-    sendCmd(16, (uint8_t *)lcdRegData3);
-    sendCmd(0, (uint8_t *)ShortRegData1);
-    sendCmd(16, (uint8_t *)lcdRegData4);
-    sendCmd(0, (uint8_t *)ShortRegData36);
-    Thread::sleep(120);
-
-    /* Set Pixel color format to RGB565 */
-    sendCmd(0, (uint8_t *)ShortRegData37);
-    /* Set Pixel color format to RGB888 */
-    // sendCmd(0, (uint8_t *)ShortRegData38);
+        // Configure PLLSAI for LTDC, turn it ON and wait for its lock
+        {
+            FastInterruptDisableLock dLock;
+
+            // LTDC clock depends on PLL_M which is fixed at boot with value 8
+            // It also depends on PLLSAI which can be freely configured
+            const unsigned int PLLSAI_N = 384;
+            const unsigned int PLLSAI_R = 7;
+            // const unsigned int PLLSAI_DIVR = 0;
+
+            // Input VCO Frequency = HSE_VALUE/PPL_M must be between 1 and 2 MHz, so
+            // 8/8 = 1 MHz N must be in the range 50..432 and ensure a frequency
+            // between 100 and 432 MHz if N = 384 then 1 MHz * 384 = 384 MHz R must
+            // be in the range 2..7, we choose R = 7 so 384/7 = 54,857 MHz and then
+            // we divide it by 2 (setting DIVR to 0) to obtain 27,428 Mhz
+
+            // Read PLLSAI_P and PLLSAI_Q values from PLLSAICFGR register
+            uint32_t PLLSAI_P = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> 16);
+            uint32_t PLLSAI_Q = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24);
+            // PLLSAI_VCO_Input  = PLL_SOURCE/PLL_M
+            // PLLSAI_VCO_Output = PLLSAI_VCO_Input * PLLSAI_N
+            // LTDC_CLK(first level) = PLLSAI_VCO_Output/PLLSAI_R
+            RCC->PLLSAICFGR = (PLLSAI_N << 6) | (PLLSAI_P << 16) |
+                              (PLLSAI_Q << 24) | (PLLSAI_R << 28);
+            // LTDC_CLK = LTDC_CLK(first level)/PLLSAI_DIVR
+            RCC->DCKCFGR = RCC->DCKCFGR & ~RCC_DCKCFGR_PLLSAIDIVR;
+
+            RCC->CR |= RCC_CR_PLLSAION;
+        }
+        while ((RCC->CR & RCC_CR_PLLSAIRDY) == 0)
+            ;
+
+        /* Start LTDC configuration */
+        // Configure timings
+        LTDC->SSCR = (hsync - 1) << 16 | (vsync - 1);
+        LTDC->BPCR = (hsync + hbp - 1) << 16 | (vsync + vbp - 1);
+        LTDC->AWCR = (hsync + hbp + width - 1) << 16 | (vsync + vbp + height - 1);
+        LTDC->TWCR = (hsync + hbp + width + hfp - 1) << 16 |
+                     (vsync + vbp + height + vfp - 1);
+
+        // Configure polarities (everything active high except data enabled)
+        LTDC->GCR |=
+            (LTDC_GCR_HSPOL | LTDC_GCR_VSPOL | LTDC_GCR_DEPOL | LTDC_GCR_PCPOL);
+        LTDC->GCR &= ~LTDC_GCR_DEPOL;
+
+        // Configure background color
+        LTDC->BCCR = 0;
+
+        // Configure the layer
+        // Horizontal start and stop position
+        LTDC_Layer1->WHPCR &= ~(LTDC_LxWHPCR_WHSTPOS | LTDC_LxWHPCR_WHSPPOS);
+        LTDC_Layer1->WHPCR = ((hsync + hbp + width - 1) << 16) | (hsync + hbp);
+        // Vertical start and stop position
+        LTDC_Layer1->WVPCR &= ~(LTDC_LxWVPCR_WVSTPOS | LTDC_LxWVPCR_WVSPPOS);
+        LTDC_Layer1->WVPCR = ((vsync + vbp + height - 1) << 16) | (vsync + vbp);
+        // Pixel format
+        LTDC_Layer1->PFCR &= ~(LTDC_LxPFCR_PF);
+        LTDC_Layer1->PFCR |= RGB565;
+        // Color frame buffer start address
+        LTDC_Layer1->CFBAR &= ~(LTDC_LxCFBAR_CFBADD);
+        LTDC_Layer1->CFBAR = reinterpret_cast<unsigned int>(framebuffer1);
+        // Color frame buffer pitch in byte (multiply by 2 for RGB565)
+        LTDC_Layer1->CFBLR &= ~(LTDC_LxCFBLR_CFBP | LTDC_LxCFBLR_CFBLL);
+        LTDC_Layer1->CFBLR = (width * 2) << 16 | (width * 2 + 3);
+        // Frame buffer line number
+        LTDC_Layer1->CFBLNR &= ~(LTDC_LxCFBLNR_CFBLNBR);
+        LTDC_Layer1->CFBLNR = height;
+        // Default color values (black with no alpha)
+        LTDC_Layer1->DCCR &= ~(LTDC_LxDCCR_DCBLUE | LTDC_LxDCCR_DCGREEN |
+                               LTDC_LxDCCR_DCRED | LTDC_LxDCCR_DCALPHA);
+        LTDC_Layer1->DCCR = 0;
+        // Specifies the constant alpha value
+        LTDC_Layer1->CACR &= ~(LTDC_LxCACR_CONSTA);
+        LTDC_Layer1->CACR = 255;
+        // Blending factors (constant alpha)
+        LTDC_Layer1->BFCR &= ~(LTDC_LxBFCR_BF2 | LTDC_LxBFCR_BF1);
+        LTDC_Layer1->BFCR = (0x400 | 0x5);
+        // Enable layer
+        LTDC_Layer1->CR |= LTDC_LxCR_LEN;
+
+        // If needed enable dithering and color keying
+        LTDC_Layer1->CKCR = 0;
+
+        // Reload shadow registers
+        LTDC->SRCR |= LTDC_SRCR_IMR;
+
+        // Finally enable the display
+        LTDC->GCR |= LTDC_GCR_LTDCEN;
+        /* End LTDC configuration */
+
+        /* Start DSI configuration */
+        // Turn on the DSI regulator and wait for the regulator ready
+        DSI->WRPCR |= DSI_WRPCR_REGEN;
+        while ((DSI->WISR & DSI_WISR_RRS) == 0)
+            ;
+
+        // Configure the DSI PLL, turn it ON and wait for its lock
+        // F_VCO = (HSE_VALUE / IDF) * 2 * NDIV
+        // Lane_Byte_CLK = F_VCO / (2 * ODF * 8)
+        // F_VCO must be in the range from 500 MHz to 1 GHz
+        // To obtain 500 Mbit/s rate, Lane_Byte_CLK must be 31,25 MHz
+        // Since HSE_VALUE = 8 MHz this is possible with NDIV = 125, IDF = 4, ODF =
+        // 1
+        DSI->WRPCR &= ~(DSI_WRPCR_PLL_NDIV | DSI_WRPCR_PLL_IDF | DSI_WRPCR_PLL_ODF);
+        DSI->WRPCR |= ((NDIV << 2) | (IDF << 11) | (ODF << 16));
+        DSI->WRPCR |= DSI_WRPCR_PLLEN;
+        while ((DSI->WISR & DSI_WISR_PLLLS) == 0)
+            ;
+
+        // Configure the D-PHY parameters
+        // Calculate the bit period in high-speed mode in unit of 0.25 ns (UIX4)
+        // The equation is: UIX4 = IntegerPart( (1000/F_PHY_MHz) * 4 )
+        // Where: F_PHY_MHz = (NDIV * HSE_MHz) / (IDF * ODF)
+        DSI->WPCR[0] &= ~DSI_WPCR0_UIX4;
+        DSI->WPCR[0] |= (1000 / F_PHY_MHz) * 4;
+        // Disable all error interrupts and reset the Error Mask
+        DSI->IER[0] = 0;
+        DSI->IER[1] = 0;
+        // Configure the number of active data lanes (just one out of two for 16
+        // bpp)
+        DSI->PCONFR &= ~DSI_PCONFR_NL;
+        DSI->PCONFR |= 1;
+        // Set automatic clock lane control
+        DSI->CLCR |= (DSI_CLCR_DPCC | DSI_CLCR_ACR);
+        // Time for LP/HS and HS/LP transitions for both clock lane and data lanes
+        DSI->CLTCR |= (40 << 16)    // HS to LP
+                      | (40 << 0);  // LP to HS
+        DSI->DLTCR |= (20 << 24)    // HS to LP
+                      | (20 << 16); // HS to LP
+        // Stop wait time (don't know how much should it be, random high number in 8
+        // bit)
+        DSI->PCONFR &= ~DSI_PCONFR_SW_TIME;
+        DSI->PCONFR |= (100 << 8);
+
+        // Configure the DSI Host timing
+        // DSI->CCR |= (... << 8); // timeout clock configuration non dice nulla...
+        // Configure clock speed for low-power mode
+        DSI->CCR &= ~DSI_CCR_TXECKDIV;
+        DSI->CCR |= TXECLKDIV;
+
+        // Configure the DSI Host flow control and DBI interface
+        DSI->PCR &= ~(DSI_PCR_CRCRXE | DSI_PCR_ECCRXE | DSI_PCR_BTAE |
+                      DSI_PCR_ETRXE | DSI_PCR_ETTXE);
+        DSI->GVCIDR &=
+            ~DSI_GVCIDR_VCID; // set Virtual Channel ID = 0 for the display
+
+        // Configure the DSI Host LTDC interface
+        DSI->LVCIDR &= ~3; // Virtual channel ID for LTDC interface traffic
+        DSI->LCOLCR &= ~DSI_LCOLCR_COLC;
+        DSI->LCOLCR |= RGB565; // Color coding for the host
+        DSI->WCFGR &= ~DSI_WCFGR_COLMUX;
+        DSI->WCFGR |= RGB565 << 1; // Color coding for the wrapper
+        DSI->LPCR &= ~(DSI_LPCR_DEP | DSI_LPCR_VSP | DSI_LPCR_HSP);
+        DSI->LPCR |=
+            (DSI_LPCR_DEP | 0 |
+             0);                       // Polarity of control signals: same of LTDC except for DE
+        DSI->WCFGR |= DSI_WCFGR_VSPOL; // LTDC halts at VSYNC rising edge
+
+        // Configure the DSI Host for command mode
+        // Select command mode by setting CMDM and DSIM bits
+        DSI->MCR |= DSI_MCR_CMDM;
+        DSI->WCFGR |= DSI_WCFGR_DSIM;
+        // Configure the maximum allowed size for write memory command
+        DSI->LCCR &= ~DSI_LCCR_CMDSIZE;
+        DSI->LCCR |= width;
+
+        DSI->VMCR |= 0x3f << 8;        // LP allowed in all video periods
+        DSI->VMCR &= ~DSI_VMCR_FBTAAE; // Do not request acknowledge at end of
+                                       // frame (at this time)
+        DSI->VMCR |= DSI_VMCR_LPCE;    // Allow commands in LP
+        DSI->VPCR |= width;            // Video packet size
+        DSI->VCCR = 0;                 // Chunks number to be transmitted through the DSI link
+        DSI->VNPCR |= 0xFFF;           // Size of the null packet
+        // Timings in lane byte clock cycles
+        DSI->VLCR |= (hsync + hbp + width + hfp) * clock_ratio;
+        DSI->VHSACR |= hsync * clock_ratio;
+        DSI->VHBPCR |= hbp * clock_ratio;
+        DSI->VVSACR |= vsync;
+        DSI->VVBPCR |= vbp;
+        DSI->VVFPCR |= vfp;
+        DSI->VVACR |= height;
+        DSI->LPMCR |= (64 << 16); // Low power largest packet size
+        DSI->LPMCR |= 64;         // Low power VACT largest packet size
+        // Command trasmission only in low power mode
+        DSI->CMCR |=
+            (DSI_CMCR_GSW0TX | DSI_CMCR_GSW1TX | DSI_CMCR_GSW2TX | DSI_CMCR_GSR0TX |
+             DSI_CMCR_GSR1TX | DSI_CMCR_GSR2TX | DSI_CMCR_GLWTX | DSI_CMCR_DSW0TX |
+             DSI_CMCR_DSW1TX | DSI_CMCR_DSR0TX | DSI_CMCR_DLWTX | DSI_CMCR_MRDPS);
+
+        // Configure the acknowledge request after each packet transmission
+        DSI->CMCR |= DSI_CMCR_ARE;
+
+        // Enable the D-PHY data lane
+        DSI->PCTLR |= DSI_PCTLR_DEN;
+
+        // Enable the D-PHY clock lane
+        DSI->PCTLR |= DSI_PCTLR_CKE;
+
+        // Enable the DSI Host
+        DSI->CR |= DSI_CR_EN;
+
+        // Enable the DSI wrapper
+        DSI->WCR |= DSI_WCR_DSIEN;
+        /* End DSI configuration */
+
+        // Send DCS commands through the APB generic interface to configure the
+        // display
+        /* OTM8009A power up sequence */
+        const uint8_t lcdRegData1[] = {0x80, 0x09, 0x01, 0xFF};
+        const uint8_t lcdRegData2[] = {0x80, 0x09, 0xFF};
+        const uint8_t lcdRegData3[] = {0x00, 0x09, 0x0F, 0x0E, 0x07, 0x10,
+                                       0x0B, 0x0A, 0x04, 0x07, 0x0B, 0x08,
+                                       0x0F, 0x10, 0x0A, 0x01, 0xE1};
+        const uint8_t lcdRegData4[] = {0x00, 0x09, 0x0F, 0x0E, 0x07, 0x10,
+                                       0x0B, 0x0A, 0x04, 0x07, 0x0B, 0x08,
+                                       0x0F, 0x10, 0x0A, 0x01, 0xE2};
+        const uint8_t lcdRegData5[] = {0x79, 0x79, 0xD8};
+        const uint8_t lcdRegData6[] = {0x00, 0x01, 0xB3};
+        const uint8_t lcdRegData7[] = {0x85, 0x01, 0x00, 0x84, 0x01, 0x00, 0xCE};
+        const uint8_t lcdRegData8[] = {0x18, 0x04, 0x03, 0x39, 0x00,
+                                       0x00, 0x00, 0x18, 0x03, 0x03,
+                                       0x3A, 0x00, 0x00, 0x00, 0xCE};
+        const uint8_t lcdRegData9[] = {0x18, 0x02, 0x03, 0x3B, 0x00,
+                                       0x00, 0x00, 0x18, 0x01, 0x03,
+                                       0x3C, 0x00, 0x00, 0x00, 0xCE};
+        const uint8_t lcdRegData10[] = {0x01, 0x01, 0x20, 0x20, 0x00, 0x00,
+                                        0x01, 0x02, 0x00, 0x00, 0xCF};
+        const uint8_t lcdRegData11[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                        0x00, 0x00, 0x00, 0x00, 0xCB};
+        const uint8_t lcdRegData12[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                        0x00, 0x00, 0x00, 0xCB};
+        const uint8_t lcdRegData13[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                        0x00, 0x00, 0x00, 0xCB};
+        const uint8_t lcdRegData14[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                        0x00, 0x00, 0x00, 0x00, 0xCB};
+        const uint8_t lcdRegData15[] = {0x00, 0x04, 0x04, 0x04, 0x04, 0x04,
+                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                        0x00, 0x00, 0x00, 0xCB};
+        const uint8_t lcdRegData16[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                        0x04, 0x04, 0x04, 0x04, 0x04, 0x00,
+                                        0x00, 0x00, 0x00, 0xCB};
+        const uint8_t lcdRegData17[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                        0x00, 0x00, 0x00, 0x00, 0xCB};
+        const uint8_t lcdRegData18[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+                                        0xFF, 0xFF, 0xFF, 0xFF, 0xCB};
+        const uint8_t lcdRegData19[] = {0x00, 0x26, 0x09, 0x0B, 0x01, 0x25,
+                                        0x00, 0x00, 0x00, 0x00, 0xCC};
+        const uint8_t lcdRegData20[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x26,
+                                        0x0A, 0x0C, 0x02, 0xCC};
+        const uint8_t lcdRegData21[] = {0x25, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                        0x00, 0x00, 0x00, 0xCC};
+        const uint8_t lcdRegData22[] = {0x00, 0x25, 0x0C, 0x0A, 0x02, 0x26,
+                                        0x00, 0x00, 0x00, 0x00, 0xCC};
+        const uint8_t lcdRegData23[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x25,
+                                        0x0B, 0x09, 0x01, 0xCC};
+        const uint8_t lcdRegData24[] = {0x26, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                                        0x00, 0x00, 0x00, 0xCC};
+        const uint8_t lcdRegData25[] = {0xFF, 0xFF, 0xFF, 0xFF};
+
+        /*
+         * CASET value (Column Address Set): X direction LCD GRAM boundaries
+         * depending on LCD orientation mode PASET value (Page Address Set): Y
+         * direction LCD GRAM boundaries depending on LCD orientation mode
+         *
+         * XS[15:0] = 0x000 = 0, XE[15:0] = 0x31F = 799 for landscape mode: apply to
+         * CASET YS[15:0] = 0x000 = 0, YE[15:0] = 0x31F = 799 for portrait mode:
+         * apply to PASET
+         *
+         * XS[15:0] = 0x000 = 0, XE[15:0] = 0x1DF = 479 for portrait mode: apply to
+         * CASET YS[15:0] = 0x000 = 0, YE[15:0] = 0x1DF = 479 for landscape mode:
+         * apply to PASET
+         */
+
+        //     #if defined MXGUI_ORIENTATION_VERTICAL
+        //     const uint8_t lcdRegData27[] = {0x00, 0x00, 0x03, 0x1F, 0x2B};
+        //     const uint8_t lcdRegData28[] = {0x00, 0x00, 0x01, 0xDF, 0x2A};
+        //     #elif defined MXGUI_ORIENTATION_HORIZONTAL
+        //     const uint8_t lcdRegData27[] = {0x00, 0x00, 0x03, 0x1F, 0x2A};
+        //     const uint8_t lcdRegData28[] = {0x00, 0x00, 0x01, 0xDF, 0x2B};
+        //     #endif
+
+        const uint8_t ShortRegData1[] = {0x00, 0x00};
+        const uint8_t ShortRegData2[] = {0x00, 0x80};
+        const uint8_t ShortRegData3[] = {0xC4, 0x30};
+        const uint8_t ShortRegData4[] = {0x00, 0x8A};
+        const uint8_t ShortRegData5[] = {0xC4, 0x40};
+        const uint8_t ShortRegData6[] = {0x00, 0xB1};
+        const uint8_t ShortRegData7[] = {0xC5, 0xA9};
+        const uint8_t ShortRegData8[] = {0x00, 0x91};
+        const uint8_t ShortRegData9[] = {0xC5, 0x34};
+        const uint8_t ShortRegData10[] = {0x00, 0xB4};
+        const uint8_t ShortRegData11[] = {0xC0, 0x50};
+        const uint8_t ShortRegData12[] = {0xD9, 0x4E};
+        const uint8_t ShortRegData13[] = {0x00, 0x81};
+        const uint8_t ShortRegData14[] = {0xC1, 0x66};
+        const uint8_t ShortRegData15[] = {0x00, 0xA1};
+        const uint8_t ShortRegData16[] = {0xC1, 0x08};
+        const uint8_t ShortRegData17[] = {0x00, 0x92};
+        const uint8_t ShortRegData18[] = {0xC5, 0x01};
+        const uint8_t ShortRegData19[] = {0x00, 0x95};
+        const uint8_t ShortRegData20[] = {0x00, 0x94};
+        const uint8_t ShortRegData21[] = {0xC5, 0x33};
+        const uint8_t ShortRegData22[] = {0x00, 0xA3};
+        const uint8_t ShortRegData23[] = {0xC0, 0x1B};
+        const uint8_t ShortRegData24[] = {0x00, 0x82};
+        const uint8_t ShortRegData25[] = {0xC5, 0x83};
+        const uint8_t ShortRegData26[] = {0xC4, 0x83};
+        const uint8_t ShortRegData27[] = {0xC1, 0x0E};
+        const uint8_t ShortRegData28[] = {0x00, 0xA6};
+        const uint8_t ShortRegData29[] = {0x00, 0xA0};
+        const uint8_t ShortRegData30[] = {0x00, 0xB0};
+        const uint8_t ShortRegData31[] = {0x00, 0xC0};
+        const uint8_t ShortRegData32[] = {0x00, 0xD0};
+        const uint8_t ShortRegData33[] = {0x00, 0x90};
+        const uint8_t ShortRegData34[] = {0x00, 0xE0};
+        const uint8_t ShortRegData35[] = {0x00, 0xF0};
+        const uint8_t ShortRegData36[] = {0x11, 0x00};
+        const uint8_t ShortRegData37[] = {0x3A, 0x55};
+        //     const uint8_t ShortRegData38[] = {0x3A, 0x77};
+
+        //     #if defined MXGUI_ORIENTATION_VERTICAL
+        //     const uint8_t ShortRegData39[] = {0x36, 0x00};
+        //     #elif defined MXGUI_ORIENTATION_HORIZONTAL
+        //     const uint8_t ShortRegData39[] = {0x36, 0x60};
+        //     #endif
+
+        const uint8_t ShortRegData40[] = {
+            0x51, 0xFF}; /* Draupner: Brightness changed from 0x7F */
+        const uint8_t ShortRegData41[] = {0x53, 0x2C};
+        const uint8_t ShortRegData42[] = {0x55, 0x02};
+        const uint8_t ShortRegData43[] = {0x5E, 0xFF};
+        const uint8_t ShortRegData44[] = {0x29, 0x00};
+        const uint8_t ShortRegData45[] = {0x2C, 0x00};
+        const uint8_t ShortRegData46[] = {0xCF, 0x00};
+        const uint8_t ShortRegData47[] = {0xC5, 0x66};
+        const uint8_t ShortRegData48[] = {0x00, 0xB6};
+        const uint8_t ShortRegData49[] = {0xF5, 0x06};
+
+        sendCmd(0, (uint8_t *)ShortRegData1);
+        sendCmd(3, (uint8_t *)lcdRegData1);
+        sendCmd(0, (uint8_t *)ShortRegData2);
+        sendCmd(2, (uint8_t *)lcdRegData2);
+        sendCmd(0, (uint8_t *)ShortRegData2);
+        sendCmd(0, (uint8_t *)ShortRegData3);
+        Thread::sleep(10);
+        sendCmd(0, (uint8_t *)ShortRegData4);
+        sendCmd(0, (uint8_t *)ShortRegData5);
+        Thread::sleep(10);
+        sendCmd(0, (uint8_t *)ShortRegData6);
+        sendCmd(0, (uint8_t *)ShortRegData7);
+        sendCmd(0, (uint8_t *)ShortRegData8);
+        sendCmd(0, (uint8_t *)ShortRegData9);
+        sendCmd(0, (uint8_t *)ShortRegData10);
+        sendCmd(0, (uint8_t *)ShortRegData11);
+        sendCmd(0, (uint8_t *)ShortRegData1);
+        sendCmd(0, (uint8_t *)ShortRegData12);
+        sendCmd(0, (uint8_t *)ShortRegData13);
+        sendCmd(0, (uint8_t *)ShortRegData14);
+        sendCmd(0, (uint8_t *)ShortRegData15);
+        sendCmd(0, (uint8_t *)ShortRegData16);
+        sendCmd(0, (uint8_t *)ShortRegData17);
+        sendCmd(0, (uint8_t *)ShortRegData18);
+        sendCmd(0, (uint8_t *)ShortRegData19);
+        sendCmd(0, (uint8_t *)ShortRegData9);
+        sendCmd(0, (uint8_t *)ShortRegData1);
+        sendCmd(2, (uint8_t *)lcdRegData5);
+        sendCmd(0, (uint8_t *)ShortRegData20);
+        sendCmd(0, (uint8_t *)ShortRegData21);
+        sendCmd(0, (uint8_t *)ShortRegData22);
+        sendCmd(0, (uint8_t *)ShortRegData23);
+        sendCmd(0, (uint8_t *)ShortRegData24);
+        sendCmd(0, (uint8_t *)ShortRegData25);
+        sendCmd(0, (uint8_t *)ShortRegData13);
+        sendCmd(0, (uint8_t *)ShortRegData26);
+        sendCmd(0, (uint8_t *)ShortRegData15);
+        sendCmd(0, (uint8_t *)ShortRegData27);
+        sendCmd(0, (uint8_t *)ShortRegData28);
+        sendCmd(2, (uint8_t *)lcdRegData6);
+        sendCmd(0, (uint8_t *)ShortRegData2);
+        sendCmd(6, (uint8_t *)lcdRegData7);
+        sendCmd(0, (uint8_t *)ShortRegData29);
+        sendCmd(14, (uint8_t *)lcdRegData8);
+        sendCmd(0, (uint8_t *)ShortRegData30);
+        sendCmd(14, (uint8_t *)lcdRegData9);
+        sendCmd(0, (uint8_t *)ShortRegData31);
+        sendCmd(10, (uint8_t *)lcdRegData10);
+        sendCmd(0, (uint8_t *)ShortRegData32);
+        sendCmd(0, (uint8_t *)ShortRegData46);
+        sendCmd(0, (uint8_t *)ShortRegData2);
+        sendCmd(10, (uint8_t *)lcdRegData11);
+        sendCmd(0, (uint8_t *)ShortRegData33);
+        sendCmd(15, (uint8_t *)lcdRegData12);
+        sendCmd(0, (uint8_t *)ShortRegData29);
+        sendCmd(15, (uint8_t *)lcdRegData13);
+        sendCmd(0, (uint8_t *)ShortRegData30);
+        sendCmd(10, (uint8_t *)lcdRegData14);
+        sendCmd(0, (uint8_t *)ShortRegData31);
+        sendCmd(15, (uint8_t *)lcdRegData15);
+        sendCmd(0, (uint8_t *)ShortRegData32);
+        sendCmd(15, (uint8_t *)lcdRegData16);
+        sendCmd(0, (uint8_t *)ShortRegData34);
+        sendCmd(10, (uint8_t *)lcdRegData17);
+        sendCmd(0, (uint8_t *)ShortRegData35);
+        sendCmd(10, (uint8_t *)lcdRegData18);
+        sendCmd(0, (uint8_t *)ShortRegData2);
+        sendCmd(10, (uint8_t *)lcdRegData19);
+        sendCmd(0, (uint8_t *)ShortRegData33);
+        sendCmd(15, (uint8_t *)lcdRegData20);
+        sendCmd(0, (uint8_t *)ShortRegData29);
+        sendCmd(15, (uint8_t *)lcdRegData21);
+        sendCmd(0, (uint8_t *)ShortRegData30);
+        sendCmd(10, (uint8_t *)lcdRegData22);
+        sendCmd(0, (uint8_t *)ShortRegData31);
+        sendCmd(15, (uint8_t *)lcdRegData23);
+        sendCmd(0, (uint8_t *)ShortRegData32);
+        sendCmd(15, (uint8_t *)lcdRegData24);
+        sendCmd(0, (uint8_t *)ShortRegData13);
+        sendCmd(0, (uint8_t *)ShortRegData47);
+        sendCmd(0, (uint8_t *)ShortRegData48);
+        sendCmd(0, (uint8_t *)ShortRegData49);
+        sendCmd(0, (uint8_t *)ShortRegData1);
+        sendCmd(3, (uint8_t *)lcdRegData25);
+        sendCmd(0, (uint8_t *)ShortRegData1);
+        sendCmd(0, (uint8_t *)ShortRegData1);
+        sendCmd(16, (uint8_t *)lcdRegData3);
+        sendCmd(0, (uint8_t *)ShortRegData1);
+        sendCmd(16, (uint8_t *)lcdRegData4);
+        sendCmd(0, (uint8_t *)ShortRegData36);
+        Thread::sleep(120);
+
+        /* Set Pixel color format to RGB565 */
+        sendCmd(0, (uint8_t *)ShortRegData37);
+        /* Set Pixel color format to RGB888 */
+        // sendCmd(0, (uint8_t *)ShortRegData38);
 
 #if defined MXGUI_ORIENTATION_HORIZONTAL
-    /* Send command to configure display in landscape orientation mode.
-       By default the orientation mode is portrait. */
-    sendCmd(0, (uint8_t *)ShortRegData39);
-    sendCmd(4, (uint8_t *)lcdRegData27);
-    sendCmd(4, (uint8_t *)lcdRegData28);
+        /* Send command to configure display in landscape orientation mode.
+           By default the orientation mode is portrait. */
+        sendCmd(0, (uint8_t *)ShortRegData39);
+        sendCmd(4, (uint8_t *)lcdRegData27);
+        sendCmd(4, (uint8_t *)lcdRegData28);
 #endif
 
-    sendCmd(0, (uint8_t *)ShortRegData40);
-    sendCmd(0, (uint8_t *)ShortRegData41);
-    sendCmd(0, (uint8_t *)ShortRegData42);
-    sendCmd(0, (uint8_t *)ShortRegData43);
-    sendCmd(0, (uint8_t *)ShortRegData44);
-    sendCmd(0, (uint8_t *)ShortRegData1);
-    sendCmd(0, (uint8_t *)ShortRegData45);
-    /* End OTM8009A power up sequence */
-
-    // Disable command trasmission only in low power mode
-    DSI->CMCR &= ~(DSI_CMCR_GSW0TX | DSI_CMCR_GSW1TX | DSI_CMCR_GSW2TX |
-                   DSI_CMCR_GSR0TX | DSI_CMCR_GSR1TX | DSI_CMCR_GSR2TX |
-                   DSI_CMCR_GLWTX | DSI_CMCR_DSW0TX | DSI_CMCR_DSW1TX |
-                   DSI_CMCR_DSR0TX | DSI_CMCR_DLWTX | DSI_CMCR_MRDPS);
-
-    DSI->PCR &= ~(DSI_PCR_CRCRXE | DSI_PCR_ECCRXE | DSI_PCR_BTAE |
-                  DSI_PCR_ETRXE | DSI_PCR_ETTXE);
-    DSI->PCR |= DSI_PCR_BTAE;
-
-    // Enable the LTDC
-    LTDC->GCR |= LTDC_GCR_LTDCEN;
-
-    // Start the LTDC flow through the DSI wrapper (CR.LTDCEN = 1).
-    // In video mode, the data streaming starts as soon as the LTDC is enabled.
-    // In adapted command mode, the frame buffer update is launched as soon as
-    // the CR.LTDCEN bit is set.
-    DSI->CR |= DSI_CR_EN;
-
-    // Update the display
-    DSI->WCR |= DSI_WCR_LTDCEN;
-
-    setFont(droid11);
-    setTextColor(make_pair(Color(0xffff), Color(0x0000)));
-    clear(black);
-}
+        sendCmd(0, (uint8_t *)ShortRegData40);
+        sendCmd(0, (uint8_t *)ShortRegData41);
+        sendCmd(0, (uint8_t *)ShortRegData42);
+        sendCmd(0, (uint8_t *)ShortRegData43);
+        sendCmd(0, (uint8_t *)ShortRegData44);
+        sendCmd(0, (uint8_t *)ShortRegData1);
+        sendCmd(0, (uint8_t *)ShortRegData45);
+        /* End OTM8009A power up sequence */
+
+        // Disable command trasmission only in low power mode
+        DSI->CMCR &= ~(DSI_CMCR_GSW0TX | DSI_CMCR_GSW1TX | DSI_CMCR_GSW2TX |
+                       DSI_CMCR_GSR0TX | DSI_CMCR_GSR1TX | DSI_CMCR_GSR2TX |
+                       DSI_CMCR_GLWTX | DSI_CMCR_DSW0TX | DSI_CMCR_DSW1TX |
+                       DSI_CMCR_DSR0TX | DSI_CMCR_DLWTX | DSI_CMCR_MRDPS);
+
+        DSI->PCR &= ~(DSI_PCR_CRCRXE | DSI_PCR_ECCRXE | DSI_PCR_BTAE |
+                      DSI_PCR_ETRXE | DSI_PCR_ETTXE);
+        DSI->PCR |= DSI_PCR_BTAE;
+
+        // Enable the LTDC
+        LTDC->GCR |= LTDC_GCR_LTDCEN;
+
+        // Start the LTDC flow through the DSI wrapper (CR.LTDCEN = 1).
+        // In video mode, the data streaming starts as soon as the LTDC is enabled.
+        // In adapted command mode, the frame buffer update is launched as soon as
+        // the CR.LTDCEN bit is set.
+        DSI->CR |= DSI_CR_EN;
+
+        // Update the display
+        DSI->WCR |= DSI_WCR_LTDCEN;
+
+        setFont(droid11);
+        setTextColor(make_pair(Color(0xffff), Color(0x0000)));
+        clear(black);
+    }
 
-Color DisplayImpl::pixel_iterator::dummy;
+    Color DisplayImpl::pixel_iterator::dummy;
 
-}  // namespace mxgui
+} // namespace mxgui
 
-#endif  //_BOARD_STM32F469NI_STM32F469I_DISCO
+#endif //_BOARD_STM32F469NI_STM32F469I_DISCO
diff --git a/mxgui/drivers/display_stm32f4discovery.h b/mxgui/drivers/display_stm32f4discovery.h
index cecc4fe52879ae3c3b9de67f817d43451ea88f65..8a722ded7442d410cf3a89d1aeac02f8afb5243f 100644
--- a/mxgui/drivers/display_stm32f4discovery.h
+++ b/mxgui/drivers/display_stm32f4discovery.h
@@ -28,7 +28,7 @@
 #ifndef MXGUI_LIBRARY
 #error "This is header is private, it can be used only within mxgui."
 #error "If your code depends on a private header, it IS broken."
-#endif  // MXGUI_LIBRARY
+#endif // MXGUI_LIBRARY
 
 #ifndef DISPLAY_STM32F4DISCOVERY_H
 #define DISPLAY_STM32F4DISCOVERY_H
@@ -47,7 +47,8 @@
     defined(_BOARD_STM32F429ZI_HRE_TEST_STAND) ||          \
     defined(_BOARD_STM32F429ZI_SKYWARD_PYXIS_AUXILIARY) || \
     defined(_BOARD_STM32F429ZI_SKYWARD_PARAFOIL) ||        \
-    defined(_BOARD_STM32F205RC_SKYWARD_CIUTI)
+    defined(_BOARD_STM32F205RC_SKYWARD_CIUTI) ||           \
+    defined(_BOARD_STM32F429ZI_SKYWARD_RIG)
 
 #include <config/mxgui_settings.h>
 
@@ -73,295 +74,295 @@ namespace mxgui
 #error The ILI9341 driver requires a color depth of 16bit per pixel
 #endif
 
-class DisplayImpl : public Display
-{
-public:
-    /**
-     * \return an instance to this class (singleton)
-     */
-    static DisplayImpl& instance();
-
-    /**
-     * Turn the display On after it has been turned Off.
-     * Display initial state is On.
-     */
-    void doTurnOn() override;
-
-    /**
-     * Turn the display Off. It can be later turned back On.
-     */
-    void doTurnOff() override;
-
-    /**
-     * Set display brightness. Depending on the underlying driver,
-     * may do nothing.
-     * \param brt from 0 to 100
-     */
-    void doSetBrightness(int brt) override;
-
-    /**
-     * \return a pair with the display height and width
-     */
-    std::pair<short int, short int> doGetSize() const override;
-
-    /**
-     * Write text to the display. If text is too long it will be truncated
-     * \param p point where the upper left corner of the text will be printed
-     * \param text, text to print.
-     */
-    void write(Point p, const char* text) override;
-
-    /**
-     * Write part of text to the display
-     * \param p point of the upper left corner where the text will be drawn.
-     * Negative coordinates are allowed, as long as the clipped view has
-     * positive or zero coordinates
-     * \param a Upper left corner of clipping rectangle
-     * \param b Lower right corner of clipping rectangle
-     * \param text text to write
-     */
-    void clippedWrite(Point p, Point a, Point b, const char* text) override;
-
-    /**
-     * Clear the Display. The screen will be filled with the desired color
-     * \param color fill color
-     */
-    void clear(Color color) override;
-
-    /**
-     * Clear an area of the screen
-     * \param p1 upper left corner of area to clear
-     * \param p2 lower right corner of area to clear
-     * \param color fill color
-     */
-    void clear(Point p1, Point p2, Color color) override;
-
-    /**
-     * This backend does not require it, so it is a blank.
-     */
-    void beginPixel() override;
-
-    /**
-     * Draw a pixel with desired color. You have to call beginPixel() once
-     * before calling setPixel()
-     * \param p point where to draw pixel
-     * \param color pixel color
-     */
-    void setPixel(Point p, Color color) override;
-
-    /**
-     * Draw a line between point a and point b, with color c
-     * \param a first point
-     * \param b second point
-     * \param c line color
-     */
-    void line(Point a, Point b, Color color) override;
-
-    /**
-     * Draw an horizontal line on screen.
-     * Instead of line(), this member function takes an array of colors to be
-     * able to individually set pixel colors of a line.
-     * \param p starting point of the line
-     * \param colors an array of pixel colors whoase size must be b.x()-a.x()+1
-     * \param length length of colors array.
-     * p.x()+length must be <= display.width()
-     */
-    void scanLine(Point p, const Color* colors, unsigned short length) override;
-
-    /**
-     * \return a buffer of length equal to this->getWidth() that can be used to
-     * render a scanline.
-     */
-    Color* getScanLineBuffer() override;
-
-    /**
-     * Draw the content of the last getScanLineBuffer() on an horizontal line
-     * on the screen.
-     * \param p starting point of the line
-     * \param length length of colors array.
-     * p.x()+length must be <= display.width()
-     */
-    void scanLineBuffer(Point p, unsigned short length) override;
-
-    /**
-     * Draw an image on the screen
-     * \param p point of the upper left corner where the image will be drawn
-     * \param i image to draw
-     */
-    void drawImage(Point p, const ImageBase& img) override;
-
-    /**
-     * Draw part of an image on the screen
-     * \param p point of the upper left corner where the image will be drawn.
-     * Negative coordinates are allowed, as long as the clipped view has
-     * positive or zero coordinates
-     * \param a Upper left corner of clipping rectangle
-     * \param b Lower right corner of clipping rectangle
-     * \param i Image to draw
-     */
-    void clippedDrawImage(Point p, Point a, Point b,
-                          const ImageBase& img) override;
-
-    /**
-     * Draw a rectangle (not filled) with the desired color
-     * \param a upper left corner of the rectangle
-     * \param b lower right corner of the rectangle
-     * \param c color of the line
-     */
-    void drawRectangle(Point a, Point b, Color c) override;
-
-    /**
-     * Pixel iterator. A pixel iterator is an output iterator that allows to
-     * define a window on the display and write to its pixels.
-     */
-    class pixel_iterator
+    class DisplayImpl : public Display
     {
     public:
         /**
-         * Default constructor, results in an invalid iterator.
-         * Note that since aIncr and sIncr are both zero all the writes will
-         * happens to the same memory location, but we need a safe
-         * /dev/null-like location where to write, which is dummy
+         * \return an instance to this class (singleton)
          */
-        pixel_iterator()
-            : ctr(0), endCtr(0), aIncr(0), sIncr(0), dataPtr(&dummy)
-        {
-        }
+        static DisplayImpl &instance();
 
         /**
-         * Set a pixel and move the pointer to the next one
-         * \param color color to set the current pixel
-         * \return a reference to this
+         * Turn the display On after it has been turned Off.
+         * Display initial state is On.
          */
-        pixel_iterator& operator=(Color color)
-        {
-            *dataPtr = color;
+        void doTurnOn() override;
 
-            // This is to move to the adjacent pixel
-            dataPtr += aIncr;
+        /**
+         * Turn the display Off. It can be later turned back On.
+         */
+        void doTurnOff() override;
 
-            // This is the step move to the next horizontal/vertical line
-            if (++ctr >= endCtr)
-            {
-                ctr = 0;
-                dataPtr += sIncr;
-            }
-            return *this;
-        }
+        /**
+         * Set display brightness. Depending on the underlying driver,
+         * may do nothing.
+         * \param brt from 0 to 100
+         */
+        void doSetBrightness(int brt) override;
 
         /**
-         * Compare two pixel_iterators for equality.
-         * They are equal if they point to the same location.
+         * \return a pair with the display height and width
          */
-        bool operator==(const pixel_iterator& itr)
-        {
-            return this->dataPtr == itr.dataPtr;
-        }
+        std::pair<short int, short int> doGetSize() const override;
 
         /**
-         * Compare two pixel_iterators for inequality.
-         * They different if they point to different locations.
+         * Write text to the display. If text is too long it will be truncated
+         * \param p point where the upper left corner of the text will be printed
+         * \param text, text to print.
          */
-        bool operator!=(const pixel_iterator& itr)
-        {
-            return this->dataPtr != itr.dataPtr;
-        }
+        void write(Point p, const char *text) override;
 
         /**
-         * \return a reference to this.
+         * Write part of text to the display
+         * \param p point of the upper left corner where the text will be drawn.
+         * Negative coordinates are allowed, as long as the clipped view has
+         * positive or zero coordinates
+         * \param a Upper left corner of clipping rectangle
+         * \param b Lower right corner of clipping rectangle
+         * \param text text to write
          */
-        pixel_iterator& operator*() { return *this; }
+        void clippedWrite(Point p, Point a, Point b, const char *text) override;
 
         /**
-         * \return a reference to this. Does not increment pixel pointer.
+         * Clear the Display. The screen will be filled with the desired color
+         * \param color fill color
          */
-        pixel_iterator& operator++() { return *this; }
+        void clear(Color color) override;
 
         /**
-         * \return a reference to this. Does not increment pixel pointer.
+         * Clear an area of the screen
+         * \param p1 upper left corner of area to clear
+         * \param p2 lower right corner of area to clear
+         * \param color fill color
          */
-        pixel_iterator& operator++(int) { return *this; }
+        void clear(Point p1, Point p2, Color color) override;
 
         /**
-         * Must be called if not all pixels of the required window are going
-         * to be written.
+         * This backend does not require it, so it is a blank.
          */
-        void invalidate() {}
+        void beginPixel() override;
+
+        /**
+         * Draw a pixel with desired color. You have to call beginPixel() once
+         * before calling setPixel()
+         * \param p point where to draw pixel
+         * \param color pixel color
+         */
+        void setPixel(Point p, Color color) override;
+
+        /**
+         * Draw a line between point a and point b, with color c
+         * \param a first point
+         * \param b second point
+         * \param c line color
+         */
+        void line(Point a, Point b, Color color) override;
+
+        /**
+         * Draw an horizontal line on screen.
+         * Instead of line(), this member function takes an array of colors to be
+         * able to individually set pixel colors of a line.
+         * \param p starting point of the line
+         * \param colors an array of pixel colors whoase size must be b.x()-a.x()+1
+         * \param length length of colors array.
+         * p.x()+length must be <= display.width()
+         */
+        void scanLine(Point p, const Color *colors, unsigned short length) override;
+
+        /**
+         * \return a buffer of length equal to this->getWidth() that can be used to
+         * render a scanline.
+         */
+        Color *getScanLineBuffer() override;
+
+        /**
+         * Draw the content of the last getScanLineBuffer() on an horizontal line
+         * on the screen.
+         * \param p starting point of the line
+         * \param length length of colors array.
+         * p.x()+length must be <= display.width()
+         */
+        void scanLineBuffer(Point p, unsigned short length) override;
+
+        /**
+         * Draw an image on the screen
+         * \param p point of the upper left corner where the image will be drawn
+         * \param i image to draw
+         */
+        void drawImage(Point p, const ImageBase &img) override;
+
+        /**
+         * Draw part of an image on the screen
+         * \param p point of the upper left corner where the image will be drawn.
+         * Negative coordinates are allowed, as long as the clipped view has
+         * positive or zero coordinates
+         * \param a Upper left corner of clipping rectangle
+         * \param b Lower right corner of clipping rectangle
+         * \param i Image to draw
+         */
+        void clippedDrawImage(Point p, Point a, Point b,
+                              const ImageBase &img) override;
+
+        /**
+         * Draw a rectangle (not filled) with the desired color
+         * \param a upper left corner of the rectangle
+         * \param b lower right corner of the rectangle
+         * \param c color of the line
+         */
+        void drawRectangle(Point a, Point b, Color c) override;
 
-    private:
         /**
-         * Constructor
-         * \param start Upper left corner of window
-         * \param end Lower right corner of window
-         * \param direction Iterator direction
-         * \param disp Display we're associated
+         * Pixel iterator. A pixel iterator is an output iterator that allows to
+         * define a window on the display and write to its pixels.
          */
-        pixel_iterator(Point start, Point end, IteratorDirection direction,
-                       DisplayImpl* disp)
-            : ctr(0), dataPtr(disp->framebuffer1)
+        class pixel_iterator
         {
-            // Compute the increment in the adjacent direction (aIncr) and in
-            // the step direction (sIncr) depending on the direction
-            dataPtr += start.y() * disp->getWidth() + start.x();
-            if (direction == RD)
+        public:
+            /**
+             * Default constructor, results in an invalid iterator.
+             * Note that since aIncr and sIncr are both zero all the writes will
+             * happens to the same memory location, but we need a safe
+             * /dev/null-like location where to write, which is dummy
+             */
+            pixel_iterator()
+                : ctr(0), endCtr(0), aIncr(0), sIncr(0), dataPtr(&dummy)
+            {
+            }
+
+            /**
+             * Set a pixel and move the pointer to the next one
+             * \param color color to set the current pixel
+             * \return a reference to this
+             */
+            pixel_iterator &operator=(Color color)
+            {
+                *dataPtr = color;
+
+                // This is to move to the adjacent pixel
+                dataPtr += aIncr;
+
+                // This is the step move to the next horizontal/vertical line
+                if (++ctr >= endCtr)
+                {
+                    ctr = 0;
+                    dataPtr += sIncr;
+                }
+                return *this;
+            }
+
+            /**
+             * Compare two pixel_iterators for equality.
+             * They are equal if they point to the same location.
+             */
+            bool operator==(const pixel_iterator &itr)
+            {
+                return this->dataPtr == itr.dataPtr;
+            }
+
+            /**
+             * Compare two pixel_iterators for inequality.
+             * They different if they point to different locations.
+             */
+            bool operator!=(const pixel_iterator &itr)
             {
-                endCtr = end.x() + 1 - start.x();
-                aIncr  = 1;
-                sIncr  = disp->getWidth() - endCtr;
+                return this->dataPtr != itr.dataPtr;
             }
-            else
+
+            /**
+             * \return a reference to this.
+             */
+            pixel_iterator &operator*() { return *this; }
+
+            /**
+             * \return a reference to this. Does not increment pixel pointer.
+             */
+            pixel_iterator &operator++() { return *this; }
+
+            /**
+             * \return a reference to this. Does not increment pixel pointer.
+             */
+            pixel_iterator &operator++(int) { return *this; }
+
+            /**
+             * Must be called if not all pixels of the required window are going
+             * to be written.
+             */
+            void invalidate() {}
+
+        private:
+            /**
+             * Constructor
+             * \param start Upper left corner of window
+             * \param end Lower right corner of window
+             * \param direction Iterator direction
+             * \param disp Display we're associated
+             */
+            pixel_iterator(Point start, Point end, IteratorDirection direction,
+                           DisplayImpl *disp)
+                : ctr(0), dataPtr(disp->framebuffer1)
             {
-                endCtr = end.y() + 1 - start.y();
-                aIncr  = disp->getWidth();
-                sIncr  = -aIncr * endCtr + 1;
+                // Compute the increment in the adjacent direction (aIncr) and in
+                // the step direction (sIncr) depending on the direction
+                dataPtr += start.y() * disp->getWidth() + start.x();
+                if (direction == RD)
+                {
+                    endCtr = end.x() + 1 - start.x();
+                    aIncr = 1;
+                    sIncr = disp->getWidth() - endCtr;
+                }
+                else
+                {
+                    endCtr = end.y() + 1 - start.y();
+                    aIncr = disp->getWidth();
+                    sIncr = -aIncr * endCtr + 1;
+                }
             }
-        }
 
-        unsigned short ctr;     ///< Counter to decide when to step
-        unsigned short endCtr;  ///< When ctr==endCtr apply a step
+            unsigned short ctr;    ///< Counter to decide when to step
+            unsigned short endCtr; ///< When ctr==endCtr apply a step
 
-        short aIncr;     ///< Adjacent increment
-        int sIncr;       ///< Step increment
-        Color* dataPtr;  ///< Pointer to framebuffer
+            short aIncr;    ///< Adjacent increment
+            int sIncr;      ///< Step increment
+            Color *dataPtr; ///< Pointer to framebuffer
 
-        static Color dummy;  ///< Invalid iterators write here
+            static Color dummy; ///< Invalid iterators write here
 
-        friend class DisplayImpl;  // Needs access to ctor
-    };
+            friend class DisplayImpl; // Needs access to ctor
+        };
+
+        /**
+         * Specify a window on screen and return an object that allows to write
+         * its pixels.
+         * Note: a call to begin() will invalidate any previous iterator.
+         * \param p1 upper left corner of window
+         * \param p2 lower right corner (included)
+         * \param d increment direction
+         * \return a pixel iterator
+         */
+        pixel_iterator begin(Point p1, Point p2, IteratorDirection d);
+
+        /**
+         * \return an iterator which is one past the last pixel in the pixel
+         * specified by begin. Behaviour is undefined if called before calling
+         * begin()
+         */
+        pixel_iterator end() const { return last; }
+
+        /**
+         * Destructor
+         */
+        ~DisplayImpl() override;
 
-    /**
-     * Specify a window on screen and return an object that allows to write
-     * its pixels.
-     * Note: a call to begin() will invalidate any previous iterator.
-     * \param p1 upper left corner of window
-     * \param p2 lower right corner (included)
-     * \param d increment direction
-     * \return a pixel iterator
-     */
-    pixel_iterator begin(Point p1, Point p2, IteratorDirection d);
-
-    /**
-     * \return an iterator which is one past the last pixel in the pixel
-     * specified by begin. Behaviour is undefined if called before calling
-     * begin()
-     */
-    pixel_iterator end() const { return last; }
-
-    /**
-     * Destructor
-     */
-    ~DisplayImpl() override;
-
-private:
-    /**
-     * Constructor.
-     * Do not instantiate objects of this type directly from application code.
-     */
-    DisplayImpl();
+    private:
+        /**
+         * Constructor.
+         * Do not instantiate objects of this type directly from application code.
+         */
+        DisplayImpl();
 
 #if defined MXGUI_ORIENTATION_VERTICAL
-    static const short int width  = 240;
-    static const short int height = 320;
+        static const short int width = 240;
+        static const short int height = 320;
 #elif defined MXGUI_ORIENTATION_HORIZONTAL ||      \
     defined MXGUI_ORIENTATION_VERTICAL_MIRRORED || \
     defined MXGUI_ORIENTATION_HORIZONTAL_MIRRORED
@@ -370,20 +371,20 @@ private:
 #error No orientation defined
 #endif
 
-    /**
-     * Pointer to the memory mapped display.
-     */
-    Color* const framebuffer1;
-    Color* buffer;        ///< For scanLineBuffer
-    pixel_iterator last;  ///< Last iterator for end of iteration check
-    static const unsigned int bpp = sizeof(Color);  ///< Bytes per pixel
-    static const int numPixels =
-        width * height;  ///< Number of pixels of the display
-};
+        /**
+         * Pointer to the memory mapped display.
+         */
+        Color *const framebuffer1;
+        Color *buffer;                                 ///< For scanLineBuffer
+        pixel_iterator last;                           ///< Last iterator for end of iteration check
+        static const unsigned int bpp = sizeof(Color); ///< Bytes per pixel
+        static const int numPixels =
+            width * height; ///< Number of pixels of the display
+    };
 
-}  // namespace mxgui
+} // namespace mxgui
 
-#endif  //_BOARD_STM32F429ZI_STM32F4DISCOVERY
+#endif //_BOARD_STM32F429ZI_STM32F4DISCOVERY
 
 #ifdef _BOARD_STM32F469NI_STM32F469I_DISCO
 
@@ -411,304 +412,304 @@ namespace mxgui
 #error The OTM8009A driver requires a color depth of 16bit per pixel
 #endif
 
-class DisplayImpl : public Display
-{
-public:
-    /**
-     * \return an instance to this class (singleton)
-     */
-    static DisplayImpl& instance();
-
-    /**
-     * Turn the display On after it has been turned Off.
-     * Display initial state is On.
-     */
-    void doTurnOn() override;
-
-    /**
-     * Turn the display Off. It can be later turned back On.
-     */
-    void doTurnOff() override;
-
-    /**
-     * Set display brightness. Depending on the underlying driver,
-     * may do nothing.
-     * \param brt from 0 to 100
-     */
-    void doSetBrightness(int brt) override;
-
-    /**
-     * \return a pair with the display height and width
-     */
-    std::pair<short int, short int> doGetSize() const override;
-
-    /**
-     * Write text to the display. If text is too long it will be truncated
-     * \param p point where the upper left corner of the text will be printed
-     * \param text, text to print.
-     */
-    void write(Point p, const char* text) override;
-
-    /**
-     * Write part of text to the display
-     * \param p point of the upper left corner where the text will be drawn.
-     * Negative coordinates are allowed, as long as the clipped view has
-     * positive or zero coordinates
-     * \param a Upper left corner of clipping rectangle
-     * \param b Lower right corner of clipping rectangle
-     * \param text text to write
-     */
-    void clippedWrite(Point p, Point a, Point b, const char* text) override;
-
-    /**
-     * Clear the Display. The screen will be filled with the desired color
-     * \param color fill color
-     */
-    void clear(Color color) override;
-
-    /**
-     * Clear an area of the screen
-     * \param p1 upper left corner of area to clear
-     * \param p2 lower right corner of area to clear
-     * \param color fill color
-     */
-    void clear(Point p1, Point p2, Color color) override;
-
-    /**
-     * This backend does not require it, so it is a blank.
-     */
-    void beginPixel() override;
-
-    /**
-     * Draw a pixel with desired color. You have to call beginPixel() once
-     * before calling setPixel()
-     * \param p point where to draw pixel
-     * \param color pixel color
-     */
-    void setPixel(Point p, Color color) override;
-
-    /**
-     * Draw a line between point a and point b, with color c
-     * \param a first point
-     * \param b second point
-     * \param c line color
-     */
-    void line(Point a, Point b, Color color) override;
-
-    /**
-     * Draw an horizontal line on screen.
-     * Instead of line(), this member function takes an array of colors to be
-     * able to individually set pixel colors of a line.
-     * \param p starting point of the line
-     * \param colors an array of pixel colors whoase size must be b.x()-a.x()+1
-     * \param length length of colors array.
-     * p.x()+length must be <= display.width()
-     */
-    void scanLine(Point p, const Color* colors, unsigned short length) override;
-
-    /**
-     * \return a buffer of length equal to this->getWidth() that can be used to
-     * render a scanline.
-     */
-    Color* getScanLineBuffer() override;
-
-    /**
-     * Draw the content of the last getScanLineBuffer() on an horizontal line
-     * on the screen.
-     * \param p starting point of the line
-     * \param length length of colors array.
-     * p.x()+length must be <= display.width()
-     */
-    void scanLineBuffer(Point p, unsigned short length) override;
-
-    /**
-     * Draw an image on the screen
-     * \param p point of the upper left corner where the image will be drawn
-     * \param i image to draw
-     */
-    void drawImage(Point p, const ImageBase& img) override;
-
-    /**
-     * Draw part of an image on the screen
-     * \param p point of the upper left corner where the image will be drawn.
-     * Negative coordinates are allowed, as long as the clipped view has
-     * positive or zero coordinates
-     * \param a Upper left corner of clipping rectangle
-     * \param b Lower right corner of clipping rectangle
-     * \param i Image to draw
-     */
-    void clippedDrawImage(Point p, Point a, Point b,
-                          const ImageBase& img) override;
-
-    /**
-     * Draw a rectangle (not filled) with the desired color
-     * \param a upper left corner of the rectangle
-     * \param b lower right corner of the rectangle
-     * \param c color of the line
-     */
-    void drawRectangle(Point a, Point b, Color c) override;
-
-    /**
-     * Make all changes done to the display since the last call to update()
-     * visible. This backend requires it.
-     */
-    void update() override;
-
-    /**
-     * Pixel iterator. A pixel iterator is an output iterator that allows to
-     * define a window on the display and write to its pixels.
-     */
-    class pixel_iterator
+    class DisplayImpl : public Display
     {
     public:
         /**
-         * Default constructor, results in an invalid iterator.
-         * Note that since aIncr and sIncr are both zero all the writes will
-         * happens to the same memory location, but we need a safe
-         * /dev/null-like location where to write, which is dummy
+         * \return an instance to this class (singleton)
          */
-        pixel_iterator()
-            : ctr(0), endCtr(0), aIncr(0), sIncr(0), dataPtr(&dummy)
-        {
-        }
+        static DisplayImpl &instance();
 
         /**
-         * Set a pixel and move the pointer to the next one
-         * \param color color to set the current pixel
-         * \return a reference to this
+         * Turn the display On after it has been turned Off.
+         * Display initial state is On.
          */
-        pixel_iterator& operator=(Color color)
-        {
-            *dataPtr = color;
+        void doTurnOn() override;
 
-            // This is to move to the adjacent pixel
-            dataPtr += aIncr;
+        /**
+         * Turn the display Off. It can be later turned back On.
+         */
+        void doTurnOff() override;
 
-            // This is the step move to the next horizontal/vertical line
-            if (++ctr >= endCtr)
-            {
-                ctr = 0;
-                dataPtr += sIncr;
-            }
-            return *this;
-        }
+        /**
+         * Set display brightness. Depending on the underlying driver,
+         * may do nothing.
+         * \param brt from 0 to 100
+         */
+        void doSetBrightness(int brt) override;
 
         /**
-         * Compare two pixel_iterators for equality.
-         * They are equal if they point to the same location.
+         * \return a pair with the display height and width
          */
-        bool operator==(const pixel_iterator& itr)
-        {
-            return this->dataPtr == itr.dataPtr;
-        }
+        std::pair<short int, short int> doGetSize() const override;
 
         /**
-         * Compare two pixel_iterators for inequality.
-         * They different if they point to different locations.
+         * Write text to the display. If text is too long it will be truncated
+         * \param p point where the upper left corner of the text will be printed
+         * \param text, text to print.
          */
-        bool operator!=(const pixel_iterator& itr)
-        {
-            return this->dataPtr != itr.dataPtr;
-        }
+        void write(Point p, const char *text) override;
 
         /**
-         * \return a reference to this.
+         * Write part of text to the display
+         * \param p point of the upper left corner where the text will be drawn.
+         * Negative coordinates are allowed, as long as the clipped view has
+         * positive or zero coordinates
+         * \param a Upper left corner of clipping rectangle
+         * \param b Lower right corner of clipping rectangle
+         * \param text text to write
          */
-        pixel_iterator& operator*() { return *this; }
+        void clippedWrite(Point p, Point a, Point b, const char *text) override;
 
         /**
-         * \return a reference to this. Does not increment pixel pointer.
+         * Clear the Display. The screen will be filled with the desired color
+         * \param color fill color
          */
-        pixel_iterator& operator++() { return *this; }
+        void clear(Color color) override;
 
         /**
-         * \return a reference to this. Does not increment pixel pointer.
+         * Clear an area of the screen
+         * \param p1 upper left corner of area to clear
+         * \param p2 lower right corner of area to clear
+         * \param color fill color
          */
-        pixel_iterator& operator++(int) { return *this; }
+        void clear(Point p1, Point p2, Color color) override;
 
         /**
-         * Must be called if not all pixels of the required window are going
-         * to be written.
+         * This backend does not require it, so it is a blank.
          */
-        void invalidate() {}
+        void beginPixel() override;
+
+        /**
+         * Draw a pixel with desired color. You have to call beginPixel() once
+         * before calling setPixel()
+         * \param p point where to draw pixel
+         * \param color pixel color
+         */
+        void setPixel(Point p, Color color) override;
+
+        /**
+         * Draw a line between point a and point b, with color c
+         * \param a first point
+         * \param b second point
+         * \param c line color
+         */
+        void line(Point a, Point b, Color color) override;
 
-    private:
         /**
-         * Constructor
-         * \param start Upper left corner of window
-         * \param end Lower right corner of window
-         * \param direction Iterator direction
-         * \param disp Display we're associated
+         * Draw an horizontal line on screen.
+         * Instead of line(), this member function takes an array of colors to be
+         * able to individually set pixel colors of a line.
+         * \param p starting point of the line
+         * \param colors an array of pixel colors whoase size must be b.x()-a.x()+1
+         * \param length length of colors array.
+         * p.x()+length must be <= display.width()
          */
-        pixel_iterator(Point start, Point end, IteratorDirection direction,
-                       DisplayImpl* disp)
-            : ctr(0), dataPtr(disp->framebuffer1)
+        void scanLine(Point p, const Color *colors, unsigned short length) override;
+
+        /**
+         * \return a buffer of length equal to this->getWidth() that can be used to
+         * render a scanline.
+         */
+        Color *getScanLineBuffer() override;
+
+        /**
+         * Draw the content of the last getScanLineBuffer() on an horizontal line
+         * on the screen.
+         * \param p starting point of the line
+         * \param length length of colors array.
+         * p.x()+length must be <= display.width()
+         */
+        void scanLineBuffer(Point p, unsigned short length) override;
+
+        /**
+         * Draw an image on the screen
+         * \param p point of the upper left corner where the image will be drawn
+         * \param i image to draw
+         */
+        void drawImage(Point p, const ImageBase &img) override;
+
+        /**
+         * Draw part of an image on the screen
+         * \param p point of the upper left corner where the image will be drawn.
+         * Negative coordinates are allowed, as long as the clipped view has
+         * positive or zero coordinates
+         * \param a Upper left corner of clipping rectangle
+         * \param b Lower right corner of clipping rectangle
+         * \param i Image to draw
+         */
+        void clippedDrawImage(Point p, Point a, Point b,
+                              const ImageBase &img) override;
+
+        /**
+         * Draw a rectangle (not filled) with the desired color
+         * \param a upper left corner of the rectangle
+         * \param b lower right corner of the rectangle
+         * \param c color of the line
+         */
+        void drawRectangle(Point a, Point b, Color c) override;
+
+        /**
+         * Make all changes done to the display since the last call to update()
+         * visible. This backend requires it.
+         */
+        void update() override;
+
+        /**
+         * Pixel iterator. A pixel iterator is an output iterator that allows to
+         * define a window on the display and write to its pixels.
+         */
+        class pixel_iterator
         {
-            // Compute the increment in the adjacent direction (aIncr) and in
-            // the step direction (sIncr) depending on the direction
-            dataPtr += start.y() * disp->getWidth() + start.x();
-            if (direction == RD)
+        public:
+            /**
+             * Default constructor, results in an invalid iterator.
+             * Note that since aIncr and sIncr are both zero all the writes will
+             * happens to the same memory location, but we need a safe
+             * /dev/null-like location where to write, which is dummy
+             */
+            pixel_iterator()
+                : ctr(0), endCtr(0), aIncr(0), sIncr(0), dataPtr(&dummy)
+            {
+            }
+
+            /**
+             * Set a pixel and move the pointer to the next one
+             * \param color color to set the current pixel
+             * \return a reference to this
+             */
+            pixel_iterator &operator=(Color color)
             {
-                endCtr = end.x() + 1 - start.x();
-                aIncr  = 1;
-                sIncr  = disp->getWidth() - endCtr;
+                *dataPtr = color;
+
+                // This is to move to the adjacent pixel
+                dataPtr += aIncr;
+
+                // This is the step move to the next horizontal/vertical line
+                if (++ctr >= endCtr)
+                {
+                    ctr = 0;
+                    dataPtr += sIncr;
+                }
+                return *this;
             }
-            else
+
+            /**
+             * Compare two pixel_iterators for equality.
+             * They are equal if they point to the same location.
+             */
+            bool operator==(const pixel_iterator &itr)
+            {
+                return this->dataPtr == itr.dataPtr;
+            }
+
+            /**
+             * Compare two pixel_iterators for inequality.
+             * They different if they point to different locations.
+             */
+            bool operator!=(const pixel_iterator &itr)
             {
-                endCtr = end.y() + 1 - start.y();
-                aIncr  = disp->getWidth();
-                sIncr  = -aIncr * endCtr + 1;
+                return this->dataPtr != itr.dataPtr;
             }
-        }
 
-        unsigned short ctr;     ///< Counter to decide when to step
-        unsigned short endCtr;  ///< When ctr==endCtr apply a step
+            /**
+             * \return a reference to this.
+             */
+            pixel_iterator &operator*() { return *this; }
+
+            /**
+             * \return a reference to this. Does not increment pixel pointer.
+             */
+            pixel_iterator &operator++() { return *this; }
+
+            /**
+             * \return a reference to this. Does not increment pixel pointer.
+             */
+            pixel_iterator &operator++(int) { return *this; }
+
+            /**
+             * Must be called if not all pixels of the required window are going
+             * to be written.
+             */
+            void invalidate() {}
+
+        private:
+            /**
+             * Constructor
+             * \param start Upper left corner of window
+             * \param end Lower right corner of window
+             * \param direction Iterator direction
+             * \param disp Display we're associated
+             */
+            pixel_iterator(Point start, Point end, IteratorDirection direction,
+                           DisplayImpl *disp)
+                : ctr(0), dataPtr(disp->framebuffer1)
+            {
+                // Compute the increment in the adjacent direction (aIncr) and in
+                // the step direction (sIncr) depending on the direction
+                dataPtr += start.y() * disp->getWidth() + start.x();
+                if (direction == RD)
+                {
+                    endCtr = end.x() + 1 - start.x();
+                    aIncr = 1;
+                    sIncr = disp->getWidth() - endCtr;
+                }
+                else
+                {
+                    endCtr = end.y() + 1 - start.y();
+                    aIncr = disp->getWidth();
+                    sIncr = -aIncr * endCtr + 1;
+                }
+            }
 
-        short aIncr;     ///< Adjacent increment
-        int sIncr;       ///< Step increment
-        Color* dataPtr;  ///< Pointer to framebuffer
+            unsigned short ctr;    ///< Counter to decide when to step
+            unsigned short endCtr; ///< When ctr==endCtr apply a step
 
-        static Color dummy;  ///< Invalid iterators write here
+            short aIncr;    ///< Adjacent increment
+            int sIncr;      ///< Step increment
+            Color *dataPtr; ///< Pointer to framebuffer
 
-        friend class DisplayImpl;  // Needs access to ctor
-    };
+            static Color dummy; ///< Invalid iterators write here
 
-    /**
-     * Specify a window on screen and return an object that allows to write
-     * its pixels.
-     * Note: a call to begin() will invalidate any previous iterator.
-     * \param p1 upper left corner of window
-     * \param p2 lower right corner (included)
-     * \param d increment direction
-     * \return a pixel iterator
-     */
-    pixel_iterator begin(Point p1, Point p2, IteratorDirection d);
-
-    /**
-     * \return an iterator which is one past the last pixel in the pixel
-     * specified by begin. Behaviour is undefined if called before calling
-     * begin()
-     */
-    pixel_iterator end() const { return last; }
-
-    /**
-     * Destructor
-     */
-    ~DisplayImpl() override;
-
-private:
-    /**
-     * Constructor.
-     * Do not instantiate objects of this type directly from application code.
-     */
-    DisplayImpl();
+            friend class DisplayImpl; // Needs access to ctor
+        };
+
+        /**
+         * Specify a window on screen and return an object that allows to write
+         * its pixels.
+         * Note: a call to begin() will invalidate any previous iterator.
+         * \param p1 upper left corner of window
+         * \param p2 lower right corner (included)
+         * \param d increment direction
+         * \return a pixel iterator
+         */
+        pixel_iterator begin(Point p1, Point p2, IteratorDirection d);
+
+        /**
+         * \return an iterator which is one past the last pixel in the pixel
+         * specified by begin. Behaviour is undefined if called before calling
+         * begin()
+         */
+        pixel_iterator end() const { return last; }
+
+        /**
+         * Destructor
+         */
+        ~DisplayImpl() override;
+
+    private:
+        /**
+         * Constructor.
+         * Do not instantiate objects of this type directly from application code.
+         */
+        DisplayImpl();
 
 #if defined MXGUI_ORIENTATION_VERTICAL
-    static const short int width  = 480;
-    static const short int height = 800;
+        static const short int width = 480;
+        static const short int height = 800;
 #elif defined MXGUI_ORIENTATION_HORIZONTAL
-    static const short int width  = 800;
-    static const short int height = 480;
+        static const short int width = 800;
+        static const short int height = 480;
 #elif defined MXGUI_ORIENTATION_VERTICAL_MIRRORED || \
     defined MXGUI_ORIENTATION_HORIZONTAL_MIRRORED
 #error unsupported orientation
@@ -716,19 +717,19 @@ private:
 #error No orientation defined
 #endif
 
-    /**
-     * Pointer to the memory mapped display.
-     */
-    Color* const framebuffer1;
-    Color* buffer;        ///< For scanLineBuffer
-    pixel_iterator last;  ///< Last iterator for end of iteration check
-    static const unsigned int bpp = sizeof(Color);  ///< Bytes per pixel
-    static const int numPixels =
-        width * height;  ///< Number of pixels of the display
-};
+        /**
+         * Pointer to the memory mapped display.
+         */
+        Color *const framebuffer1;
+        Color *buffer;                                 ///< For scanLineBuffer
+        pixel_iterator last;                           ///< Last iterator for end of iteration check
+        static const unsigned int bpp = sizeof(Color); ///< Bytes per pixel
+        static const int numPixels =
+            width * height; ///< Number of pixels of the display
+    };
 
-}  // namespace mxgui
+} // namespace mxgui
 
-#endif  //_BOARD_STM32F469NI_STM32F469I_DISCO
+#endif //_BOARD_STM32F469NI_STM32F469I_DISCO
 
-#endif  // DISPLAY_STM32F4DISCOVERY_H
+#endif // DISPLAY_STM32F4DISCOVERY_H
diff --git a/mxgui/drivers/event_stm32f4discovery.cpp b/mxgui/drivers/event_stm32f4discovery.cpp
index 1341b2c1334374cf68d832cdc8d5647076b493bc..04561b6496fb868c2598e89a2d8982143e5ceb73 100644
--- a/mxgui/drivers/event_stm32f4discovery.cpp
+++ b/mxgui/drivers/event_stm32f4discovery.cpp
@@ -43,6 +43,7 @@
     defined(_BOARD_STM32F429ZI_HRE_TEST_STAND) ||          \
     defined(_BOARD_STM32F429ZI_SKYWARD_PYXIS_AUXILIARY) || \
     defined(_BOARD_STM32F429ZI_SKYWARD_PARAFOIL) ||        \
+    defined(_BOARD_STM32F429ZI_SKYWARD_RIG) ||             \
     defined(_BOARD_STM32F205RC_SKYWARD_CIUTI) && defined(MXGUI_LEVEL_2)
 
 #include <algorithm>
@@ -55,7 +56,7 @@
 using namespace std;
 using namespace miosix;
 
-static Thread *waiting   = 0;
+static Thread *waiting = 0;
 static volatile bool irq = false;
 static volatile int flag = 0;
 
@@ -115,284 +116,284 @@ void __attribute__((used)) EXTI0HandlerImpl()
 namespace mxgui
 {
 
-typedef Gpio<GPIOA_BASE, 0> buttonA;
-typedef Gpio<GPIOA_BASE, 8> scl;  // I2C3 SCL
-typedef Gpio<GPIOC_BASE, 9> sda;  // I2C3 SDA
-typedef Gpio<GPIOA_BASE, 15> interrupt;
+    typedef Gpio<GPIOA_BASE, 0> buttonA;
+    typedef Gpio<GPIOA_BASE, 8> scl; // I2C3 SCL
+    typedef Gpio<GPIOC_BASE, 9> sda; // I2C3 SDA
+    typedef Gpio<GPIOA_BASE, 15> interrupt;
 
-typedef SoftwareI2C<sda, scl> stmpe811;
+    typedef SoftwareI2C<sda, scl> stmpe811;
 
-/**
- * The registers of the stmpe811 touchscreen controller
- */
-enum stmpe811regs
-{
-    SYS_CTRL1 = 0x03,
-    SYS_CTRL2 = 0x04,
-    INT_CTRL  = 0x09,
-    INT_EN    = 0x0a,
-    INT_STA   = 0x0B,
-    TSC_CTRL  = 0x40,
-    TSC_CFG   = 0x41,
-    FIFO_TH   = 0x4a,
-    FIFO_STA  = 0x4b,
-    TSC_DATA  = 0xd7,
-    FIFO_SIZE = 0x4C
-};
-
-/**
- * Write into a register in the stmpe811
- * \param reg register number
- * \param val value to be written in the register
- */
-static void stmpe811writeReg(unsigned char reg, unsigned char val)
-{
-    stmpe811::sendStart();
-    stmpe811::send(0x82);
-    stmpe811::send(reg);
-    stmpe811::send(val);
-    stmpe811::sendStop();
-}
-
-/**
- * Read from a register of the stmpe811
- * \param reg register number
- * \param n number of bytes to read from register
- * \param pointer to a memory area of at least n bytes where the read data will
- * be stored
- */
-static void stmpe811readReg(unsigned char reg, int n, unsigned char *result)
-{
-    if (n <= 0)
-        return;
-    stmpe811::sendStart();
-    stmpe811::send(0x82);
-    stmpe811::send(reg);
-    stmpe811::sendStop();
-    stmpe811::sendStart();
-    stmpe811::send(0x82 | 1);
-    for (int i = 0; i < n - 1; i++)
-        result[i] = stmpe811::recvWithAck();
-    result[n - 1] = stmpe811::recvWithNack();
-    stmpe811::sendStop();
-}
-
-/**
- * Clear the stmpe811 fifo
- */
-static void touchFifoClear()
-{
-    stmpe811writeReg(FIFO_STA, 0x01);  // RESET FIFO
-    stmpe811writeReg(FIFO_STA, 0x00);  // RESET FIFO
-}
+    /**
+     * The registers of the stmpe811 touchscreen controller
+     */
+    enum stmpe811regs
+    {
+        SYS_CTRL1 = 0x03,
+        SYS_CTRL2 = 0x04,
+        INT_CTRL = 0x09,
+        INT_EN = 0x0a,
+        INT_STA = 0x0B,
+        TSC_CTRL = 0x40,
+        TSC_CFG = 0x41,
+        FIFO_TH = 0x4a,
+        FIFO_STA = 0x4b,
+        TSC_DATA = 0xd7,
+        FIFO_SIZE = 0x4C
+    };
+
+    /**
+     * Write into a register in the stmpe811
+     * \param reg register number
+     * \param val value to be written in the register
+     */
+    static void stmpe811writeReg(unsigned char reg, unsigned char val)
+    {
+        stmpe811::sendStart();
+        stmpe811::send(0x82);
+        stmpe811::send(reg);
+        stmpe811::send(val);
+        stmpe811::sendStop();
+    }
 
-/**
- * \return the touch point or (-1,-1) if no touch is in progress
- */
-static Point getTouchData()
-{
-    unsigned char ctrl;
-    stmpe811readReg(TSC_CTRL, 1, &ctrl);
-    if ((ctrl & 0x80) == 0)
+    /**
+     * Read from a register of the stmpe811
+     * \param reg register number
+     * \param n number of bytes to read from register
+     * \param pointer to a memory area of at least n bytes where the read data will
+     * be stored
+     */
+    static void stmpe811readReg(unsigned char reg, int n, unsigned char *result)
     {
-        flag = 0;
-        return Point(-1, -1);
+        if (n <= 0)
+            return;
+        stmpe811::sendStart();
+        stmpe811::send(0x82);
+        stmpe811::send(reg);
+        stmpe811::sendStop();
+        stmpe811::sendStart();
+        stmpe811::send(0x82 | 1);
+        for (int i = 0; i < n - 1; i++)
+            result[i] = stmpe811::recvWithAck();
+        result[n - 1] = stmpe811::recvWithNack();
+        stmpe811::sendStop();
     }
-    if (flag == 0)
+
+    /**
+     * Clear the stmpe811 fifo
+     */
+    static void touchFifoClear()
     {
-        flag = 1;
-        return Point(-1, -1);
+        stmpe811writeReg(FIFO_STA, 0x01); // RESET FIFO
+        stmpe811writeReg(FIFO_STA, 0x00); // RESET FIFO
     }
-    else
+
+    /**
+     * \return the touch point or (-1,-1) if no touch is in progress
+     */
+    static Point getTouchData()
     {
-        unsigned char tsData[3];
-        stmpe811readReg(TSC_DATA, 3, tsData);
-        stmpe811writeReg(FIFO_STA, 0x01);  // RESET FIFO
-        stmpe811writeReg(FIFO_STA, 0x00);  // RESET FIFO
-        int x = static_cast<int>(tsData[0]) << 4 | tsData[1] >> 4;
-        int y = ((static_cast<int>(tsData[1]) & 0xf) << 8) | tsData[2];
-        x     = 4095 - x;  // X is swapped
-        // Calibration values. May vary from unit to unit
-        const int xMin = 300;
-        const int xMax = 3770;
-        const int yMin = 300;
-        const int yMax = 3880;
-
-        x = ((x - xMin) * 240) / (xMax - xMin);
-        y = ((y - yMin) * 320) / (yMax - yMin);
-        x = min(239, max(0, x));
-        y = min(319, max(0, y));
-        return Point(x, y);
+        unsigned char ctrl;
+        stmpe811readReg(TSC_CTRL, 1, &ctrl);
+        if ((ctrl & 0x80) == 0)
+        {
+            flag = 0;
+            return Point(-1, -1);
+        }
+        if (flag == 0)
+        {
+            flag = 1;
+            return Point(-1, -1);
+        }
+        else
+        {
+            unsigned char tsData[3];
+            stmpe811readReg(TSC_DATA, 3, tsData);
+            stmpe811writeReg(FIFO_STA, 0x01); // RESET FIFO
+            stmpe811writeReg(FIFO_STA, 0x00); // RESET FIFO
+            int x = static_cast<int>(tsData[0]) << 4 | tsData[1] >> 4;
+            int y = ((static_cast<int>(tsData[1]) & 0xf) << 8) | tsData[2];
+            x = 4095 - x; // X is swapped
+            // Calibration values. May vary from unit to unit
+            const int xMin = 300;
+            const int xMax = 3770;
+            const int yMin = 300;
+            const int yMax = 3880;
+
+            x = ((x - xMin) * 240) / (xMax - xMin);
+            y = ((y - yMin) * 320) / (yMax - yMin);
+            x = min(239, max(0, x));
+            y = min(319, max(0, y));
+            return Point(x, y);
+        }
     }
-}
 
-static Queue<Event, 10> eventQueue;
-static std::function<void()> eventCallback;
+    static Queue<Event, 10> eventQueue;
+    static std::function<void()> eventCallback;
 
-static void callback(Event e)
-{
+    static void callback(Event e)
     {
-        FastInterruptDisableLock dLock;
-        if (eventQueue.IRQput(e) == false)
-            return;
+        {
+            FastInterruptDisableLock dLock;
+            if (eventQueue.IRQput(e) == false)
+                return;
+        }
+        if (eventCallback)
+            eventCallback();
     }
-    if (eventCallback)
-        eventCallback();
-}
 
-static void waitForTouchOrButton()
-{
+    static void waitForTouchOrButton()
     {
-        FastInterruptDisableLock dLock2;
-        if (irq == false)
         {
-            waiting = Thread::IRQgetCurrentThread();
-            while (waiting)
+            FastInterruptDisableLock dLock2;
+            if (irq == false)
             {
-                Thread::IRQwait();
-                FastInterruptEnableLock eLock(dLock2);
-                Thread::yield();
+                waiting = Thread::IRQgetCurrentThread();
+                while (waiting)
+                {
+                    Thread::IRQwait();
+                    FastInterruptEnableLock eLock(dLock2);
+                    Thread::yield();
+                }
             }
+            irq = false;
         }
-        irq = false;
+        stmpe811writeReg(INT_STA, 0x03);
     }
-    stmpe811writeReg(INT_STA, 0x03);
-}
 
-static void eventThread(void *)
-{
-    bool aPrev = false;
-    bool tPrev = false;
-    Point pOld;
-    for (;;)
+    static void eventThread(void *)
     {
-        waitForTouchOrButton();
-
-        // Check buttons
-        if (buttonA::value() == 1)
-        {
-            if (aPrev == false)
-                callback(Event(EventType::ButtonA, EventDirection::DOWN));
-            aPrev = true;
-        }
-        else
-        {
-            if (aPrev == true)
-                callback(Event(EventType::ButtonA, EventDirection::UP));
-            aPrev = false;
-        }
-        // Check touchscreen
-        Point p = getTouchData();
-        if (p.x() >= 0)  // Is someone touching the screen?
+        bool aPrev = false;
+        bool tPrev = false;
+        Point pOld;
+        for (;;)
         {
-            // Ok, someone is touching the screen
-            // Did the touch point differ that much from the previous?
-            if (abs(pOld.x() - p.x()) > 3 || abs(pOld.y() - p.y()) > 3 ||
-                !tPrev)
+            waitForTouchOrButton();
+
+            // Check buttons
+            if (buttonA::value() == 1)
             {
-                pOld = p;
-                if (tPrev == false)
-                    callback(Event(EventType::TouchDown, pOld,
-                                   EventDirection::DOWN));
-                else
-                    callback(Event(EventType::TouchMove, pOld,
-                                   EventDirection::DOWN));
+                if (aPrev == false)
+                    callback(Event(EventType::ButtonA, EventDirection::DOWN));
+                aPrev = true;
             }
-            tPrev = true;
-        }
-        else
-        {
-            // No, no one is touching the screen
-            if (tPrev == true)
+            else
             {
-                touchFifoClear();
-                callback(Event(EventType::TouchUp, pOld, EventDirection::UP));
+                if (aPrev == true)
+                    callback(Event(EventType::ButtonA, EventDirection::UP));
+                aPrev = false;
+            }
+            // Check touchscreen
+            Point p = getTouchData();
+            if (p.x() >= 0) // Is someone touching the screen?
+            {
+                // Ok, someone is touching the screen
+                // Did the touch point differ that much from the previous?
+                if (abs(pOld.x() - p.x()) > 3 || abs(pOld.y() - p.y()) > 3 ||
+                    !tPrev)
+                {
+                    pOld = p;
+                    if (tPrev == false)
+                        callback(Event(EventType::TouchDown, pOld,
+                                       EventDirection::DOWN));
+                    else
+                        callback(Event(EventType::TouchMove, pOld,
+                                       EventDirection::DOWN));
+                }
+                tPrev = true;
+            }
+            else
+            {
+                // No, no one is touching the screen
+                if (tPrev == true)
+                {
+                    touchFifoClear();
+                    callback(Event(EventType::TouchUp, pOld, EventDirection::UP));
+                }
+                tPrev = false;
             }
-            tPrev = false;
         }
     }
-}
 
-//
-// class InputHandlerImpl
-//
+    //
+    // class InputHandlerImpl
+    //
 
-InputHandlerImpl::InputHandlerImpl()
-{
+    InputHandlerImpl::InputHandlerImpl()
     {
-        FastInterruptDisableLock dLock;
-        buttonA::mode(Mode::INPUT_PULL_DOWN);
-        interrupt::mode(Mode::INPUT);
-        stmpe811::init();
-    }
+        {
+            FastInterruptDisableLock dLock;
+            buttonA::mode(Mode::INPUT_PULL_DOWN);
+            interrupt::mode(Mode::INPUT);
+            stmpe811::init();
+        }
 
-    // To let the I2C voltages settle
-    Thread::sleep(5);
-
-    stmpe811writeReg(SYS_CTRL1, 0x02);  // SOFT_RESET=1
-    Thread::sleep(10);
-    stmpe811writeReg(SYS_CTRL1, 0x00);  // SOFT_RESET=0
-    Thread::sleep(2);
-    stmpe811writeReg(SYS_CTRL2, 0x08);  // !GPIO_OFF !TSC_OFF !ADC_OFF
-
-    // Total time to read the touchscreen is
-    // TDD*2+SETTLING*3+AVE*17.2us*3= ~ 17.5ms
-    stmpe811writeReg(TSC_CFG, 0xe4);   // TSC_CFG= AVE=8, TDD=1ms, SETTLING=5ms
-    stmpe811writeReg(FIFO_TH, 0x01);   // FIFO_TH= 1
-    stmpe811writeReg(FIFO_STA, 0x01);  // RESET FIFO
-    stmpe811writeReg(FIFO_STA, 0x00);  // RESET FIFO
-
-    // This may allow the chip to go out of hibernate once touch detected
-    stmpe811writeReg(INT_CTRL, 0x01);
-    stmpe811writeReg(INT_EN, 0x03);
-
-    stmpe811writeReg(
-        TSC_CTRL, 0x73);  // TSC_CTRL=No window track, XY, Enabled
-                          // 0xA3 Rumore escluso. impostare A da 1(min) a 7(max)
-                          // per modificare l'assorbimento del rumore sul touch
-    // impostiamo registri
-    stmpe811writeReg(FIFO_TH, 0x01);
-
-    // impostiamo l'interrupt del touchscreen
-    EXTI->IMR |= EXTI_IMR_MR15;
-    EXTI->FTSR |= EXTI_FTSR_TR15;
-    NVIC_EnableIRQ(EXTI15_10_IRQn);
-    NVIC_SetPriority(EXTI15_10_IRQn, 15);  // Low priority
-
-    // impostiamo l'interrupt del bottone
-    EXTI->IMR |= EXTI_IMR_MR0;
-    EXTI->RTSR |= EXTI_RTSR_TR0;
-    EXTI->FTSR |= EXTI_FTSR_TR0;
-    NVIC_EnableIRQ(EXTI0_IRQn);
-    NVIC_SetPriority(EXTI0_IRQn, 15);  // Low priority
-
-    // Note that this class is instantiated only once. Otherwise
-    // we'd have to think a way to avoid creating multiple threads
-    Thread::create(eventThread, STACK_MIN);
-}
+        // To let the I2C voltages settle
+        Thread::sleep(5);
+
+        stmpe811writeReg(SYS_CTRL1, 0x02); // SOFT_RESET=1
+        Thread::sleep(10);
+        stmpe811writeReg(SYS_CTRL1, 0x00); // SOFT_RESET=0
+        Thread::sleep(2);
+        stmpe811writeReg(SYS_CTRL2, 0x08); // !GPIO_OFF !TSC_OFF !ADC_OFF
+
+        // Total time to read the touchscreen is
+        // TDD*2+SETTLING*3+AVE*17.2us*3= ~ 17.5ms
+        stmpe811writeReg(TSC_CFG, 0xe4);  // TSC_CFG= AVE=8, TDD=1ms, SETTLING=5ms
+        stmpe811writeReg(FIFO_TH, 0x01);  // FIFO_TH= 1
+        stmpe811writeReg(FIFO_STA, 0x01); // RESET FIFO
+        stmpe811writeReg(FIFO_STA, 0x00); // RESET FIFO
+
+        // This may allow the chip to go out of hibernate once touch detected
+        stmpe811writeReg(INT_CTRL, 0x01);
+        stmpe811writeReg(INT_EN, 0x03);
+
+        stmpe811writeReg(
+            TSC_CTRL, 0x73); // TSC_CTRL=No window track, XY, Enabled
+                             // 0xA3 Rumore escluso. impostare A da 1(min) a 7(max)
+                             // per modificare l'assorbimento del rumore sul touch
+        // impostiamo registri
+        stmpe811writeReg(FIFO_TH, 0x01);
+
+        // impostiamo l'interrupt del touchscreen
+        EXTI->IMR |= EXTI_IMR_MR15;
+        EXTI->FTSR |= EXTI_FTSR_TR15;
+        NVIC_EnableIRQ(EXTI15_10_IRQn);
+        NVIC_SetPriority(EXTI15_10_IRQn, 15); // Low priority
+
+        // impostiamo l'interrupt del bottone
+        EXTI->IMR |= EXTI_IMR_MR0;
+        EXTI->RTSR |= EXTI_RTSR_TR0;
+        EXTI->FTSR |= EXTI_FTSR_TR0;
+        NVIC_EnableIRQ(EXTI0_IRQn);
+        NVIC_SetPriority(EXTI0_IRQn, 15); // Low priority
+
+        // Note that this class is instantiated only once. Otherwise
+        // we'd have to think a way to avoid creating multiple threads
+        Thread::create(eventThread, STACK_MIN);
+    }
 
-Event InputHandlerImpl::getEvent()
-{
-    Event result;
-    eventQueue.get(result);
-    return result;
-}
+    Event InputHandlerImpl::getEvent()
+    {
+        Event result;
+        eventQueue.get(result);
+        return result;
+    }
 
-Event InputHandlerImpl::popEvent()
-{
-    FastInterruptDisableLock dLock;
-    Event result;
-    if (eventQueue.isEmpty() == false)
-        eventQueue.IRQget(result);
-    return result;
-}
+    Event InputHandlerImpl::popEvent()
+    {
+        FastInterruptDisableLock dLock;
+        Event result;
+        if (eventQueue.isEmpty() == false)
+            eventQueue.IRQget(result);
+        return result;
+    }
 
-function<void()> InputHandlerImpl::registerEventCallback(function<void()> cb)
-{
-    swap(eventCallback, cb);
-    return cb;
-}
+    function<void()> InputHandlerImpl::registerEventCallback(function<void()> cb)
+    {
+        swap(eventCallback, cb);
+        return cb;
+    }
 
-}  // namespace mxgui
+} // namespace mxgui
 
-#endif  //_BOARD_STM32F429ZI_STM32F4DISCOVERY
+#endif //_BOARD_STM32F429ZI_STM32F4DISCOVERY
diff --git a/mxgui/drivers/event_stm32f4discovery.h b/mxgui/drivers/event_stm32f4discovery.h
index 60ce9578f8cf37f6816073d6fea317d8247cf052..8334fe87c0454feb78becc86489ccae8987a9965 100644
--- a/mxgui/drivers/event_stm32f4discovery.h
+++ b/mxgui/drivers/event_stm32f4discovery.h
@@ -28,7 +28,7 @@
 #ifndef MXGUI_LIBRARY
 #error "This is header is private, it can be used only within mxgui."
 #error "If your code depends on a private header, it IS broken."
-#endif  // MXGUI_LIBRARY
+#endif // MXGUI_LIBRARY
 
 #include <functional>
 
@@ -52,46 +52,47 @@
     defined(_BOARD_STM32F429ZI_HRE_TEST_STAND) ||          \
     defined(_BOARD_STM32F429ZI_SKYWARD_PYXIS_AUXILIARY) || \
     defined(_BOARD_STM32F429ZI_SKYWARD_PARAFOIL) ||        \
-    defined(_BOARD_STM32F205RC_SKYWARD_CIUTI)
+    defined(_BOARD_STM32F205RC_SKYWARD_CIUTI) ||           \
+    defined(_BOARD_STM32F429ZI_SKYWARD_RIG)
 
 namespace mxgui
 {
 
-/**
- * Implementation class to handle events in the Mp3v2 backend
- */
-class InputHandlerImpl
-{
-public:
-    InputHandlerImpl();
-
     /**
-     * \return an event, blocking
+     * Implementation class to handle events in the Mp3v2 backend
      */
-    Event getEvent();
+    class InputHandlerImpl
+    {
+    public:
+        InputHandlerImpl();
 
-    /**
-     * \return an event, nonblocking. A default constructed event is returned
-     * if there are no events.
-     */
-    Event popEvent();
+        /**
+         * \return an event, blocking
+         */
+        Event getEvent();
 
-    /**
-     * Register a callback that will be called every time an event is geenrated
-     *
-     * Note: the thread calling the callback has a very small stack.
-     *
-     * Note: concurrent access to this memebr function causes undefined
-     * behaviour
-     *
-     * \param cb new callback to register
-     * \return the previous callback
-     */
-    std::function<void()> registerEventCallback(std::function<void()> cb);
-};
+        /**
+         * \return an event, nonblocking. A default constructed event is returned
+         * if there are no events.
+         */
+        Event popEvent();
+
+        /**
+         * Register a callback that will be called every time an event is geenrated
+         *
+         * Note: the thread calling the callback has a very small stack.
+         *
+         * Note: concurrent access to this memebr function causes undefined
+         * behaviour
+         *
+         * \param cb new callback to register
+         * \return the previous callback
+         */
+        std::function<void()> registerEventCallback(std::function<void()> cb);
+    };
 
-}  // namespace mxgui
+} // namespace mxgui
 
-#endif  //_BOARD_STM32F429ZI_STM32F4DISCOVERY
+#endif //_BOARD_STM32F429ZI_STM32F4DISCOVERY
 
-#endif  // EVENT_STM32F4DISCOVERY_H
+#endif // EVENT_STM32F4DISCOVERY_H
diff --git a/mxgui/drivers/event_types_stm32f4discovery.h b/mxgui/drivers/event_types_stm32f4discovery.h
index 6eb398beec960621b9f65c1df8ebc799485c1b11..587502a1bcdc708454307adce67dce1c04695477 100644
--- a/mxgui/drivers/event_types_stm32f4discovery.h
+++ b/mxgui/drivers/event_types_stm32f4discovery.h
@@ -43,7 +43,8 @@
     defined(_BOARD_STM32F429ZI_HRE_TEST_STAND) ||          \
     defined(_BOARD_STM32F429ZI_SKYWARD_PYXIS_AUXILIARY) || \
     defined(_BOARD_STM32F429ZI_SKYWARD_PARAFOIL) ||        \
-    defined(_BOARD_STM32F205RC_SKYWARD_CIUTI)
+    defined(_BOARD_STM32F205RC_SKYWARD_CIUTI) ||           \
+    defined(_BOARD_STM32F429ZI_SKYWARD_RIG)
 
 class EventType
 {
@@ -51,23 +52,23 @@ public:
     enum E
     {
         // These are a must on all backends -- begin
-        Default = 0,          // This actually means 'no event'
-        WindowPartialRedraw,  // At least one drawable has requested redraw
-        WindowForeground,     // Window manager moved this window to foreground
-        WindowBackground,     // Window manager moved this window to background
-        WindowQuit,           // Window manager requested the window to close
-                              // These are a must on all backends -- end
+        Default = 0,         // This actually means 'no event'
+        WindowPartialRedraw, // At least one drawable has requested redraw
+        WindowForeground,    // Window manager moved this window to foreground
+        WindowBackground,    // Window manager moved this window to background
+        WindowQuit,          // Window manager requested the window to close
+                             // These are a must on all backends -- end
 
         TouchDown = 1,
-        TouchUp   = 2,
+        TouchUp = 2,
         TouchMove = 3,
-        ButtonA   = 4  // The blue button
+        ButtonA = 4 // The blue button
     };
 
 private:
     EventType();
 };
 
-#endif  //_BOARD_STM32F429ZI_STM32F4DISCOVERY
+#endif //_BOARD_STM32F429ZI_STM32F4DISCOVERY
 
-#endif  // EVENT_TYPES_STM32F4DISCOVERY_H
+#endif // EVENT_TYPES_STM32F4DISCOVERY_H