diff --git a/mxgui/drivers/display_stm32f4discovery.cpp b/mxgui/drivers/display_stm32f4discovery.cpp index dcb340706a6f01496439d61c111834b007b98fb6..68f76f86c4d6b1994e9b05770aea55158ea19acf 100644 --- a/mxgui/drivers/display_stm32f4discovery.cpp +++ b/mxgui/drivers/display_stm32f4discovery.cpp @@ -26,67 +26,71 @@ ***************************************************************************/ #include "display_stm32f4discovery.h" -#include "miosix.h" + #include <cstdarg> +#include "miosix.h" + using namespace std; using namespace miosix; -#if defined(_BOARD_STM32F429ZI_STM32F4DISCOVERY) \ - || defined(_BOARD_STM32F429ZI_OLEDBOARD2) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_ANAKIN) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_HOMEONE) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_ROGALLINA) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_X) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_V3) \ - || defined(_BOARD_STM32F429ZI_HRE_TEST_STAND) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_PYXIS_AUXILIARY) \ - || defined(_BOARD_STM32F429ZI_PARAFOIL) - -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; +#if defined(_BOARD_STM32F429ZI_STM32F4DISCOVERY) || \ + defined(_BOARD_STM32F429ZI_OLEDBOARD2) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_ANAKIN) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_HOMEONE) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_ROGALLINA) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_X) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_V3) || \ + defined(_BOARD_STM32F429ZI_HRE_TEST_STAND) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_PYXIS_AUXILIARY) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_PARAFOIL) + +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 +// 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) +static unsigned char spi5sendRev(unsigned char c = 0) { - SPI5->DR=c; - while((SPI5->SR & SPI_SR_RXNE)==0) ; + SPI5->DR = c; + while ((SPI5->SR & SPI_SR_RXNE) == 0) + ; return SPI5->DR; } @@ -105,18 +109,18 @@ static void sendCmd(unsigned char cmd, int len, ...) delayUs(1); dcx::high(); va_list arg; - va_start(arg,len); - for(int i=0;i<len;i++) - { + va_start(arg, len); + for (int i = 0; i < len; i++) + { csx::low(); - spi5sendRev(va_arg(arg,int)); + spi5sendRev(va_arg(arg, int)); csx::high(); delayUs(1); } va_end(arg); } -void registerDisplayHook(DisplayManager& dm) +void registerDisplayHook(DisplayManager &dm) { dm.registerDisplay(&DisplayImpl::instance()); } @@ -125,7 +129,7 @@ void registerDisplayHook(DisplayManager& dm) // class DisplayImpl // -DisplayImpl& DisplayImpl::instance() +DisplayImpl &DisplayImpl::instance() { static DisplayImpl instance; return instance; @@ -135,82 +139,92 @@ void DisplayImpl::doTurnOn() { LTDC->GCR |= LTDC_GCR_LTDCEN; Thread::sleep(40); - sendCmd(0x29,0); //LCD_DISPLAY_ON + sendCmd(0x29, 0); // LCD_DISPLAY_ON } void DisplayImpl::doTurnOff() { - sendCmd(0x28,0); //LCD_DISPLAY_OFF - LTDC->GCR &=~ LTDC_GCR_LTDCEN; + sendCmd(0x28, 0); // LCD_DISPLAY_OFF + LTDC->GCR &= ~LTDC_GCR_LTDCEN; } void DisplayImpl::doSetBrightness(int brt) {} pair<short int, short int> DisplayImpl::doGetSize() const { - return make_pair(height,width); + return make_pair(height, width); } void DisplayImpl::write(Point p, const char *text) { - font.draw(*this,textColor,p,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); + font.clippedDraw(*this, textColor, p, a, b, text); } void DisplayImpl::clear(Color color) { - clear(Point(0,0),Point(width-1,height-1),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)) + 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 use memset - if(p1.x()==0 && p2.x()==width-1) + // 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 { - //Can merge lines - memset(framebuffer1+p1.y()*width,color,(p2.y()-p1.y()+1)*width*bpp); - } 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 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; + memset(ptr, color, len * bpp); + ptr += width; } } - } else { - //Can't use memset - if(p1.x()==0 && p2.x()==width-1) + } + 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++) + // 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++=color; + *ptr++ = color; + *ptr++ = color; + *ptr++ = color; + *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 (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; + for (short j = 0; j < len; j++) + *ptr++ = color; + ptr += width - len; } } } @@ -220,350 +234,401 @@ 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; + int offset = p.x() + p.y() * width; + if (offset < 0 || offset >= numPixels) + return; + *(framebuffer1 + offset) = color; } void DisplayImpl::line(Point a, Point b, Color color) { - //Horizontal line speed optimization - if(a.y()==b.y()) + // 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; + 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; } - //Vertical line speed optimization - if(a.x()==b.x()) + // Vertical line speed optimization + if (a.x() == b.x()) { - 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++) + 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; + *ptr = color; + ptr += width; } 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); + 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); + 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) +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); + 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); } -void DisplayImpl::clippedDrawImage(Point p, Point a, Point b, const ImageBase& img) +void DisplayImpl::clippedDrawImage(Point p, Point a, Point b, + const ImageBase &img) { -// if(img.getData()==0) -// { - img.clippedDraw(*this,p,a,b); + // if(img.getData()==0) + // { + img.clippedDraw(*this, p, a, b); return; -// } //else optimized version for memory-loaded images -// //TODO: optimize -// } + // } //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); + 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) + 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) + 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 invalid (dummy) iterators + this->last = pixel_iterator(); return this->last; } - //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); + // 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); - return pixel_iterator(p1,p2,d,this); + return pixel_iterator(p1, p2, d, this); } DisplayImpl::~DisplayImpl() {} DisplayImpl::DisplayImpl() - : framebuffer1(reinterpret_cast<unsigned short*>(0xd0600000)), - buffer(framebuffer1+numPixels) + : 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; + // 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; } - - while((RCC->CR & RCC_CR_PLLSAIRDY)==0) + + while ((RCC->CR & RCC_CR_PLLSAIRDY) == 0) ; - + { FastInterruptDisableLock dLock; - - scl::mode(Mode::ALTERNATE); scl::alternateFunction(5); //SPI5 - sda::mode(Mode::ALTERNATE); sda::alternateFunction(5); - csx::mode(Mode::OUTPUT); csx::high(); + + 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; + 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(); } - - 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 + + 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 + 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 + 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 + 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 + + 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 - + // 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))); + setTextColor(make_pair(Color(0xffff), Color(0x0000))); clear(black); } Color DisplayImpl::pixel_iterator::dummy; -} //namespace mxgui +} // namespace mxgui -#endif //_BOARD_STM32F429ZI_STM32F4DISCOVERY +#endif //_BOARD_STM32F429ZI_STM32F4DISCOVERY #ifdef _BOARD_STM32F469NI_STM32F469I_DISCO -namespace mxgui { +namespace mxgui +{ -//Control interface +// Control interface -//Pixel sync interface -typedef Gpio<GPIOF_BASE,10> en; +// 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) { +// 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)); + 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)); } -void longWrite(uint32_t numParams, uint32_t param0, uint8_t *pParams) { +void longWrite(uint32_t numParams, uint32_t param0, uint8_t *pParams) +{ // Command FIFO Empty - while ((DSI->GPSR & DSI_GPSR_CMDFE) == 0); - + 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)); + 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)); + } + else + { + DSI->GPDR = ((*(pParams + uicounter)) | + ((*(pParams + uicounter + 1)) << 8) | + ((*(pParams + uicounter + 2)) << 16) | + ((*(pParams + uicounter + 3)) << 24)); uicounter += 4; } } - - DSI->GHCR = (0x39 | // DSI_DCS_LONG_PKT_WRITE - (0 << 6) | // Virtual Channel Id - (((numParams+1)&0x00FF) << 8) | \ - ((((numParams+1)&0xFF00) >> 8) << 16)); + + 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 sendCmd(uint32_t numParams, uint8_t *pParams) +{ + if (numParams <= 1) + { shortWrite(pParams[0], pParams[1]); - } else { + } + else + { longWrite(numParams, pParams[numParams], pParams); } } -void registerDisplayHook(DisplayManager& dm) +void registerDisplayHook(DisplayManager &dm) { dm.registerDisplay(&DisplayImpl::instance()); } @@ -572,7 +637,7 @@ void registerDisplayHook(DisplayManager& dm) // class DisplayImpl // -DisplayImpl& DisplayImpl::instance() +DisplayImpl &DisplayImpl::instance() { static DisplayImpl instance; return instance; @@ -597,69 +662,79 @@ void DisplayImpl::doSetBrightness(int brt) {} pair<short int, short int> DisplayImpl::doGetSize() const { - return make_pair(height,width); + return make_pair(height, width); } void DisplayImpl::write(Point p, const char *text) { - font.draw(*this,textColor,p,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); + font.clippedDraw(*this, textColor, p, a, b, text); } void DisplayImpl::clear(Color color) { - clear(Point(0,0),Point(width-1,height-1),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)) + 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 use memset - if(p1.x()==0 && p2.x()==width-1) + // 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 { - //Can merge lines - memset(framebuffer1+p1.y()*width,color,(p2.y()-p1.y()+1)*width*bpp); - } 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 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; + memset(ptr, color, len * bpp); + ptr += width; } } - } else { - //Can't use memset - if(p1.x()==0 && p2.x()==width-1) + } + 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++) + // 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++=color; + *ptr++ = color; + *ptr++ = color; + *ptr++ = color; + *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 (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; + for (short j = 0; j < len; j++) + *ptr++ = color; + ptr += width - len; } } } @@ -669,119 +744,128 @@ 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; + int offset = p.x() + p.y() * width; + if (offset < 0 || offset >= numPixels) + return; + *(framebuffer1 + offset) = color; } void DisplayImpl::line(Point a, Point b, Color color) { - //Horizontal line speed optimization - if(a.y()==b.y()) + // 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; + 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; } - //Vertical line speed optimization - if(a.x()==b.x()) + // Vertical line speed optimization + if (a.x() == b.x()) { - 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++) + 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; + *ptr = color; + ptr += width; } 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); + 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); + 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) +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); + 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); } -void DisplayImpl::clippedDrawImage(Point p, Point a, Point b, const ImageBase& img) +void DisplayImpl::clippedDrawImage(Point p, Point a, Point b, + const ImageBase &img) { -// if(img.getData()==0) -// { - img.clippedDraw(*this,p,a,b); + // if(img.getData()==0) + // { + img.clippedDraw(*this, p, a, b); return; -// } //else optimized version for memory-loaded images -// //TODO: optimize -// } + // } //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); + 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); } -void DisplayImpl::update() -{ - DSI->WCR |= DSI_WCR_LTDCEN; -} +void DisplayImpl::update() { DSI->WCR |= DSI_WCR_LTDCEN; } DisplayImpl::pixel_iterator DisplayImpl::begin(Point p1, Point p2, - IteratorDirection d) + 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) + 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 invalid (dummy) iterators + this->last = pixel_iterator(); return this->last; } - //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); + // 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); - return pixel_iterator(p1,p2,d,this); + return pixel_iterator(p1, p2, d, this); } DisplayImpl::~DisplayImpl() {} @@ -790,45 +874,53 @@ 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. + /* 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 { + 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, + RGB888 = 1, + RGB565 = 2, ARGB1555 = 3, ARGB4444 = 4, - L8 = 5, - AL44 = 6, - AL88 = 7 + 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} + +// 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); - + 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); @@ -837,40 +929,80 @@ DisplayImpl::DisplayImpl() 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); - + 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; } @@ -878,140 +1010,149 @@ DisplayImpl::DisplayImpl() // 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 - + // 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); + 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); + 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); - + 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); - + 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_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 + // 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->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->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 + // 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) + // 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->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); + // 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 + // Specifies the constant alpha value LTDC_Layer1->CACR &= ~(LTDC_LxCACR_CONSTA); LTDC_Layer1->CACR = 255; - // Blending factors (constant alpha) + // Blending factors (constant alpha) LTDC_Layer1->BFCR &= ~(LTDC_LxBFCR_BF2 | LTDC_LxBFCR_BF1); LTDC_Layer1->BFCR = (0x400 | 0x5); - // Enable layer + // Enable layer LTDC_Layer1->CR |= LTDC_LxCR_LEN; - - // If needed enable dithering and color keying + + // 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 + 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 + // 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); - + 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; + 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) + // 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->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... + // 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 - + 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; @@ -1019,109 +1160,139 @@ DisplayImpl::DisplayImpl() 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->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 + // 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 + // 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->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->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 + 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); - + 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; + DSI->WCR |= DSI_WCR_DSIEN; /* End DSI configuration */ - - // Send DCS commands through the APB generic interface to configure the display + + // 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}; - + 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 + * 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] = 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 + * 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}; @@ -1160,15 +1331,16 @@ DisplayImpl::DisplayImpl() 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 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}; @@ -1178,7 +1350,7 @@ DisplayImpl::DisplayImpl() 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); @@ -1263,27 +1435,27 @@ DisplayImpl::DisplayImpl() 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(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. + // 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); - #endif - +#endif + sendCmd(0, (uint8_t *)ShortRegData40); sendCmd(0, (uint8_t *)ShortRegData41); sendCmd(0, (uint8_t *)ShortRegData42); @@ -1292,34 +1464,26 @@ DisplayImpl::DisplayImpl() 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->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. + // 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; @@ -1330,6 +1494,6 @@ DisplayImpl::DisplayImpl() 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 25d3c80c78f334879bc722463b6fd964c77c64ba..d261c445c32280dfaa981bfad23082b775db37a5 100644 --- a/mxgui/drivers/display_stm32f4discovery.h +++ b/mxgui/drivers/display_stm32f4discovery.h @@ -28,41 +28,44 @@ #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 - -#if defined(_BOARD_STM32F429ZI_STM32F4DISCOVERY) \ - || defined(_BOARD_STM32F429ZI_OLEDBOARD2) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_ANAKIN) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_HOMEONE) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_ROGALLINA) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_X) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_V3) \ - || defined(_BOARD_STM32F429ZI_HRE_TEST_STAND) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_PYXIS_AUXILIARY) \ - || defined(_BOARD_STM32F429ZI_PARAFOIL) \ - || defined(_BOARD_STM32F205RC_SKYWARD_CIUTI) +#define DISPLAY_STM32F4DISCOVERY_H + +#if defined(_BOARD_STM32F429ZI_STM32F4DISCOVERY) || \ + defined(_BOARD_STM32F429ZI_OLEDBOARD2) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_ANAKIN) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_HOMEONE) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_ROGALLINA) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_X) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_V3) || \ + defined(_BOARD_STM32F429ZI_HRE_TEST_STAND) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_PYXIS_AUXILIARY) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_PARAFOIL) || \ + defined(_BOARD_STM32F205RC_SKYWARD_CIUTI) #include <config/mxgui_settings.h> -#include "display.h" -#include "point.h" + +#include <algorithm> +#include <cstdio> +#include <cstring> + #include "color.h" +#include "display.h" #include "font.h" #include "image.h" #include "iterator_direction.h" -#include "misc_inst.h" #include "line.h" -#include <cstdio> -#include <cstring> -#include <algorithm> +#include "misc_inst.h" +#include "point.h" -namespace mxgui { +namespace mxgui +{ -//This display is 16 bit per pixel, check that the color depth is properly -//configured +// This display is 16 bit per pixel, check that the color depth is properly +// configured #ifndef MXGUI_COLOR_DEPTH_16_BIT #error The ILI9341 driver requires a color depth of 16bit per pixel #endif @@ -74,7 +77,7 @@ 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. @@ -85,14 +88,14 @@ public: * 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 */ @@ -103,7 +106,7 @@ public: * \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; + void write(Point p, const char* text) override; /** * Write part of text to the display @@ -114,7 +117,7 @@ public: * \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; + void clippedWrite(Point p, Point a, Point b, const char* text) override; /** * Clear the Display. The screen will be filled with the desired color @@ -160,14 +163,14 @@ public: * \param length length of colors array. * p.x()+length must be <= display.width() */ - void scanLine(Point p, const Color *colors, unsigned short length) override; - + 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; - + Color* getScanLineBuffer() override; + /** * Draw the content of the last getScanLineBuffer() on an horizontal line * on the screen. @@ -193,7 +196,8 @@ public: * \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; + void clippedDrawImage(Point p, Point a, Point b, + const ImageBase& img) override; /** * Draw a rectangle (not filled) with the desired color @@ -202,7 +206,7 @@ public: * \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. @@ -216,26 +220,28 @@ public: * 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) {} + 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) + pixel_iterator& operator=(Color color) { - *dataPtr=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) + // 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; + ctr = 0; + dataPtr += sIncr; } return *this; } @@ -244,35 +250,35 @@ public: * Compare two pixel_iterators for equality. * They are equal if they point to the same location. */ - bool operator== (const pixel_iterator& itr) + bool operator==(const pixel_iterator& itr) { - return this->dataPtr==itr.dataPtr; + 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) + bool operator!=(const pixel_iterator& itr) { - return this->dataPtr!=itr.dataPtr; + return this->dataPtr != itr.dataPtr; } /** * \return a reference to this. */ - pixel_iterator& operator* () { return *this; } + pixel_iterator& operator*() { return *this; } /** * \return a reference to this. Does not increment pixel pointer. */ - pixel_iterator& operator++ () { return *this; } + pixel_iterator& operator++() { return *this; } /** * \return a reference to this. Does not increment pixel pointer. */ - pixel_iterator& operator++ (int) { return *this; } - + pixel_iterator& operator++(int) { return *this; } + /** * Must be called if not all pixels of the required window are going * to be written. @@ -288,33 +294,36 @@ public: * \param disp Display we're associated */ pixel_iterator(Point start, Point end, IteratorDirection direction, - DisplayImpl *disp) : ctr(0), dataPtr(disp->framebuffer1) + 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) + // 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; + 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 - - short aIncr; ///< Adjacent increment - int sIncr; ///< Step increment - Color *dataPtr; ///< Pointer to framebuffer - - static Color dummy; ///< Invalid iterators write here + 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 + + static Color dummy; ///< Invalid iterators write here - friend class DisplayImpl; //Needs access to ctor + friend class DisplayImpl; // Needs access to ctor }; /** @@ -334,7 +343,7 @@ public: * begin() */ pixel_iterator end() const { return last; } - + /** * Destructor */ @@ -346,51 +355,55 @@ private: * 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; - #elif defined MXGUI_ORIENTATION_HORIZONTAL || \ - defined MXGUI_ORIENTATION_VERTICAL_MIRRORED || \ - defined MXGUI_ORIENTATION_HORIZONTAL_MIRRORED - #error unsupported orientation - #else - #error No orientation defined - #endif + +#if defined MXGUI_ORIENTATION_VERTICAL + 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 +#error unsupported orientation +#else +#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 + 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 #include <config/mxgui_settings.h> -#include "display.h" -#include "point.h" + +#include <algorithm> +#include <cstdio> +#include <cstring> + #include "color.h" +#include "display.h" #include "font.h" #include "image.h" #include "iterator_direction.h" -#include "misc_inst.h" #include "line.h" -#include <cstdio> -#include <cstring> -#include <algorithm> +#include "misc_inst.h" +#include "point.h" -namespace mxgui { +namespace mxgui +{ -//This display is 16 bit per pixel, check that the color depth is properly -//configured +// This display is 16 bit per pixel, check that the color depth is properly +// configured #ifndef MXGUI_COLOR_DEPTH_16_BIT #error The OTM8009A driver requires a color depth of 16bit per pixel #endif @@ -402,7 +415,7 @@ 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. @@ -413,14 +426,14 @@ public: * 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 */ @@ -431,7 +444,7 @@ public: * \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; + void write(Point p, const char* text) override; /** * Write part of text to the display @@ -442,7 +455,7 @@ public: * \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; + void clippedWrite(Point p, Point a, Point b, const char* text) override; /** * Clear the Display. The screen will be filled with the desired color @@ -488,14 +501,14 @@ public: * \param length length of colors array. * p.x()+length must be <= display.width() */ - void scanLine(Point p, const Color *colors, unsigned short length) override; - + 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; - + Color* getScanLineBuffer() override; + /** * Draw the content of the last getScanLineBuffer() on an horizontal line * on the screen. @@ -521,7 +534,8 @@ public: * \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; + void clippedDrawImage(Point p, Point a, Point b, + const ImageBase& img) override; /** * Draw a rectangle (not filled) with the desired color @@ -530,13 +544,13 @@ public: * \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. @@ -550,26 +564,28 @@ public: * 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) {} + 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) + pixel_iterator& operator=(Color color) { - *dataPtr=color; + *dataPtr = color; + + // This is to move to the adjacent pixel + dataPtr += aIncr; - //This is to move to the adjacent pixel - dataPtr+=aIncr; - - //This is the step move to the next horizontal/vertical line - if(++ctr>=endCtr) + // This is the step move to the next horizontal/vertical line + if (++ctr >= endCtr) { - ctr=0; - dataPtr+=sIncr; + ctr = 0; + dataPtr += sIncr; } return *this; } @@ -578,35 +594,35 @@ public: * Compare two pixel_iterators for equality. * They are equal if they point to the same location. */ - bool operator== (const pixel_iterator& itr) + bool operator==(const pixel_iterator& itr) { - return this->dataPtr==itr.dataPtr; + 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) + bool operator!=(const pixel_iterator& itr) { - return this->dataPtr!=itr.dataPtr; + return this->dataPtr != itr.dataPtr; } /** * \return a reference to this. */ - pixel_iterator& operator* () { return *this; } + pixel_iterator& operator*() { return *this; } /** * \return a reference to this. Does not increment pixel pointer. */ - pixel_iterator& operator++ () { return *this; } + pixel_iterator& operator++() { return *this; } /** * \return a reference to this. Does not increment pixel pointer. */ - pixel_iterator& operator++ (int) { return *this; } - + pixel_iterator& operator++(int) { return *this; } + /** * Must be called if not all pixels of the required window are going * to be written. @@ -622,33 +638,36 @@ public: * \param disp Display we're associated */ pixel_iterator(Point start, Point end, IteratorDirection direction, - DisplayImpl *disp) : ctr(0), dataPtr(disp->framebuffer1) + 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) + // 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.x()+1-start.x(); - aIncr=1; - sIncr=disp->getWidth()-endCtr; - } else { - endCtr=end.y()+1-start.y(); - aIncr=disp->getWidth(); - sIncr=-aIncr*endCtr+1; + 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 - - short aIncr; ///< Adjacent increment - int sIncr; ///< Step increment - Color *dataPtr; ///< Pointer to framebuffer - - static Color dummy; ///< Invalid iterators write here + 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 - friend class DisplayImpl; //Needs access to ctor + static Color dummy; ///< Invalid iterators write here + + friend class DisplayImpl; // Needs access to ctor }; /** @@ -668,7 +687,7 @@ public: * begin() */ pixel_iterator end() const { return last; } - + /** * Destructor */ @@ -680,32 +699,33 @@ private: * 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; - #elif defined MXGUI_ORIENTATION_HORIZONTAL - 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 - #else - #error No orientation defined - #endif + +#if defined MXGUI_ORIENTATION_VERTICAL + 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; +#elif defined MXGUI_ORIENTATION_VERTICAL_MIRRORED || \ + defined MXGUI_ORIENTATION_HORIZONTAL_MIRRORED +#error unsupported orientation +#else +#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 + 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 020c3e6bd4f3089db1e71ae1c710492515bdb28d..fd97c7c2bb4c1bf8d81a6e0a63c016e4f1a89d3c 100644 --- a/mxgui/drivers/event_stm32f4discovery.cpp +++ b/mxgui/drivers/event_stm32f4discovery.cpp @@ -11,7 +11,7 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * - * * + * * * As a special exception, if other files instantiate templates or use * * macros or inline functions from this file, or you compile this file * * and link it with other works to produce a work based on this file, * @@ -28,33 +28,33 @@ #include <config/mxgui_settings.h> -#if (defined(_BOARD_STM32F4DISCOVERY) \ - || defined(_BOARD_STM32F429ZI_STM32F4DISCOVERY) \ - || defined(_BOARD_STM32F429ZI_OLEDBOARD2) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_ANAKIN) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_HOMEONE) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_ROGALLINA) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_X) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_V3)) \ - || defined(_BOARD_STM32F429ZI_HRE_TEST_STAND) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_PYXIS_AUXILIARY) \ - || defined(_BOARD_STM32F429ZI_PARAFOIL) \ - || defined(_BOARD_STM32F205RC_SKYWARD_CIUTI) \ - && defined(MXGUI_LEVEL_2) +#if (defined(_BOARD_STM32F4DISCOVERY) || \ + defined(_BOARD_STM32F429ZI_STM32F4DISCOVERY) || \ + defined(_BOARD_STM32F429ZI_OLEDBOARD2) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_ANAKIN) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_HOMEONE) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_ROGALLINA) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_X) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_V3)) || \ + defined(_BOARD_STM32F429ZI_HRE_TEST_STAND) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_PYXIS_AUXILIARY) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_PARAFOIL) || \ + defined(_BOARD_STM32F205RC_SKYWARD_CIUTI) && defined(MXGUI_LEVEL_2) + +#include <algorithm> #include "event_stm32f4discovery.h" -#include "miosix.h" #include "kernel/scheduler/scheduler.h" +#include "miosix.h" #include "util/software_i2c.h" -#include <algorithm> using namespace std; using namespace miosix; -static Thread *waiting=0; -static volatile bool irq=false; -static volatile int flag=0; +static Thread *waiting = 0; +static volatile bool irq = false; +static volatile int flag = 0; /** * Touchscreen interrupt @@ -71,13 +71,16 @@ void __attribute__((naked)) EXTI15_10_IRQHandler() */ void __attribute__((used)) EXTI15_10HandlerImpl() { - EXTI->PR=EXTI_PR_PR15; - - irq=true; - if(waiting==0) return; + EXTI->PR = EXTI_PR_PR15; + + irq = true; + if (waiting == 0) + return; waiting->IRQwakeup(); - if(waiting->IRQgetPriority()>Thread::IRQgetCurrentThread()->IRQgetPriority()) Scheduler::IRQfindNextThread(); - waiting=0; + if (waiting->IRQgetPriority() > + Thread::IRQgetCurrentThread()->IRQgetPriority()) + Scheduler::IRQfindNextThread(); + waiting = 0; } /** @@ -95,40 +98,43 @@ void __attribute__((naked)) EXTI0_IRQHandler() */ void __attribute__((used)) EXTI0HandlerImpl() { - EXTI->PR=EXTI_PR_PR0; - - if(waiting==0) return; + EXTI->PR = EXTI_PR_PR0; + + if (waiting == 0) + return; waiting->IRQwakeup(); - if(waiting->IRQgetPriority()>Thread::IRQgetCurrentThread()->IRQgetPriority()) + if (waiting->IRQgetPriority() > + Thread::IRQgetCurrentThread()->IRQgetPriority()) Scheduler::IRQfindNextThread(); - waiting=0; + waiting = 0; } -namespace mxgui { +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 + 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 }; /** @@ -154,15 +160,17 @@ static void stmpe811writeReg(unsigned char reg, unsigned char val) */ static void stmpe811readReg(unsigned char reg, int n, unsigned char *result) { - if(n<=0) return; + 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(); + for (int i = 0; i < n - 1; i++) + result[i] = stmpe811::recvWithAck(); + result[n - 1] = stmpe811::recvWithNack(); stmpe811::sendStop(); } @@ -171,8 +179,8 @@ static void stmpe811readReg(unsigned char reg, int n, unsigned char *result) */ static void touchFifoClear() { - stmpe811writeReg(FIFO_STA,0x01); //RESET FIFO - stmpe811writeReg(FIFO_STA,0x00); //RESET FIFO + stmpe811writeReg(FIFO_STA, 0x01); // RESET FIFO + stmpe811writeReg(FIFO_STA, 0x00); // RESET FIFO } /** @@ -181,113 +189,123 @@ static void touchFifoClear() static Point getTouchData() { unsigned char ctrl; - stmpe811readReg(TSC_CTRL,1,&ctrl); - if((ctrl & 0x80)==0) + stmpe811readReg(TSC_CTRL, 1, &ctrl); + if ((ctrl & 0x80) == 0) { - flag=0; - return Point(-1,-1); + flag = 0; + return Point(-1, -1); } - if(flag==0) + if (flag == 0) { - flag=1; - return Point(-1,-1); + 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); + 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) { { FastInterruptDisableLock dLock; - if(eventQueue.IRQput(e)==false) return; + if (eventQueue.IRQput(e) == false) + return; } - if(eventCallback) eventCallback(); + if (eventCallback) + eventCallback(); } static void waitForTouchOrButton() { { FastInterruptDisableLock dLock2; - if(irq==false) + if (irq == false) { - waiting=Thread::IRQgetCurrentThread(); - while(waiting) - { + waiting = Thread::IRQgetCurrentThread(); + while (waiting) + { Thread::IRQwait(); FastInterruptEnableLock eLock(dLock2); - Thread::yield(); + 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(;;) + bool aPrev = false; + bool tPrev = false; + Point pOld; + for (;;) { waitForTouchOrButton(); - //Check buttons - if(buttonA::value()==1) + // 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; + if (aPrev == false) + callback(Event(EventType::ButtonA, EventDirection::DOWN)); + aPrev = true; } - //Check touchscreen - Point p=getTouchData(); - if(p.x()>=0) //Is someone touching the screen? + else { - //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) + 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) + 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)); + callback(Event(EventType::TouchUp, pOld, EventDirection::UP)); } - tPrev=false; + tPrev = false; } } } @@ -304,48 +322,50 @@ InputHandlerImpl::InputHandlerImpl() interrupt::mode(Mode::INPUT); stmpe811::init(); } - - //To let the I2C voltages settle + + // To let the I2C voltages settle Thread::sleep(5); - - stmpe811writeReg(SYS_CTRL1,0x02); //SOFT_RESET=1 + + stmpe811writeReg(SYS_CTRL1, 0x02); // SOFT_RESET=1 Thread::sleep(10); - stmpe811writeReg(SYS_CTRL1,0x00); //SOFT_RESET=0 + 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 + 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 + NVIC_SetPriority(EXTI15_10_IRQn, 15); // Low priority - //impostiamo l'interrupt del bottone + // 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 + 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); + // 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() @@ -359,16 +379,17 @@ Event InputHandlerImpl::popEvent() { FastInterruptDisableLock dLock; Event result; - if(eventQueue.isEmpty()==false) eventQueue.IRQget(result); + if (eventQueue.isEmpty() == false) + eventQueue.IRQget(result); return result; } -function<void ()> InputHandlerImpl::registerEventCallback(function<void ()> cb) +function<void()> InputHandlerImpl::registerEventCallback(function<void()> cb) { - swap(eventCallback,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 14baefa9ee768e45f298299aea0222d467a20371..d11275f44b6511b6b521ca93fffb0498158c5013 100644 --- a/mxgui/drivers/event_stm32f4discovery.h +++ b/mxgui/drivers/event_stm32f4discovery.h @@ -28,29 +28,31 @@ #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> + #include "level2/input.h" #ifndef EVENT_STM32F4DISCOVERY_H -#define EVENT_STM32F4DISCOVERY_H +#define EVENT_STM32F4DISCOVERY_H -#if defined(_BOARD_STM32F4DISCOVERY) \ - || defined(_BOARD_STM32F429ZI_STM32F4DISCOVERY) \ - || defined(_BOARD_STM32F429ZI_OLEDBOARD2) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_ANAKIN) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_HOMEONE) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_ROGALLINA) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_X) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_V3) \ - || defined(_BOARD_STM32F429ZI_HRE_TEST_STAND) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_PYXIS_AUXILIARY) \ - || defined(_BOARD_STM32F429ZI_PARAFOIL) \ - || defined(_BOARD_STM32F205RC_SKYWARD_CIUTI) +#if defined(_BOARD_STM32F4DISCOVERY) || \ + defined(_BOARD_STM32F429ZI_STM32F4DISCOVERY) || \ + defined(_BOARD_STM32F429ZI_OLEDBOARD2) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_ANAKIN) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_HOMEONE) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_ROGALLINA) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_X) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_V3) || \ + defined(_BOARD_STM32F429ZI_HRE_TEST_STAND) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_PYXIS_AUXILIARY) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_PARAFOIL) || \ + defined(_BOARD_STM32F205RC_SKYWARD_CIUTI) -namespace mxgui { +namespace mxgui +{ /** * Implementation class to handle events in the Mp3v2 backend @@ -70,22 +72,23 @@ public: * 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 - * + * 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); + 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 07a0ea8600c1c0b17378ab9c8b94b1ea20329369..8688bdcf5f797b5579b074f8f0029a6c105b59bd 100644 --- a/mxgui/drivers/event_types_stm32f4discovery.h +++ b/mxgui/drivers/event_types_stm32f4discovery.h @@ -26,21 +26,21 @@ ***************************************************************************/ #ifndef EVENT_TYPES_STM32F4DISCOVERY_H -#define EVENT_TYPES_STM32F4DISCOVERY_H +#define EVENT_TYPES_STM32F4DISCOVERY_H -#if defined(_BOARD_STM32F4DISCOVERY) \ - || defined(_BOARD_STM32F429ZI_STM32F4DISCOVERY) \ - || defined(_BOARD_STM32F429ZI_OLEDBOARD2) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_ANAKIN) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_HOMEONE) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_ROGALLINA) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_X) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_V3) \ - || defined(_BOARD_STM32F429ZI_HRE_TEST_STAND) \ - || defined(_BOARD_STM32F429ZI_SKYWARD_PYXIS_AUXILIARY) \ - || defined(_BOARD_STM32F429ZI_PARAFOIL) \ - || defined(_BOARD_STM32F205RC_SKYWARD_CIUTI) +#if defined(_BOARD_STM32F4DISCOVERY) || \ + defined(_BOARD_STM32F429ZI_STM32F4DISCOVERY) || \ + defined(_BOARD_STM32F429ZI_OLEDBOARD2) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_ANAKIN) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_HOMEONE) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_ROGALLINA) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_X) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_V3) || \ + defined(_BOARD_STM32F429ZI_HRE_TEST_STAND) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_PYXIS_AUXILIARY) || \ + defined(_BOARD_STM32F429ZI_SKYWARD_PARAFOIL) || \ + defined(_BOARD_STM32F205RC_SKYWARD_CIUTI) class EventType { @@ -48,22 +48,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 - - TouchDown=1, - TouchUp=2, - TouchMove=3, - ButtonA=4 //The blue button + 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, + TouchMove = 3, + 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 diff --git a/mxgui/level2/input.cpp b/mxgui/level2/input.cpp index 9936a16f8f38df27249703e1d100fa0d71a4349a..0dc9427fcc9d8c576acfa2a1c9545da2c06fafdb 100644 --- a/mxgui/level2/input.cpp +++ b/mxgui/level2/input.cpp @@ -29,18 +29,19 @@ #ifdef MXGUI_LEVEL_2 -#include "drivers/event_qt.h" -#include "drivers/event_win.h" #include "drivers/event_mp3v2.h" -#include "drivers/event_strive.h" -#include "drivers/event_stm3210e-eval.h" +#include "drivers/event_qt.h" #include "drivers/event_redbull_v2.h" #include "drivers/event_sony-newman.h" +#include "drivers/event_stm3210e-eval.h" #include "drivers/event_stm32f4discovery.h" +#include "drivers/event_strive.h" +#include "drivers/event_win.h" using namespace std; -namespace mxgui { +namespace mxgui +{ // // class InputHandler @@ -53,23 +54,17 @@ InputHandler& InputHandler::instance() return singleton; } -Event InputHandler::getEvent() -{ - return pImpl->getEvent(); -} +Event InputHandler::getEvent() { return pImpl->getEvent(); } -Event InputHandler::popEvent() -{ - return pImpl->popEvent(); -} +Event InputHandler::popEvent() { return pImpl->popEvent(); } -function<void ()> InputHandler::registerEventCallback(function<void ()> cb) +function<void()> InputHandler::registerEventCallback(function<void()> cb) { return pImpl->registerEventCallback(cb); } -InputHandler::InputHandler(InputHandlerImpl *impl) : pImpl(impl) {} +InputHandler::InputHandler(InputHandlerImpl* impl) : pImpl(impl) {} -} //namespace mxgui +} // namespace mxgui -#endif //MXGUI_LEVEL_2 +#endif // MXGUI_LEVEL_2