<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TFT Archives - Digital Me</title>
	<atom:link href="https://ba0sh1.com/tag/tft/feed/" rel="self" type="application/rss+xml" />
	<link>https://ba0sh1.com/tag/tft/</link>
	<description>Electronics, Computers at leisure time</description>
	<lastBuildDate>Mon, 11 Jul 2022 04:58:03 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.1.1</generator>
	<item>
		<title>First sight into ESP32</title>
		<link>https://ba0sh1.com/2015/12/26/first-signt-into-esp32/</link>
					<comments>https://ba0sh1.com/2015/12/26/first-signt-into-esp32/#comments</comments>
		
		<dc:creator><![CDATA[Baoshi]]></dc:creator>
		<pubDate>Fri, 25 Dec 2015 16:32:18 +0000</pubDate>
				<category><![CDATA[Project]]></category>
		<category><![CDATA[ESP31]]></category>
		<category><![CDATA[ESP32]]></category>
		<category><![CDATA[TFT]]></category>
		<guid isPermaLink="false">https://www.ba0sh1.com/?p=1151</guid>

					<description><![CDATA[<p>So I am one of the 200 lucky bastards who receive the Espressif ESP32 beta units. It arrives in a nicely printed packaging which resembles very much like a jewel box. And...</p>
<p>The post <a rel="nofollow" href="https://ba0sh1.com/2015/12/26/first-signt-into-esp32/">First sight into ESP32</a> appeared first on <a rel="nofollow" href="https://ba0sh1.com">Digital Me</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>So I am one of the 200 lucky bastards who receive the Espressif ESP32 beta units. It arrives in a nicely printed packaging which resembles very much like a jewel box. And the item inside is really a piece of jewelry.</p>
<p><span id="more-1151"></span></p>
<figure id="attachment_1152" aria-describedby="caption-attachment-1152" style="width: 640px" class="wp-caption aligncenter"><img decoding="async" loading="lazy" class="wp-image-1152 size-full" src="https://ba0sh1.com/wp-content/uploads/2015/12/3df35-esp31-box.png" alt="ESP31 packaging" width="640" height="480" srcset="https://ba0sh1.com/wp-content/uploads/2015/12/3df35-esp31-box.png 640w, https://ba0sh1.com/wp-content/uploads/2015/12/3df35-esp31-box-300x225.png 300w" sizes="(max-width: 640px) 100vw, 640px" /><figcaption id="caption-attachment-1152" class="wp-caption-text">ESP31 packaging</figcaption></figure>
<p>Appearantly the breakout board, &#8220;ESP_Module_Testboard&#8221;, is little bit too wide for breadboard use, (leaving one row on each side), I decided to make a quick development board. The end result looks like this.</p>
<figure id="attachment_1154" aria-describedby="caption-attachment-1154" style="width: 800px" class="wp-caption aligncenter"><img decoding="async" loading="lazy" class="wp-image-1154 size-full" src="https://ba0sh1.com/wp-content/uploads/2015/12/c1fb2-esp31-devboard.png" alt="ESP31 development board" width="800" height="600" srcset="https://ba0sh1.com/wp-content/uploads/2015/12/c1fb2-esp31-devboard.png 800w, https://ba0sh1.com/wp-content/uploads/2015/12/c1fb2-esp31-devboard-300x225.png 300w, https://ba0sh1.com/wp-content/uploads/2015/12/c1fb2-esp31-devboard-768x576.png 768w" sizes="(max-width: 800px) 100vw, 800px" /><figcaption id="caption-attachment-1154" class="wp-caption-text">ESP31 development board</figcaption></figure>
<p>Some notes about the board:</p>
<ul>
<li>Pin &#8220;EN&#8221; has a 10k pull-up resistor. The reset button pulls &#8220;EN&#8221; down. ESP31 does not come with a RESET pin, it seems EN does the same.</li>
<li>Pin &#8220;IO0&#8221; has a 10k pull-up resistor. The &#8220;IO0&#8221; pin pulls it down. Low level on IO0 during reset allows the ESP31 to enter programming mode. This is very much the same as ESP8266. I am not sure if the pull-up resistor is needed because it seems there is one built-in. Nevertheless I just put one for safety reason.</li>
<li>The red board is a FTDI USB-Serial converter. The board is set to 3.3V I/O. The orange color jumper wire from FTDI board is to get 5V power from USB, feed through an AMS1117-3.3 to power the ESP31 module. I used a 100uF output tantinium capacitor. It seems this setup is not good enough. I&#8217;ll explain later.</li>
</ul>
<p>With the board on hand, it is now time to setup development environment. There are excellent guides at <a href="http://www.instructables.com/id/Beginners-ESP32-Guide-to-Assembly-Testing/" target="_blank" rel="noopener">http://www.instructables.com/id/Beginners-ESP32-Guide-to-Assembly-Testing/</a>, as well as LadyAda&#8217;s live show <a href="https://www.youtube.com/watch?v=HCGHb0OVz1s" target="_blank" rel="noopener">https://www.youtube.com/watch?v=HCGHb0OVz1s</a></p>
<p>New year is around the corner and I am so eager to continue my new year greeting video &#8220;series&#8221;. It natually envolves into this:</p>
<p><iframe loading="lazy" title="Merry Christmas from ESP31" width="640" height="360" src="https://www.youtube.com/embed/6SR7anr_Xi4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<p>And the source code too: <a href="https://github.com/baoshi/ESP32-XMAS" target="_blank" rel="noopener">https://github.com/baoshi/ESP32-XMAS</a></p>
<p>Again some notes about the source code:</p>
<ul>
<li>The TFT screen contains 128&#215;160 pixels, at 16bit/pixel it amounts to 40kB/frame, or 320kbits/frame. The SPI bus is running at 13.3MHz, that works out around 40fps. Due to some coding overhead the fastest I can achieve is about 25fps. But again becaused of the latency at WiFi side, I&#8217;m currently running the screen at 10fps. That is only 400kB/s for WiFi traffic, which is significantly slower than the claimed 140Mb/s rated speed. Of course there is huge room for improvement at software side.</li>
<li>The ESP31 seems to take more power than it&#8217;s predecessor ESP8266. The above mentioned AMS1117-3.3 cannot provide enough juice. The phenomenon is garbaged output from serial port, lost WiFi connection, or failed with exception after reset. It could be a thermal issue. I ended up using a lab power supply then all the problems are gone. My supply registered 170mA when WiFi is active. Of course it includes the LCD comsumption. I will do some further investigation at a later time.</li>
<li>I encouontered some WiFi abnormalities that the connection speed slows down significantly from time to time. Reset the chip will resolve the issue. For the time being I havn&#8217;t fully dig into it.</li>
<li>Other than these, ESP31 (ESP32 Beta) and the current SDK (1.1.0) seems quite stable.</li>
</ul>
<p>To all my readers or viewers I take this oppotunity to wish you a Merry Christmas and Happy New Year. See you next year.</p>
<p>The post <a rel="nofollow" href="https://ba0sh1.com/2015/12/26/first-signt-into-esp32/">First sight into ESP32</a> appeared first on <a rel="nofollow" href="https://ba0sh1.com">Digital Me</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ba0sh1.com/2015/12/26/first-signt-into-esp32/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>FlappyDuino &#8211; Arduino Day 2014 celebration</title>
		<link>https://ba0sh1.com/2014/03/29/flappyduino-arduino-day-2014-celebration/</link>
					<comments>https://ba0sh1.com/2014/03/29/flappyduino-arduino-day-2014-celebration/#comments</comments>
		
		<dc:creator><![CDATA[Baoshi]]></dc:creator>
		<pubDate>Fri, 28 Mar 2014 16:01:25 +0000</pubDate>
				<category><![CDATA[Diary]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Distance Sensor]]></category>
		<category><![CDATA[TFT]]></category>
		<guid isPermaLink="false">https://www.ba0sh1.com/?p=915</guid>

					<description><![CDATA[<p>March 29 2014 is Arduino&#8217;s 10 years birthday, also the World&#8217;s Arduino Day. In conjunction with the global celebration, SG Makers in partnership with IDA is organizing a whole series of events for Singapore Arduino lovers....</p>
<p>The post <a rel="nofollow" href="https://ba0sh1.com/2014/03/29/flappyduino-arduino-day-2014-celebration/">FlappyDuino &#8211; Arduino Day 2014 celebration</a> appeared first on <a rel="nofollow" href="https://ba0sh1.com">Digital Me</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>March 29 2014 is Arduino&#8217;s 10 years birthday, also the World&#8217;s Arduino Day. In conjunction with the global celebration, <a title="SGMakers" href="http://sgmakers.com/" target="_blank" rel="noopener">SG Makers</a> in partnership with <a title="IDA" href="http://www.ida.gov.sg/" target="_blank" rel="noopener">IDA</a> is organizing a whole series of events for Singapore Arduino lovers. And I was invited to showcase some Arduino projects.<span id="more-915"></span></p>
<p>Being not too much dedicated to Arduino, I have to quickly put up something demo-able. And since I&#8217;ve been playing with display devices often, I decided to make an Arduino graphics project. After two weeks, I finished my first Arduino game &#8212; FlappyDuino (thanks SG Makers William Hooi for inventing the name).</p>
<p>The project hardware is really simple. It only contains an Arduino Pro Mini, a ST7735 SPI TFT panel and a distance sensor (Sharp GP2Y0A21YK0F, which I used before in <a title="Project Crystal (Part 1)" href="https://www.ba0sh1.com/project-crystal-part-1/" target="_blank" rel="noopener">Project Crystal</a>). I have put the KiCAD schematic, PCB and Arduino sketch code at <a title="FlappyDuino" href="https://github.com/baoshi/FlappyDuino" target="_blank" rel="noopener">https://github.com/baoshi/FlappyDuino</a>. Feel free to download and criticise my code.</p>
<p>Lazy me also think a video is worth thousands of words.</p>
<p><iframe loading="lazy" title="FlappyDuino" width="640" height="360" src="https://www.youtube.com/embed/uOS7CkUbVWU?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<p>Happy Birthday Arduino!</p>
<p>The post <a rel="nofollow" href="https://ba0sh1.com/2014/03/29/flappyduino-arduino-day-2014-celebration/">FlappyDuino &#8211; Arduino Day 2014 celebration</a> appeared first on <a rel="nofollow" href="https://ba0sh1.com">Digital Me</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ba0sh1.com/2014/03/29/flappyduino-arduino-day-2014-celebration/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>HOWTO: Write a display driver for SEGGER emWin</title>
		<link>https://ba0sh1.com/2014/01/30/write-a-display-driver-for-emwin/</link>
					<comments>https://ba0sh1.com/2014/01/30/write-a-display-driver-for-emwin/#comments</comments>
		
		<dc:creator><![CDATA[Baoshi]]></dc:creator>
		<pubDate>Thu, 30 Jan 2014 12:10:26 +0000</pubDate>
				<category><![CDATA[Project]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[emWin]]></category>
		<category><![CDATA[GCC]]></category>
		<category><![CDATA[LCD]]></category>
		<category><![CDATA[SEGGER]]></category>
		<category><![CDATA[STM32]]></category>
		<category><![CDATA[TFT]]></category>
		<guid isPermaLink="false">https://www.ba0sh1.com/?p=826</guid>

					<description><![CDATA[<p>One lucky day you wake up to find your dream of creating sophisticated graphics user interface for MCU projects comes true, because STMicroelectronics has released a free version of SEGGER emWin for...</p>
<p>The post <a rel="nofollow" href="https://ba0sh1.com/2014/01/30/write-a-display-driver-for-emwin/">HOWTO: Write a display driver for SEGGER emWin</a> appeared first on <a rel="nofollow" href="https://ba0sh1.com">Digital Me</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>One lucky day you wake up to find your dream of creating sophisticated graphics user interface for MCU projects comes true, because STMicroelectronics has released a free version of SEGGER emWin for STM32 line of ARM controllers. But your excitement is quickly balanced by the frustration that your favourite LCD panel is not supported. That is a typical day of mine, and my favourite LCD is a 2.6&#8243; 400&#215;240 IPS panel, model TFT1P5971-E by Truly. This post is about how to make the LCD usable with emWin.<span id="more-826"></span></p>
<h3>Background information</h3>
<p>STemWin is available at <a href="http://www.st.com/web/en/catalog/tools/PF259225">http://www.st.com/web/en/catalog/tools/PF259225</a> (Do not complain if the link does not work. ST did great SEO job by changing URL regularly. Google is your friend&#8230;). Basically STMicroelectronics licensed it from <a title="emWin" href="http://www.segger.com/emwin.html" target="_blank" rel="noopener">SEGGER</a> and distribute the library in binary form. At the time I&#8217;m writing this post STemWin is at verison 1.1, corresponding to SEGGER emWin v5.22. The license term for STemWin is pretty obscure according to my English standard. But as far as I can interpret the usage of STemWin with STM32 micro controllers is free for both commercial or non-commercial cases. SEGGER emWin is also available from <a title="NXP emWin" href="http://www.lpcware.com/content/project/emwin-graphics-library" target="_blank" rel="noopener">NXP</a>, carrying a similar license, or from <a title="MDK-ARM" href="http://www.keil.com/arm" target="_blank" rel="noopener">Keil MDK-ARM</a>. The later requires a professional license which is far deeper than my pocket.</p>
<p>The Truly LCD costs as low as $4  from <a title="Truly 2.6 IPS panel" href="http://item.taobao.com/item.htm?spm=a1z09.5.0.0.bCWTBo&amp;id=26389548543" target="_blank" rel="noopener">taobao</a>. I suspect it is some sort of left-overs from mobile phone manufacture. The seller told me he has 10K+ ready stock. The LCD controller is Himax HX8352C. I erroneously assume that emWin supports HX8352 and HX8352B so it should support HX8352C, until I wire up the LCD and the garbage churns out.</p>
<p>As a sincere RTFM user I looked into STemWin documentation. There is a chapter &#8220;29.7.20 GUIDRV_Template &#8211; Template for a new driver&#8221;, roughly 1/3 page long, talking about how to write a display driver. Don&#8217;t blame SEGGER or ST for not providing more details. SEGGER charges €1,100 for the source code of a driver. They need to make a profitable business after all. And the 1/3 page paragraph proves to be very useful indeed.</p>
<p>For impatients or who want to criticise my code straight away, please jump to <a href="#guidrv_hx8352c">GUIDRV_HX8352C</a></p>
<h3><span style="font-size: 1.17em; line-height: 1.5em;">Bare metal LCD driver</span></h3>
<p>Before interfacing the LCD panel with emWin, it is always necessary to make the panel work with bare metal code first. My testing hardware is on a STM32F103RCT6 minimalism board. The reason I choose a 64-pin RCT6 instead of a 100-pin monster is that I wanted to test GPIO to LCD driver performance. If a 100-pin device is used, we can drive LCD using FSMC port and it will be much easier. My LCD wiring is as follows :</p>
<figure id="attachment_846" aria-describedby="caption-attachment-846" style="width: 396px" class="wp-caption aligncenter"><a class="thumbnail" href="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/12/3e2cb-hx8352c-wiring.png"><img decoding="async" loading="lazy" class="size-full wp-image-846" src="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/12/3e2cb-hx8352c-wiring.png" alt="HX8352C wiring diagram" width="396" height="167" srcset="https://ba0sh1.com/wp-content/uploads/2013/12/3e2cb-hx8352c-wiring.png 396w, https://ba0sh1.com/wp-content/uploads/2013/12/3e2cb-hx8352c-wiring-300x127.png 300w" sizes="(max-width: 396px) 100vw, 396px" /></a><figcaption id="caption-attachment-846" class="wp-caption-text">HX8352C wiring diagram</figcaption></figure>
<p>We&#8217;ll need to implement the following functions for hardware accessing:</p>


<div class="hcb_wrap"><pre class="prism line-numbers lang-c" data-lang="C"><code>void lcdReset(void);
void lcdInit(void);
void lcdWriteData(uint16_t data);
void lcdWriteReg(uint16_t data);
uint16_t lcdReadData(void);</code></pre></div>


<p></p>
<p>As the name suggests, these functions handles LCD reset, LCD initialization and read/write data/register from/to the LCD controller. Implementation of these functions is as simple as following the LCD datasheet. My actual implementation is within the GitHub repository linked below. A simple main() function to test the LCD interface:</p>
<p></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-c" data-lang="C">// Note: This code assumes 16-bit parallel interface and HX8352C controller.<br />void main(void)<br />{<br />    lcdInit(); // Internally calls lcdReset()<br />    lcdWriteReg(0x0002);<br />    lcdWriteData(0x0000);<br />    lcdWriteReg(0x0003);<br />    lcdWriteData(0x0000);<br />    lcdWriteReg(0x0006);<br />    lcdWriteData(0x0000);<br />    lcdWriteReg(0x0007);<br />    lcdWriteData(0x000);<br />    // Write data<br />    lcdWriteReg(0x0022);<br />    lcdWriteData(0xFFFF);<br />    while(1) {}<br />}</pre>
</div>
<p></p>
<p></p>
<p>This shall display a white dot at coordinate (0, 0). If it works, congratulations you&#8217;re halfway towards success. If it doesn&#8217;t, look into the controller datasheet and debug your software/hardware.</p>
<h3>Looking into a template driver</h3>
<p>STemWin comes with some sample codes for various ST development boards, but display driver is not one of them. Since the limited documentation actually tells us the sample driver is called GUIDRV_Template, try Google &#8220;GUIDRV_Template.c&#8221; will lead you to the same file at <a title="GUIDRV_Template.c" href="https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Attachments/34674/GUIDRV_Template.c" target="_blank" rel="noopener">ST forum</a>. (I try not to host the file here as I&#8217;m not sure about its license.) Another way to obtain this file is download the trial version of MDK-ARM, as bonus you&#8217;ll have all other emWin samples.</p>
<p>Now look at the template driver. The only thing it exposes to the public is a structure <em>GUIDRV_Template_API</em>, which consists a number of function pointers:</p>
<p></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-c" data-lang="C"><code>/*********************************************************************
*
* GUI_DEVICE_API structure
*/
const GUI_DEVICE_API GUIDRV_Template_API = {
    //
    // Data
    //
    DEVICE_CLASS_DRIVER,
    //
    // Drawing functions
    //
    _DrawBitmap,
    _DrawHLine,
    _DrawVLine,
    _FillRect,
    _GetPixelIndex,
    _SetPixelIndex,
    _XorPixel,
    //
    // Set origin
    //
    _SetOrg,
    //
    // Request information
    //
    _GetDevFunc,
    _GetDevProp,
    _GetDevData,
    _GetRect,
};</code></pre>
</div>
<p></p>
<p>The documentation actually tells us that among all the functions , we only need to adapt the _GetPixelIndex and _SetPixelIndex. That is more or less correct. I show you how.</p>
<h3>Quick and Dirty emWin driver</h3>
<p>Go to GUIDRV_Template.c, find _GetPixelIndex and _SetPixelIndex. SEGGER already put the comments there saying &#8220;Write into hardware &#8230; Adapt to your system&#8221;, so adapt them as follows</p>
<p></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-c" data-lang="C"><code>// Note: Pseudo code below, adapt to your implementation
static void _SetPixelIndex(GUI_DEVICE *pDevice, int x, int y, int color)
{
   //Draw_Pixel(x,y,PixelIndex);
   // Move cursor
   lcdWriteReg(0x0002);
   lcdWriteData(HIBYTE(x));
   lcdWriteReg(0x0003);
   lcdWriteData(LOBYTE(x));
   lcdWriteReg(0x0006);
   lcdWriteData(HIBYTE(y));
   lcdWriteReg(0x0007);
   lcdWriteData(LOBYTE(y));
   // Write data
   lcdWriteReg(0x0022);
   lcdWriteData(color);
}

static unsigned int _GetPixelIndex(GUI_DEVICE *pDevice, int x, int y)
{
    U16 reads[3];
    //PixelIndex = ili9320_GetPoint(x,y);
    // Move cursor
    lcdWriteReg(0x0002);
    lcdWriteData(HIBYTE(x));
    lcdWriteReg(0x0003);
    lcdWriteData(LOBYTE(x));
    lcdWriteReg(0x0006);
    lcdWriteData(HIBYTE(y));
    lcdWriteReg(0x0007);
    lcdWriteData(LOBYTE(y));
    // Start read data
    lcdWriteReg(0x0022);
    lcdReadData(reads[0]);
    lcdReadData(reads[1]);
    lcdReadData(reads[2]);
    // Pack RGB into RGB565, see HX8352C datasheet for 16-bit interface read
    PixelIndex = ((reads[1] &amp; 0xF800) | ((reads[1] &amp; 0x00FC) &lt;&lt; 3) | (reads[2] &gt;&gt; 11));
}</code></pre>
</div>
<p></p>
<p>To let emWin use the template driver, LCDConf.c must be provided. Sample LCDConf.c can be found inside STemW</p>
<p>in folder, modify LCD_X_Config like this:</p>
<p></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-c" data-lang="C"><code>....
//
// Physical display size
//
#define XSIZE_PHYS 240
#define YSIZE_PHYS 400
....
void LCD_X_Config(void)
{
    ....
    pDevice = GUI_DEVICE_CreateAndLink(GUIDRV_Template_API, GUICC_565, 0, 0);
    ....
}

....

int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData)
{
    ....
    switch (Cmd)
    {
    case LCD_X_INITCONTROLLER:
    {
        lcdInit();
        return 0;
    }
    ....
    }
    ....
}</code></pre>
</div>
<p></p>
<p>Added other necessary files (GUIConf.c, various header files, etc) into project, write a test main as</p>
<p></p>
<div class="hcb_wrap">
<pre class="prism line-numbers lang-c" data-lang="C"><code>void main(void)
{
    ....
    // Setup STM32 system (clock, PLL and Flash configuration)
    SystemInit();
    // Necessary for STemWin to authenticate that it is runing on STM32 processor
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);
    GUI_Init();
    GUI_DispString("Hello world!");
    ....
}</code></pre>
</div>
<p></p>
<p>And you&#8217;re golden.</p>
<figure id="attachment_884" aria-describedby="caption-attachment-884" style="width: 480px" class="wp-caption aligncenter"><img decoding="async" loading="lazy" class=" wp-image-884 " src="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2014/01/97700-hx8352c-devboard.jpg" alt="HX8352C emWin development board" width="480" height="360" srcset="https://ba0sh1.com/wp-content/uploads/2014/01/97700-hx8352c-devboard.jpg 600w, https://ba0sh1.com/wp-content/uploads/2014/01/97700-hx8352c-devboard-300x225.jpg 300w" sizes="(max-width: 480px) 100vw, 480px" /><figcaption id="caption-attachment-884" class="wp-caption-text">HX8352C emWin development board</figcaption></figure>
<h3>Re-organisation code</h3>
<p>Thanks for following me till this point. I must apologise that I did not prepare any ready examples  that you can modify on top. I deem providing such an example not necessary because all what we&#8217;ve been doing is &#8220;quick and dirty&#8221;. If you look into the SEGGER provided drivers and examples, you will find that the hardware interfacing, the LCD drawing primitives and the LCD panel configuration are nicely segregated into different modules. This enables SEGGER to distribute the LCD drawing primitives as hardware independent binary &#8220;drivers&#8221; without restrict the actual panel and hardware connectivity. Although I have no intention to distribute the custom driver in binary form, adopting such architecture will ensure optimal readability and portability.</p>
<p>Let&#8217;s go back look at the <em>GUIDRV_Template_API</em> structure. We have already implemented the drawing functions. The remaining 4 functions, namely <em>_GetDevFunc</em>, <em>_GetDevProp</em>, <em>_GetDevData</em>, <em>_GetRect</em>, are critical for emWin core to query necessary information from the driver. The reference implementation in GUIDRV_Template.c involves a lot of runtime settings, e.g., VRAM, panel dimension and orientation, so that user is able to configure the binary driver using external code. Since I&#8217;m working on a single panel and I&#8217;m open source,  these settings can be hard-coded (SEGGER called it compile-time). With some debug tracing it is not hard to figure out how these functions are called by emWin, and a calling digram of emWin initialization is as below:</p>
<p></p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="1024" height="632" src="https://ba0sh1.com/wp-content/uploads/2014/01/89023-emwin-init-1024x632.png" alt="emWin initialization" class="wp-image-875" srcset="https://ba0sh1.com/wp-content/uploads/2014/01/89023-emwin-init-1024x632.png 1024w, https://ba0sh1.com/wp-content/uploads/2014/01/89023-emwin-init-300x185.png 300w, https://ba0sh1.com/wp-content/uploads/2014/01/89023-emwin-init-768x474.png 768w, https://ba0sh1.com/wp-content/uploads/2014/01/89023-emwin-init-1536x948.png 1536w, https://ba0sh1.com/wp-content/uploads/2014/01/89023-emwin-init-1568x967.png 1568w, https://ba0sh1.com/wp-content/uploads/2014/01/89023-emwin-init.png 1731w" sizes="(max-width: 1024px) 100vw, 1024px" />
<figcaption>emWin initialization</figcaption>
</figure>
<p></p>
<p>I have organized the functions as SEGGER&#8217;s other binary driver, with GUIDRV_HX8352C.c handles all the controller interfacing, LCDConf.c links controller module with the hardware interface, and HX8352C_GPIO handles GPIO hardware access to the LCD controller.</p>
<h3>Driver optimization</h3>
<p>Now look at the template driver&#8217;s drawing functions. We already have <em>_GetPixelIndex</em> and <em>_SetPixelIndex</em>. The remaining 4 functions, <em>_DrawBitmap</em>,  <em>_DrawHLine</em>,  <em>_DrawVLine</em> and  <em>_FillRect</em>, are implemented as repeatedly calling  <em>_GetPixelIndex</em> and <em>_SetPixelIndex,</em> which is very inefficient. The correct way of writing these functions is to utilize the LCD controller&#8217;s hardware clipping mechanism, and fill GRAM directly. <em><br /></em></p>
<p>A lower level of optimization targets at improving GPIO driving efficiency. For this part I have referenced Andy Brown&#8217;s excellent <a title="stm32plus" href="http://andybrown.me.uk/wk/tag/stm32plus/" target="_blank" rel="noopener">stm32plus </a>library. Most GPIO driving functions are implemented as ARM assembly to ensure correct timing. Andy further introduced a way of fast GPIO writing by utilizing data already on the databus and toggle WR signal repeatedly. This is very useful when doing block filling or line drawing. When all these optimization I have archived 8,846,000 pixel/second filling rate with 72MHz processor clock.</p>
<p><iframe loading="lazy" title="emWin display driver demo" width="640" height="360" src="https://www.youtube.com/embed/LOHcaCOj9TM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<p>Performance can be further enhanced with a higher pin count STM32 processor using FSMC port access.</p>
<h3><a name="guidrv_hx8352c"></a><br />GUIDRV_HX8352C</h3>
<p>The source for this driver is available at <a title="HX8352C-GPIO-emWin" href="https://github.com/baoshi/HX8352C-GPIO-emWin" target="_blank" rel="noopener">GitHub</a>. Several notes:</p>
<ol>
<li>Demo application is from SEGGER.</li>
<li>The building environment is Eclipse + GNU Make + ARM GCC, as described in my <a title="Opensource STM32 development" href="https://www.ba0sh1.com/opensource-stm32-development/" target="_blank" rel="noopener">previous blog</a>.</li>
<li> The STM32 development board is from <a title="STM32F103RBT6 Dev Board" href="http://item.taobao.com/item.htm?id=35595258574" target="_blank" rel="noopener">taobao</a>. I choose this because it uses 4 wire SWD interface, saving many I/O pins.</li>
<li>Theoretically the driver supports emWin &#8220;multi-layer&#8221; or &#8220;multi-display&#8221;. But I have not tested it yet.</li>
<li>Panel orientation is hard-coded in LCDConf.h, to maintain the compatibility with other emWin drivers.</li>
<li>Due to the limited LCD GRAM and RAM in STM32 processor, not all emWin examples are usable. The video below shows those I&#8217;ve been able run on a STM32F103RCT6.</li>
</ol>


<p></p>
<p>The post <a rel="nofollow" href="https://ba0sh1.com/2014/01/30/write-a-display-driver-for-emwin/">HOWTO: Write a display driver for SEGGER emWin</a> appeared first on <a rel="nofollow" href="https://ba0sh1.com">Digital Me</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ba0sh1.com/2014/01/30/write-a-display-driver-for-emwin/feed/</wfw:commentRss>
			<slash:comments>25</slash:comments>
		
		
			</item>
	</channel>
</rss>
