<?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>mikestirling.co.uk &#187; AVR32</title>
	<atom:link href="http://mikestirling.co.uk/category/avr32/feed/" rel="self" type="application/rss+xml" />
	<link>http://mikestirling.co.uk</link>
	<description></description>
	<lastBuildDate>Sun, 18 Sep 2011 11:19:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Mono STN display on an AVR32 AP7000</title>
		<link>http://mikestirling.co.uk/2009/02/mono-stn-display-on-an-avr32-ap7000/</link>
		<comments>http://mikestirling.co.uk/2009/02/mono-stn-display-on-an-avr32-ap7000/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 21:04:50 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[AVR32]]></category>
		<category><![CDATA[Embedded]]></category>
		<category><![CDATA[Home Stuff]]></category>

		<guid isPermaLink="false">http://mikestirling.co.uk/wordpress/?p=5</guid>
		<description><![CDATA[I&#8217;ve had a few controllerless QVGA (320&#215;240) mono LCD modules lying around for a while looking for some use.  These are fairly easy to get going with a low-end microcontroller using an external controller IC like the SED1335, but that&#8217;s another story.  I&#8217;d been thinking about doing some sort of integrated home automation project, and [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_11" class="wp-caption alignleft" style="width: 310px"><img class="size-medium wp-image-11" title="NGW100 STN" src="http://mikestirling.co.uk/wordpress/wp-content/uploads/2009/02/stn_lcd-300x187.jpg" alt="AVR32 NGW100 Driving an STN LCD Module" width="300" height="187" /><p class="wp-caption-text">AVR32 NGW100 Driving an STN LCD Module</p></div>
<p style="text-align: justify;">I&#8217;ve had a few controllerless QVGA (320&#215;240) mono LCD modules lying around for a while looking for some use.  These are fairly easy to get going with a low-end microcontroller using an external controller IC like the SED1335, but that&#8217;s another story.  I&#8217;d been thinking about doing some sort of integrated home automation project, and since this would need a user interface and I happened to have an NGW100 going spare, getting one of these displays to run on the AP7000&#8242;s integrated LCD controller seemed like a nice idea.</p>
<p style="text-align: justify;">The NGW100 only has a 16-bit interface to its already relatively slow DRAM, so driving a high-res colour LCD from it leads to a fairly obvious slowdown.  For this application a mono display would be adequate, and easier to drive, requiring only a 4-bit data bus, the 3 clocks and a GPIO to power up the drivers.  The LCDC has no problem driving an STN panel, although I had to deviate from the datasheet in one area to get it to work &#8211; more on that later.</p>
<p style="text-align: justify;"><span id="more-5"></span>The particular panel (a Samsung UG32F05) requires a 5 V logic supply, but also calls for around -20 V for the LCD drive.  In the prototype this was generated using a nasty buck-boost converter thrown together from a 555 timer and a MOSFET, but this is not recommended (use a real switch-mode controller)!  The 5 V was derived with a linear regulator connected to the NGW100&#8242;s 2-pin power header, and the signal lines from the LCDC were connected up directly (D0-D3 straight through, PCLK to XSCL/CL2, HSYNC to LP/CL1 and VSYNC to DIN/FLM).  Because powering an STN display without the proper clocks applied can cause damage the module provides a /DISPOFF connection, which was driven from a spare GPIO on the NGW100.  Normally this would be connected to the LCDC&#8217;s PWR output, but this is shared with the SD card detect input on the NGW, and the application would be using this.  The pinout of the module goes like this:</p>
<table style="text-align: justify;" border="0">
<tbody>
<tr>
<td>Pin</td>
<td>Name</td>
<td>Function</td>
</tr>
<tr>
<td>1</td>
<td>FLM</td>
<td>Frame scan start (to LCDC_VSYNC) &#8211; P7 pin 29</td>
</tr>
<tr>
<td>2</td>
<td>M</td>
<td>Backplane sync signal (not used on this module, but connect to LCDC_MODE) &#8211; P7 pin 26</td>
</tr>
<tr>
<td>3</td>
<td>CL1</td>
<td>Data latch clock (to LCDC_HSYNC) &#8211; P7 pin 27</td>
</tr>
<tr>
<td>4</td>
<td>CL2</td>
<td>Data shift clock (to LCDC_PCLK) &#8211; P7 pin 28</td>
</tr>
<tr>
<td>5</td>
<td>/DISPOFF</td>
<td>Display inhibit (to GPIO) &#8211; P7 pin 5</td>
</tr>
<tr>
<td>6</td>
<td>D0</td>
<td>Display data input (to LCDC_D[0]) &#8211; P7 pin 1</td>
</tr>
<tr>
<td>7</td>
<td>D1</td>
<td>Display data input (to LCDC_D[1]) &#8211; P7 pin 2</td>
</tr>
<tr>
<td>8</td>
<td>D2</td>
<td>Display data input (to LCDC_D[2]) &#8211; P7 pin 3</td>
</tr>
<tr>
<td>9</td>
<td>D3</td>
<td>Display data input (to LCDC_D[3]) &#8211; P7 pin 4</td>
</tr>
<tr>
<td>10</td>
<td>Vdd</td>
<td>5V supply</td>
</tr>
<tr>
<td>11</td>
<td>Vss</td>
<td>0V supply</td>
</tr>
<tr>
<td>12</td>
<td>Vee</td>
<td>LCD supply (typically -20V)</td>
</tr>
<tr>
<td>13</td>
<td>Vo</td>
<td>Contrast (potential divider between Vee and Vss)</td>
</tr>
<tr>
<td>14</td>
<td>FG</td>
<td>Frame ground</td>
</tr>
</tbody>
</table>
<p style="text-align: justify;">To get the display working from Linux (I started from a vanilla 2.6.28.1 kernel) I created a copy of the evklcd10x.c board support module, added it to Kconfig and modified it to suit the parameters of the new LCD.  The fb_videomode structure was set up as follows:</p>
<ul style="text-align: justify;">
<li>refresh = 75</li>
<li>xres = 320, yres = 240</li>
<li>pixclock = KHZ2PICOS(1500)</li>
<li>left_margin = 1, right_margin = 1</li>
<li>upper_margin = 0, lower_margin = 0</li>
<li>hsync_len = 2, vsync_len = 1</li>
<li>sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT</li>
<li>vmode = FB_VMODE_NONINTERLACED</li>
</ul>
<p style="text-align: justify;">This gives a refresh rate of around 75 Hz, although this is mis-reported by fbset.  The settings in the fb_monspecs structure are not that critical (it seems).  I set the frequency ranges based on the quoted timing data for the display.  More important is the atmel_lcdfb_info data, which was set up like this:</p>
<ul style="text-align: justify;">
<li>default_bpp =1</li>
<li>default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN</li>
<li>default_lcdcon2 = ATMEL_LCDC_DISTYPE_STNMONO | ATMEL_LCDC_SCANMOD_SINGLE | ATMEL_LCDC_IFWIDTH_4 | ATMEL_LCDC_INVVD_INVERTED</li>
<li>guard_time = 2</li>
<li>default_monspecs = fb_monspecs_structure</li>
<li>atmel_lcdfb_power_control = lcd_power_control_function</li>
</ul>
<p style="text-align: justify;">The power control callback function is called by the driver after the controller has been set up and the timing signals are valid.  This is used to control the GPIO pin connected to the /DISPOFF input of the panel.  It is trivial, and along with an updated initialisation function it looks like this:</p>
<blockquote style="text-align: justify;"><p>#define LCD_nDISPOFF    GPIO_PIN_PE(7)</p>
<p>static void lcd_power_control_function(int on)<br />
{<br />
printk(KERN_INFO &#8220;Turning LCD power %s\n&#8221;,on ? &#8220;on&#8221;:&#8221;off&#8221;);<br />
gpio_set_value(LCD_nDISPOFF,on);<br />
}</p>
<p>static int __init lcd_board_init(void)<br />
{<br />
at32_add_device_lcdc(0, &amp;lcd_board_lcdc_data,<br />
fbmem_start, fbmem_size,<br />
/* IO port mask */<br />
ATMEL_LCDC(PE, DATA0)  | ATMEL_LCDC(PE, DATA1)  |<br />
ATMEL_LCDC(PE, DATA2)  | ATMEL_LCDC(PE, DATA3)    |<br />
ATMEL_LCDC(PE, MODE) |<br />
ATMEL_LCDC_CONTROL);<br />
at32_select_gpio(LCD_nDISPOFF,AT32_GPIOF_OUTPUT); /* LCD /DISPOFF */<br />
return 0;<br />
}</p></blockquote>
<p style="text-align: justify;">That should be it.  However, it turned out that the AP7000 was generating 1/4 the number of clocks per line that it should have been even considering the 4-bit interface (20 clocks instead of 80).  Although I established this fact prior to connecting the module, visually this results in a display of vertical stripes.  In the datasheet it states that for STN mono mode, HOZVAL (found in the LCDFRMCFG register) is equal to (number of horizontal pixels / interface width) &#8211; 1.  The Linux driver calculates HOZVAL based on the display type, but does it by the book and chooses a value of 79 (320/4-1).  It was found that going against the datasheet and setting HOZVAL=319 solved the problem.  This was implemented by patching atmel_lcdfb.c so that hozval_linesz = info-&gt;var.xres (around line 577).  Please feel free to point out where I have screwed up here, or if this is indeed a mistake in the databook!</p>
<p style="text-align: justify;">Once the board boots you can use <em>fbset -depth 4</em> to switch to 16 shade greyscale mode.  The photo above shows the Qt text editor demo running in this mode.  Certain shades of grey exhibit a slight flicker, but for an STN display the image is pretty reasonable.</p>
]]></content:encoded>
			<wfw:commentRss>http://mikestirling.co.uk/2009/02/mono-stn-display-on-an-avr32-ap7000/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

