<?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>STM32 Archives - Digital Me</title>
	<atom:link href="https://ba0sh1.com/tag/stm32/feed/" rel="self" type="application/rss+xml" />
	<link>https://ba0sh1.com/tag/stm32/</link>
	<description>Electronics, Computers at leisure time</description>
	<lastBuildDate>Sun, 10 Jul 2022 10:01:30 +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>TrueSTUDIO STM32 project to GCC Makefile converter</title>
		<link>https://ba0sh1.com/2015/04/30/truestudio-stm32-project-to-gcc-makefile-converter/</link>
					<comments>https://ba0sh1.com/2015/04/30/truestudio-stm32-project-to-gcc-makefile-converter/#comments</comments>
		
		<dc:creator><![CDATA[Baoshi]]></dc:creator>
		<pubDate>Thu, 30 Apr 2015 09:25:07 +0000</pubDate>
				<category><![CDATA[Project]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[GCC]]></category>
		<category><![CDATA[Makefile]]></category>
		<category><![CDATA[STM32]]></category>
		<guid isPermaLink="false">https://www.ba0sh1.com/?p=1087</guid>

					<description><![CDATA[<p>Since I wrote the STM32CubeMX to Makefile converter, a lot of people have been helping to improve the project. Thanks! Meanwhile I also heard a lot of complaints about the quality of STM32Cube...</p>
<p>The post <a rel="nofollow" href="https://ba0sh1.com/2015/04/30/truestudio-stm32-project-to-gcc-makefile-converter/">TrueSTUDIO STM32 project to GCC Makefile converter</a> appeared first on <a rel="nofollow" href="https://ba0sh1.com">Digital Me</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Since I wrote the <a title="STM32CubeMX GCC Makefile project" href="https://www.ba0sh1.com/stm32cubemx-gcc-makefile/" target="_blank" rel="noopener">STM32CubeMX to Makefile converter</a>, a lot of people have been helping to improve the project. Thanks! Meanwhile I also heard a lot of complaints about the quality of STM32Cube codes, for example, the thread <a title="ST's (STM32Cube) software ecosystem is terrible - how can we fix it?" href="http://www.eevblog.com/forum/microcontrollers/st's-(stm32cube)-software-ecosystem-is-terrible-how-can-we-fix-it/" target="_blank" rel="noopener">here</a>. Although I believe STM32Cube&#8217;s quality will eventually improve, at the moment there are still applications for the good old &#8220;Standard Peripheral Library&#8221; and other ST middlewares. Therefore I wrote another program, that converts most of ST&#8217;s example project into Makefile project.<span id="more-1087"></span></p>
<p>The new utility, named ST2Makefile, is available on <a title="ST2Makefile" href="https://github.com/baoshi/ST2Makefile" target="_blank" rel="noopener">https://github.com/baoshi/ST2Makefile</a></p>
<p>My limited testing shows it works for most example projects in ST&#8217;s library package, as well as STM32CubeMX exported projects. One thing needs tweaking could be that some ST&#8217;s example project contains duplicated source files. If you receive error message such as &#8220;Symbol already defined in XXX&#8221; during linking, please check the SRCS section for any duplicated source entries.</p>
<p>The usage is changed a little since CubeMX2Makefile.py, now you should run:</p>
<p>[code light=&#8221;true&#8221;]<br />
ST2Makefile.py &lt;TrueSTUDIO project location&gt;<br />
[/code]</p>
<p>where you can identify TrueSTUDIO project location by locating &#8220;.project&#8221; and &#8220;.cproject&#8221; files inside it.</p>
<p>&nbsp;</p>
<p>As usual, some useful resources:</p>
<h3>Useful links</h3>
<p>ST2Makefile: <a title="ST2Makefile" href="https://github.com/baoshi/ST2Makefile" target="_blank" rel="noopener">https://github.com/baoshi/ST2Makefile</a><br />
ARM GCC: <a title="https://launchpad.net/gcc-arm-embedded" href="https://launchpad.net/gcc-arm-embedded" target="_blank" rel="noopener">https://launchpad.net/gcc-arm-embedded</a></p>
<p>My packaged GNU Make for Win32: <a title="GNU Make Win32" href="https://ba0sh1com.files.wordpress.com/2020/09/2c1c9-make.zip" target="_blank" rel="noopener">https://ba0sh1com.files.wordpress.com/2020/09/2c1c9-make.zip</a></p>
<p>The post <a rel="nofollow" href="https://ba0sh1.com/2015/04/30/truestudio-stm32-project-to-gcc-makefile-converter/">TrueSTUDIO STM32 project to GCC Makefile converter</a> appeared first on <a rel="nofollow" href="https://ba0sh1.com">Digital Me</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ba0sh1.com/2015/04/30/truestudio-stm32-project-to-gcc-makefile-converter/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>STM32CubeMX GCC Makefile project</title>
		<link>https://ba0sh1.com/2015/02/23/stm32cubemx-gcc-makefile/</link>
					<comments>https://ba0sh1.com/2015/02/23/stm32cubemx-gcc-makefile/#comments</comments>
		
		<dc:creator><![CDATA[Baoshi]]></dc:creator>
		<pubDate>Sun, 22 Feb 2015 18:15:48 +0000</pubDate>
				<category><![CDATA[Project]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[GCC]]></category>
		<category><![CDATA[Makefile]]></category>
		<category><![CDATA[STM32]]></category>
		<category><![CDATA[STM32Cube]]></category>
		<category><![CDATA[STM32CubeMX]]></category>
		<guid isPermaLink="false">https://www.ba0sh1.com/?p=1062</guid>

					<description><![CDATA[<p>Writing peripheral initialization code is probably the most tedious work in embedded development. It always successfully stops me from starting a new project. I believe engineers at STMicroelectronics share the same pain. Therefore...</p>
<p>The post <a rel="nofollow" href="https://ba0sh1.com/2015/02/23/stm32cubemx-gcc-makefile/">STM32CubeMX GCC Makefile project</a> appeared first on <a rel="nofollow" href="https://ba0sh1.com">Digital Me</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Writing peripheral initialization code is probably the most tedious work in embedded development. It always successfully stops me from starting a new project. I believe engineers at STMicroelectronics share the same pain. Therefore they created <a title="STM32Cube" href="http://www.st.com/stm32cube" target="_blank" rel="noopener">STM32Cube</a> firmware and STM32CubeMX graphical configuration tool, which turns numerous key strokes and page flips into just a few mouse clicks. STM32CubeMX is free software, but the initialization code it generates require compiler tools carrying hefty price tags, IARARM, Keil ARM-MDK, and Atollic TrueSTUDIO, to name the few. Fair enough these compilers do offer free editions with limited functionality. But I still prefer unrestricted, free tool that is easily scale-able for my current and future projects. Just like the GNU Make and ARM GCC toolchain I described in <a title="Opensource STM32 development" href="https://www.ba0sh1.com/opensource-stm32-development/" target="_blank" rel="noopener">Opensource STM32 development</a>.</p>
<p><span id="more-1062"></span></p>
<h2><span style="color:#ff0000;">UPDATE</span></h2>
<p><span style="color:#ff0000;">Always get update from https://github.com/baoshi/CubeMX2Makefile The code is now based on SW4STM32 project output. Thanks various contributors to make this possible.</span></p>
<p>Deprived off electronics lab back in Singapore, a Chinese new year holiday here in Shanghai home is perfect for some software projects. I have little exposure with Python but after two days of Googling (through VPN) and copy/paste, a crude CubeMX2Makefile utility is ready, available at https://github.com/baoshi/CubeMX2Makefile (OOP aficionados please forgive my spaghetti styled code. It works is it?)</p>
<p>As the name suggests, the program converts STM32CubeMX project into a GNU Makefile. Here is a mini-HOWTO:</p>
<ol>
<ol>
<li>Create a STM32CubeMX project, configure pins, peripherals and MiddleWare, then edit project settings as follows: <span style="color:#ff0000;">(choose SW4STM32 instead of TrueStudio in the picture below)</span>
<figure id="attachment_1065" aria-describedby="caption-attachment-1065" style="width: 600px" class="wp-caption aligncenter"><a class="thumbnail" href="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2015/02/897a8-stm32cubemx_project_setting.png" target="_blank" rel="noopener"><img decoding="async" class="wp-image-1065" src="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2015/02/897a8-stm32cubemx_project_setting.png?w=1024&#038;h=512" alt="STM32CubeMX project settings" width="600" height="300" srcset="https://ba0sh1.com/wp-content/uploads/2015/02/897a8-stm32cubemx_project_setting.png 1220w, https://ba0sh1.com/wp-content/uploads/2015/02/897a8-stm32cubemx_project_setting-300x150.png 300w, https://ba0sh1.com/wp-content/uploads/2015/02/897a8-stm32cubemx_project_setting-1024x512.png 1024w, https://ba0sh1.com/wp-content/uploads/2015/02/897a8-stm32cubemx_project_setting-768x384.png 768w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption id="caption-attachment-1065" class="wp-caption-text">STM32CubeMX project settings</figcaption></figure>
<p>Make sure the Tool/IDE selection is TrueSTUDIO 4.3.1 (as of STM32CubeMX 4.6.0), and note down the &#8220;Toolchain Folder Location&#8221;. I found it necessary to empty the old &#8220;Toolchain Folder&#8221; before each code generation, otherwise the project file just keep growing regardless of settings (this could be a bug in STM32CubeMX). See <a href="#update">update</a> below.</li>
<li>Download the project from the Github repo below, extract files to a folder, say &#8220;C:CubeMX2Makefile&#8221;. Install Python 2.7 Win32 from www.python.org
<p>[code light=&#8221;true&#8221;]<br />
c:CubeMX2Makefile&gt;dir /b<br />
.gitattributes<br />
.gitignore<br />
CubeMX2Makefile.py<br />
CubeMX2Makefile.tpl<br />
readme.md<br />
[/code]</p>
</li>
<li>From command prompt, execute CubeMX2Makefile.py, e.g,
<p>[code light=&#8221;true&#8221;]<br />
c:CubeMX2Makefile&gt;CubeMX2Makefile.py R:411ProjTestF4<br />
File created: R:411ProjTestF4Makefile<br />
[/code]</p>
</li>
<li>Cd into &#8220;Toolchain Folder Locaiton&#8221;, make project, i.e.,
<p>[code light=&#8221;true&#8221;]<br />
R:411ProjTestF4&gt;make<br />
&#8230;<br />
arm-none-eabi-size build/TestF4.elf<br />
 text data bss dec hex filename<br />
 5876 12 1056 6944 1b20 build/TestF4.elf<br />
arm-none-eabi-objcopy -O ihex build/TestF4.elf build/TestF4.hex<br />
[/code]</p>
<p>Refer to <a title="Command line tools" href="https://www.ba0sh1.com/opensource-stm32-development/#commandlinetools" target="_blank" rel="noopener">blog</a> and below links for ARM GCC and make utility installation. It will be much easier to import the Makefile project into Eclipse CDT for code editing and debugging.</li>
</ol>
</ol>
<h3>Useful links</h3>
<p>CubeMX2Makefile: <a title="https://github.com/baoshi/CubeMX2Makefile" href="https://github.com/baoshi/CubeMX2Makefile" target="_blank" rel="noopener">https://github.com/baoshi/CubeMX2Makefile</a></p>
<p>STM32Cube: <a title="http://www.st.com/stm32cube" href="http://www.st.com/stm32cube" target="_blank" rel="noopener">http://www.st.com/stm32cube</a></p>
<p>ARM GCC: <a title="https://launchpad.net/gcc-arm-embedded" href="https://launchpad.net/gcc-arm-embedded" target="_blank" rel="noopener">https://launchpad.net/gcc-arm-embedded</a></p>
<p>My packaged GNU Make for Win32: <a title="GNU Make Win32" href="https://ba0sh1com.files.wordpress.com/2020/09/2c1c9-make.zip" target="_blank" rel="noopener">https://ba0sh1com.files.wordpress.com/2020/09/2c1c9-make.zip</a></p>
<p><a name="update"></a></p>
<p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://ba0sh1.com/2015/02/23/stm32cubemx-gcc-makefile/">STM32CubeMX GCC Makefile project</a> appeared first on <a rel="nofollow" href="https://ba0sh1.com">Digital Me</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ba0sh1.com/2015/02/23/stm32cubemx-gcc-makefile/feed/</wfw:commentRss>
			<slash:comments>36</slash:comments>
		
		
			</item>
		<item>
		<title>HOWTO: Use STM32 SPI half duplex mode</title>
		<link>https://ba0sh1.com/2014/05/31/howto-use-stm32-spi-half-duplex-mode/</link>
					<comments>https://ba0sh1.com/2014/05/31/howto-use-stm32-spi-half-duplex-mode/#comments</comments>
		
		<dc:creator><![CDATA[Baoshi]]></dc:creator>
		<pubDate>Fri, 30 May 2014 16:11:19 +0000</pubDate>
				<category><![CDATA[Project]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[SPI]]></category>
		<category><![CDATA[STM32]]></category>
		<guid isPermaLink="false">https://www.ba0sh1.com/?p=929</guid>

					<description><![CDATA[<p>I&#8217;ve got my hands onto some STM32F030F4P6 ARM-Cortex M0 processors. Though touted as &#8220;32 cents 32-bit micro&#8221;, it is not that inexpensive from DigiKey in one-off quantity ($1.45). However it is still cheaper...</p>
<p>The post <a rel="nofollow" href="https://ba0sh1.com/2014/05/31/howto-use-stm32-spi-half-duplex-mode/">HOWTO: Use STM32 SPI half duplex mode</a> appeared first on <a rel="nofollow" href="https://ba0sh1.com">Digital Me</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>I&#8217;ve got my hands onto some STM32F030F4P6 ARM-Cortex M0 processors. Though touted as &#8220;32 cents 32-bit micro&#8221;, it is not that inexpensive from DigiKey in one-off quantity ($1.45). However it is still cheaper than ATmegas and offers 3 times the performance. The chip comes in 20-pin TSSOP package. Limited pins require much more thoughts when assigning pin function. For example, using 3-pin half-duplex SPI instead of 4-pin full-duplex SPI saves me 1 very precious GPIO pin. <span id="more-929"></span> It should be noted that not all SPI slave devices support half duplex mode, and most devices will not mention half-duplex mode in the datasheets. Generally, a SPI slave device supports half duplex SPI mode if:</p>
<figure id="attachment_932" aria-describedby="caption-attachment-932" style="width: 600px" class="wp-caption aligncenter"><a href="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2014/05/007d0-spi-timing.png" target="_blank" rel="noopener"><img decoding="async" loading="lazy" class="thumbnail wp-image-932" src="https://www.ba0sh1.com/wp-content/uploads/2014/05/SPI-timing-1024x329.png" alt="SPI device supports half-duplex" width="600" height="193" /></a><figcaption id="caption-attachment-932" class="wp-caption-text">SPI device supports half-duplex</figcaption></figure>
<ol>
<li>The device&#8217;s MISO (or DOUT) pin uses open-drain output. This is usually true because open-drain allows multiple SPI slaves to share the same MISO line.</li>
<li>In the communication protocol, the slave device always waits for the master to send fixed number of bytes (commands) from  MOSI, then returns a fixed number of bytes to MISO. Some devices which transmit and receive data simultaneously cannot be used in half-duplex mode.</li>
<li>The slave ignores whatever appears on the MOSI pin when transmitting data to the master. This is usually not mentioned in the datasheet. However, if the slave device mandates a CS or STROBE signal to be asserted at the beginning of each data exchange, we can usually assume this is true. Reason being that the slave device is using CS to reset its internal state rather than always listening and parsing command byte(s) from the master.</li>
</ol>
<p>Half-duplex wiring of STM32 SPI is as follows:</p>
<figure id="attachment_940" aria-describedby="caption-attachment-940" style="width: 600px" class="wp-caption aligncenter"><a href="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2014/05/d1990-spi_hd_conn.png" target="_blank" rel="noopener"><img decoding="async" loading="lazy" class="thumbnail wp-image-940" src="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2014/05/d1990-spi_hd_conn.png" alt="STM32 half-duplex SPI connection" width="600" height="246" srcset="https://ba0sh1.com/wp-content/uploads/2014/05/d1990-spi_hd_conn.png 840w, https://ba0sh1.com/wp-content/uploads/2014/05/d1990-spi_hd_conn-300x123.png 300w, https://ba0sh1.com/wp-content/uploads/2014/05/d1990-spi_hd_conn-768x315.png 768w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption id="caption-attachment-940" class="wp-caption-text">STM32 half-duplex SPI connection</figcaption></figure>
<p>In particular, MOSI and SCK are configured as &#8220;Alternate Function&#8221; mode. Hardware CS (NSS) management must be disabled and user shall manually control CS using GPIO output. R2 is pull-up resistor as required by SPI. R1 works as protection resistor in case STM32 MOSI pin somehow enters into push-pull output mode. The SPI setup code is as follows:</p>
<p>[code]<br />
void SPI_Configure()<br />
{<br />
    SPI_InitTypeDef SPI_InitStructure;<br />
    // Enable SPI1 clock<br />
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);<br />
    // SPI1 configuration<br />
    SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; // Initially Tx<br />
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;<br />
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;<br />
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; // Clock steady high<br />
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // Data write on rising (second) edge<br />
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;<br />
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;<br />
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;<br />
    SPI_InitStructure.SPI_CRCPolynomial = 7;<br />
    SPI_Init(SPI1, &amp;SPI_InitStructure);<br />
    SPI_RxFIFOThresholdConfig(SPI1, SPI_RxFIFOThreshold_QF);<br />
    SPI_Cmd(SPI1, ENABLE);<br />
}<br />
[/code]</p>
<p>Line 7 sets the SPI peripheral to half-dulex transmission mode. Line 17 sets the SPI FIFO buffer threshold to quarter full. This is new in STM32F0 with 4-byte SPI FIFO buffer. SPI_RxFIFOThreshold_QF meaning that the SPI_I2S_FLAG_RXNE flag will be set as soon as 1 byte (quarter buffer) is shifted into receiving FIFO. SPI master sending data to slave is as simple as:</p>
<p>[code]<br />
void send_byte(uint8_t val)<br />
{<br />
    GPIO_ResetBits(GPIOA, GPIO_Pin_4); // CS low<br />
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); //wait buffer empty<br />
    SPI_SendData8(SPI1, val);<br />
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); //wait finish sending<br />
    GPIO_SetBits(GPIOA, GPIO_Pin_4); // CS high<br />
}<br />
[/code]</p>
<p>The following code demonstrates master sends 1 byte command to slave and reads 1 byte back.</p>
<p>[code]<br />
uint8_t send_and_read_byte(uint8_t cmd)<br />
{<br />
    uint8_t result;<br />
    GPIO_ResetBits(GPIOA, GPIO_Pin_4); // CS low<br />
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); //wait buffer empty<br />
    SPI_SendData8(SPI1, cmd);<br />
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); //wait finish sending<br />
    // Read receiving FIFO until it is empty<br />
    while (SPI_GetReceptionFIFOStatus(SPI1) != SPI_ReceptionFIFOStatus_Empty)<br />
        SPI_ReceiveData8(SPI1);<br />
    SPI_BiDirectionalLineConfig(SPI1, SPI_Direction_Rx);<br />
    while (!(SPI1-&gt;SR &amp; SPI_I2S_FLAG_RXNE)) ; // wait data received<br />
    GPIO_SetBits(GPIOA, GPIO_Pin_4); // CS high<br />
    SPI1-&gt;CR1 |= SPI_Direction_Tx;  // Set Tx mode to stop Rx clock<br />
    result = SPI_ReceiveData8(SPI1);<br />
    return result;<br />
}<br />
[/code]</p>
<p>Immediately after one byte is sent, the program empties all stale data in the FIFO (line 9, 10), then sets SPI direction to receiving mode (line 11). <em>As soon as SPI enters into receiving mode, STM32 will continuously generate clock on SCK pin until receiving mode is disabled. </em>Along with the clock toggling, data are shifted from MOSI pin into receiving FIFO, and SPI_I2S_FLAG_RXNE flag is set once 1 byte of data is received (line 12). The program then disables CS (line 13, to disable slave output) and switches SPI back to transmitting mode (line 14, to stop the clock). These two steps must be executed fast enough before the next clock is sent out to prevent the slave device enter into any undefined state. Timing is very critical here especially when SPI clock is high. To receive multiple bytes from the slave, put line 9-15 into a loop but disable CS only after all data are read. Important thing is to always disable receiving mode immediately after FIFO is quarter full, and verify using a scope or logic analyser to ensure exact 8 clocks are send in-between each reading.</p>
<p>The post <a rel="nofollow" href="https://ba0sh1.com/2014/05/31/howto-use-stm32-spi-half-duplex-mode/">HOWTO: Use STM32 SPI half duplex mode</a> appeared first on <a rel="nofollow" href="https://ba0sh1.com">Digital Me</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ba0sh1.com/2014/05/31/howto-use-stm32-spi-half-duplex-mode/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>
		<item>
		<title>Opensource STM32 development</title>
		<link>https://ba0sh1.com/2013/05/25/opensource-stm32-development/</link>
					<comments>https://ba0sh1.com/2013/05/25/opensource-stm32-development/#comments</comments>
		
		<dc:creator><![CDATA[Baoshi]]></dc:creator>
		<pubDate>Sat, 25 May 2013 03:10:06 +0000</pubDate>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[GCC]]></category>
		<category><![CDATA[STM32]]></category>
		<guid isPermaLink="false">https://www.ba0sh1.com/?p=636</guid>

					<description><![CDATA[<p>In an upcoming project I need a micro controller that operates: 1x 16-bit DAC (SPI); 1x 24-bit ADC (SPI); 1x 8-bit parallel LCD; 1x rotary encoder; 1x PWM fan; 1x fan tachometer; 1x...</p>
<p>The post <a rel="nofollow" href="https://ba0sh1.com/2013/05/25/opensource-stm32-development/">Opensource STM32 development</a> appeared first on <a rel="nofollow" href="https://ba0sh1.com">Digital Me</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In an upcoming project I need a micro controller that operates: 1x 16-bit DAC (SPI); 1x 24-bit ADC (SPI); 1x 8-bit parallel LCD; 1x rotary encoder; 1x PWM fan; 1x fan tachometer; 1x temperature sensor (DS18B20); 2x analog switches; 1x uplink UART; 4x push buttons, and some voltage monitoring for various power rails. To my estimation these peripherals require about 40 pins. Considering the additional clock, power and programming/debug lines, the minimal pin count I&#8217;m going for is 64. So I went to element 14 parametric search to look for a suitable chip.</p>
<p><span id="more-636"></span>While lacking of choice is not always a real engineering problem, having too many choices is usually  more troublesome. My filtering for 64-100 pin devices resulted in 1638 devices from 17 manufactures&#8230; After <del>much</del> 1 second consideration I <del>finally</del> quickly made a decision. The winner is &#8212; STM32 ARM Cortex-M series. At the price point comparable to Microchip or Atmel&#8217;s 8-bit processor, I can jump onto 32-bit ARM development, how &#8220;IN&#8221; it is!</p>
<p>But the road that follows is not as smooth as I had imagined. STmicroelectronics has labelled themselves to be a &#8220;Hardware&#8221; manufacture so that they can excuse themselves from providing a usable compiler. While they do offer downloads of development tools from reputable vendors such as IAR or Keil, those tools are either &#8220;crippled&#8221; edition or time limited ware. I then spend several days looking for a guide to setup free or opensource ARM development tool-chain. There are quite a number of good resources online, for example, <a title="Tutorial: Setting-up ARM Cortex-M3 Development Enviroment using Codesourcery Toolchain, Eclipse, and Segger J-Link Debugger" href="http://deneb.homedns.org/things/?p=113" target="_blank" rel="noopener">here</a>, <a title="Setting up the GCC ARM Toolchain" href="http://hertaville.com/2012/05/28/gcc-arm-toolchain-stm32f0discovery/" target="_blank" rel="noopener">here</a> and <a title="Learning Eclipse &amp; ARM" href="https://sites.google.com/site/learningeclipsearm/2-software-installation" target="_blank" rel="noopener">here</a>. I&#8217;m not going to write &#8220;Yet Another &#8230;&#8221;, just document my approaches here, for note taking purposes.</p>
<h3>Mini-TOC</h3>
<ol>
<li><span style="line-height:13px;"><a href="#developmentplatform">Development Platform</a></span></li>
<li><a href="#commandlinetools">Command Line Tools</a></li>
<li><a href="#projectfolder">Project Folder</a></li>
<li><a href="#projecttemplate">Project Template</a></li>
<li><a href="#eclipseide">Eclipse IDE</a></li>
<li><a href="#importstm32project">Import STM32 Project</a></li>
<li><a href="#debuggingineclipse">Debugging in Eclipse</a></li>
<li><a href="#eclipseplugins">Eclipse Plugins</a></li>
<li><a href="#attachments">Downloads</a></li>
</ol>
<p><a name="developmentplatform"></a></p>
<h3>Development Platform</h3>
<p>My toolchain installation is on Windows 7. I have test it on both 32-bit and 64-bit editions. I have no plan to do development on Linux or Mac OSX yet, mainly because my other EDA tools are only available in Windows.<br />
<a name="commandlinetools"></a></p>
<h3>Command Line Tools</h3>
<p>Compiling program from the command line is probably the best experience to understand the compiler tools and the interaction among them. Most online resources recommend <a title="Sourcery G++ Lite" href="http://www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/editions/lite-edition/" target="_blank" rel="noopener">Sourcery G++ Lite</a> as the compiler. I did try this and it works great. However Sourcery is not fully open source and I do not like the fact that you have to signup at Mentor to download it. I use the <a title="GCC ARM" href="https://launchpad.net/gcc-arm-embedded" target="_blank" rel="noopener">GNU tools for ARM</a>, because:</p>
<ol>
<li>It is fully open-source.</li>
<li>It is actively maintained by ARM employees.</li>
<li>It contains hardware float support (which is available on STM32F4) so more future-proof.</li>
</ol>
<p>I download the Windows ZIP package and extract it to C:Appsarmgcc. (C:Apps is the folder where I usually keep programs that do not need to be installed). I also add C:Appsarmgccbin to the user PATH.</p>
<p><del>GNU make utilities are also required. I download the Yagarto Tools package from <a title="Yagarto Tools" href="http://www.yagarto.de/download/yagarto/yagarto-tools-20121018-setup.exe">here</a>. GNU make from <a title="Make for Windows" href="http://gnuwin32.sourceforge.net/packages/make.htm" target="_blank" rel="noopener">here</a> is also usable but I found the one inside Yagarto Tools has better compatibility with many &#8220;Linux only&#8221; Makefiles.</del> GNU Make utility is required. Win32 version with supporting files is <a title="here" href="https://ba0sh1com.files.wordpress.com/2020/09/2c1c9-make.zip" target="_blank" rel="noopener">here</a>. I extract all the files to C:Appsbin and add the same to user PATH.</p>
<p>To verify the installation, open a Command Prompt and try these two commands:</p>
<ol>
<li><span style="line-height:13px;">arm-none-eabi-gcc -v</span></li>
<li>make -v
<p><figure id="attachment_641" aria-describedby="caption-attachment-641" style="width: 406px" class="wp-caption aligncenter"><a href="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/38876-gccnmake.png" target="_blank" rel="noopener"><img decoding="async" loading="lazy" class="thumbnail  wp-image-641  " src="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/38876-gccnmake.png" alt="gcc and make" width="406" height="349" srcset="https://ba0sh1.com/wp-content/uploads/2013/05/38876-gccnmake.png 677w, https://ba0sh1.com/wp-content/uploads/2013/05/38876-gccnmake-300x258.png 300w" sizes="(max-width: 406px) 100vw, 406px" /></a><figcaption id="caption-attachment-641" class="wp-caption-text">gcc and make</figcaption></figure></li>
</ol>
<p>I have heard some &#8220;make&#8221; utilities which maybe installed by other software such as the WinAVR or Delphi can conflict with the GNU make, so make sure &#8220;make -v&#8221; gives correct version information as &#8220;GNU make 3.81&#8221;. Otherwise just rename the make.exe to something else such as &#8220;gmake.exe&#8221;.</p>
<p><a name="projectfolder"></a></p>
<h3>Project Folder</h3>
<p>Many development tools, e.g.,  Arduino, MPLab, Atmel Studio, Altium Designer, etc, store user files in its own &#8220;workspace&#8221; or &#8220;project&#8221; folder. By default the folders are created under Windows user profile, but I prefer to move them to a central location to ease backup and sync. My central location is &#8220;D:workspace&#8221;. For STM32 I created a &#8220;D:workspaceSTM32&#8221; where I put all STM32 related files.<br />
ST Standard Peripheral Library is required for development. I downloaded the STM32F10x flavour and put it under d:workspaceSTM32STM32F10x_StdPeriph_Lib_V3.5.0</p>
<p><a name="projecttemplate"></a></p>
<h3><strong>Project Template</strong></h3>
<p>I tried several STM32 project templates available on the Internet, and finally I decided to make my own. The reason I do not like some templates are:</p>
<ol>
<li><span style="line-height:13px;">Some templates copy files from ST peripheral library to their own folder. This is only good if ST frequently modify their library interface, or you want to modify ST source code. I would rather keep ST library files in their original location and reference them from my Makefile.</span></li>
<li>Some templates compile all ST peripheral library files into one library archive (.a file). It is pretty wasteful if only part of the library are used. I choose to reference only the used ST library files.</li>
<li>Some template organize the Makefile into separate sub-makefiles and include them in the final one. It is good for large project. At currently I would rather use a monolithic Makefile to make life easier.</li>
</ol>
<p>As I have yet to learn how to create a GitHub account, my project template is attached <a href="#attachments">below</a>.<br />
Explanation for some snippets of the Makefile:</p>
<p>[code firstline=&#8221;10&#8243;]<br />
######################################<br />
# building variables<br />
######################################<br />
# debug build?<br />
DEBUG = 1<br />
# build for debug in ram?<br />
RAMBUILD = 0<br />
# optimization<br />
OPT = -O0<br />
[/code]</p>
<p>Here I set the variables controlling the build process:</p>
<ul>
<li>DEBUG is a general debugging switch. If defined as 0, no debug symbol is generated in the final .elf file.</li>
<li>RAMBUILD sets where the code is executed. If RAMBUILD = 0, the code is set to execute from Flash (starts from 0x08000000). Otherwise if RAMBUILD = 1, the code is executed from RAM (from 0x20000000). RAMBUILD selects the correct link script and interrupt vector table. It is always preferable to debug in RAM as the on-chip flash has a limited re-write cycle. The compiler will generate an error if RAM is not enough to host the complete program.</li>
<li>OPT is the optimization switch. Sometimes if RAM is not enough for debugging, use -Os to reduce program size.</li>
</ul>
<p>[code firstline=&#8221;20&#8243;]<br />
#######################################<br />
# paths<br />
#######################################<br />
# source path<br />
VPATH = src startup<br />
# firmware library path<br />
PERIPHLIBPATH = ../../STM32F10x_StdPeriph_Lib_V3.5.0/Libraries<br />
VPATH += $(PERIPHLIBPATH)/CMSIS/CM3/CoreSupport<br />
VPATH += $(PERIPHLIBPATH)/CMSIS/CM3/DeviceSupport/ST/STM32F10x<br />
VPATH += $(PERIPHLIBPATH)/STM32F10x_StdPeriph_Driver/src<br />
# Build path<br />
BUILD_DIR = build<br />
[/code]</p>
<p>Here various paths are listed, including the project source code (src and startup), ST peripheral library path and building path (BUILD_DIR). Source codes are located using VPATH directive.</p>
<p>[code firstline=&#8221;33&#8243;]<br />
# #####################################<br />
# source<br />
# #####################################<br />
SRCS =<br />
  main.c<br />
  stm32f10x_it.c<br />
  system_stm32f10x.c</p>
<p>SRCSASM =<br />
  startup_stm32f10x_hd.s</p>
<p># #####################################<br />
# firmware library<br />
# #####################################<br />
PERIPHLIB_SOURCES =<br />
  core_cm3.c<br />
  stm32f10x_gpio.c<br />
  stm32f10x_rcc.c<br />
[/code]</p>
<p>I list all the used source files here. system_stm32f10x.c and stm32f10x_it.c are copied from ST peripheral library. These two files always need modification to suit specific application. Startup code startup_stm32f10x_hd.s is from Attolic TrueStudio.</p>
<p>[code firstline=&#8221;87&#8243;]<br />
#######################################<br />
# LDFLAGS<br />
#######################################<br />
# link script<br />
ifeq ($(RAMBUILD), 1)<br />
LDSCRIPT = linker/STM32F103VE_ram.ld<br />
else<br />
LDSCRIPT = linker/STM32F103VE_flash.ld<br />
endif<br />
[/code]</p>
<p>These are the link scripts obtained from Atollic TrueStudio and ST peripheral library.<br />
More startup files and link scripts for other STM32 devices are linked at the <a href="#attachments">end</a> of the article.</p>
<p>To compile the project simply type &#8220;make&#8221; within the project root folder. The Makefile features auto generated dependencies so I do not need to clean the project all the time. At the end of the building process the size of each section is displayed.</p>
<p><figure id="attachment_672" aria-describedby="caption-attachment-672" style="width: 406px" class="wp-caption aligncenter"><a class="thumbnail" href="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/b7151-stm32-make.png" target="_blank" rel="noopener"><img decoding="async" loading="lazy" class=" wp-image-672 " src="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/b7151-stm32-make.png" alt="Make a project" width="406" height="205" srcset="https://ba0sh1.com/wp-content/uploads/2013/05/b7151-stm32-make.png 677w, https://ba0sh1.com/wp-content/uploads/2013/05/b7151-stm32-make-300x152.png 300w" sizes="(max-width: 406px) 100vw, 406px" /></a><figcaption id="caption-attachment-672" class="wp-caption-text">Make a project</figcaption></figure></p>
<p><a name="eclipseide"></a></p>
<h3>Eclipse IDE</h3>
<p>Although building program from the command line is probably the best experience to understand the compiler, sticking to the command line only is definitely the stupidest idea (except for some &#8220;cool effect&#8221; in front of young players). Eclipse is one the the greatest free IDE so I decided to use it.<br />
However Eclipse has become bloatware these days. The current binary package of &#8220;Eclipse IDE for C/C++ Developers&#8221; is about 130MB, which contains a lot of plugins, such as &#8220;Visual C++ support&#8221;, that I do not need at all. And you do not have an option to uninstall it! So I choose the bare metal way. Download the &#8220;Platform Runtime Binary&#8221; package from Eclipse archive (currently version 3.8.2 <a title="Eclipse archive" href="http://archive.eclipse.org/eclipse/downloads/drops/R-3.8.2-201301310800/">here</a>). It weights 53MB. Extraction the package to C:Appseclipse-stm32, run eclipse.exe. When workspace location is asked, give &#8220;D:workspaceSTM32eclipse&#8221;</p>
<p><figure id="attachment_675" aria-describedby="caption-attachment-675" style="width: 378px" class="wp-caption aligncenter"><a class="thumbnail" href="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/28cfc-eclipse-workspace-location.png" target="_blank" rel="noopener"><img decoding="async" loading="lazy" class=" wp-image-675   " src="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/28cfc-eclipse-workspace-location.png" alt="Eclipse workspace location" width="378" height="175" srcset="https://ba0sh1.com/wp-content/uploads/2013/05/28cfc-eclipse-workspace-location.png 630w, https://ba0sh1.com/wp-content/uploads/2013/05/28cfc-eclipse-workspace-location-300x139.png 300w" sizes="(max-width: 378px) 100vw, 378px" /></a><figcaption id="caption-attachment-675" class="wp-caption-text">Eclipse workspace location</figcaption></figure></p>
<p>For the next step, choose &#8220;Help&#8221;-&gt;&#8221;Install New Software&#8230;&#8221;, click the &#8220;Add&#8230;&#8221; button and type in Eclipse CDT site as the picture below (The current settings is for Eclispe 3.8 &#8220;Juno&#8221;):</p>
<p><figure id="attachment_676" aria-describedby="caption-attachment-676" style="width: 235px" class="wp-caption aligncenter"><a class="thumbnail" href="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/48c3f-eclipse-cdt-site.png" target="_blank" rel="noopener"><img decoding="async" loading="lazy" class=" wp-image-676 " src="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/48c3f-eclipse-cdt-site.png" alt="Eclipse CDT site" width="235" height="108" srcset="https://ba0sh1.com/wp-content/uploads/2013/05/48c3f-eclipse-cdt-site.png 392w, https://ba0sh1.com/wp-content/uploads/2013/05/48c3f-eclipse-cdt-site-300x138.png 300w" sizes="(max-width: 235px) 100vw, 235px" /></a><figcaption id="caption-attachment-676" class="wp-caption-text">Eclipse CDT site</figcaption></figure></p>
<p>Then select &#8220;Work with:&#8221; CDT and check these packages:</p>
<p><figure id="attachment_677" aria-describedby="caption-attachment-677" style="width: 443px" class="wp-caption aligncenter"><a class="thumbnail" href="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/52afa-eclipse-cdt-packages.png" target="_blank" rel="noopener"><img decoding="async" loading="lazy" class=" wp-image-677 " src="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/52afa-eclipse-cdt-packages.png" alt="Eclipse CDT packages" width="443" height="416" srcset="https://ba0sh1.com/wp-content/uploads/2013/05/52afa-eclipse-cdt-packages.png 739w, https://ba0sh1.com/wp-content/uploads/2013/05/52afa-eclipse-cdt-packages-300x282.png 300w" sizes="(max-width: 443px) 100vw, 443px" /></a><figcaption id="caption-attachment-677" class="wp-caption-text">Eclipse CDT packages</figcaption></figure></p>
<p>Click &#8220;Next&#8221;, accept some license nags and a clean bare-metal Eclipse C/C++ development environment is up.</p>
<p><a name="importstm32project"></a></p>
<h3>Import STM32 Project</h3>
<p>Start Eclipse, choose &#8220;File&#8221;-&gt;&#8221;New&#8221;-&gt;&#8221;Makefile Project with Existing Code&#8221;, enter as follows:</p>
<p><figure id="attachment_681" aria-describedby="caption-attachment-681" style="width: 315px" class="wp-caption aligncenter"><a class="thumbnail" href="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/d3588-eclipse-new-project.png" target="_blank" rel="noopener"><img decoding="async" loading="lazy" class=" wp-image-681 " src="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/d3588-eclipse-new-project.png" alt="Eclipse new project setting" width="315" height="328" srcset="https://ba0sh1.com/wp-content/uploads/2013/05/d3588-eclipse-new-project.png 525w, https://ba0sh1.com/wp-content/uploads/2013/05/d3588-eclipse-new-project-288x300.png 288w" sizes="(max-width: 315px) 100vw, 315px" /></a><figcaption id="caption-attachment-681" class="wp-caption-text">Eclipse new project setting</figcaption></figure></p>
<p>The project &#8220;Blank&#8221; is created. A small red cross is displayed at the folder icon. This is because the Eclipse indexer is not able to find all the definitions and prototypes. To fix this, right click the project folder and select &#8220;Properties&#8221;, in the popup window, select &#8220;C/C++ Build-&gt;Discovery Options&#8221;, change &#8220;Complier invocation command&#8221; to &#8220;arm-none-eabi-gcc&#8221;.</p>
<p><figure id="attachment_683" aria-describedby="caption-attachment-683" style="width: 611px" class="wp-caption aligncenter"><a class="thumbnail" href="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/b96f4-eclipse-discovery.png" target="_blank" rel="noopener"><img decoding="async" loading="lazy" class=" wp-image-683 " src="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/b96f4-eclipse-discovery.png" alt="Eclipse discovery options" width="611" height="461" srcset="https://ba0sh1.com/wp-content/uploads/2013/05/b96f4-eclipse-discovery.png 1018w, https://ba0sh1.com/wp-content/uploads/2013/05/b96f4-eclipse-discovery-300x226.png 300w, https://ba0sh1.com/wp-content/uploads/2013/05/b96f4-eclipse-discovery-768x579.png 768w" sizes="(max-width: 611px) 100vw, 611px" /></a><figcaption id="caption-attachment-683" class="wp-caption-text">Eclipse discovery options</figcaption></figure></p>
<p>Close the Properties window, do a rebuild inside Eclipse (which takes a while as compare to build from command line because Eclipse is scanning into building process). When finished, a &#8220;Includes&#8221; folder will appear in the project folder. The red cross should go away and all the symbols in the source code shall be able to resolve. (If not, right click project folder, &#8220;Index&#8221;-&gt;&#8221;Rebuild&#8221;)</p>
<p><figure id="attachment_684" aria-describedby="caption-attachment-684" style="width: 238px" class="wp-caption aligncenter"><a class="thumbnail" href="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/98a4f-eclipse-project-folder.png" target="_blank" rel="noopener"><img decoding="async" loading="lazy" class=" wp-image-684 " title="Eclipse project folder" src="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/98a4f-eclipse-project-folder.png" alt="Eclipse project folder" width="238" height="211" srcset="https://ba0sh1.com/wp-content/uploads/2013/05/98a4f-eclipse-project-folder.png 396w, https://ba0sh1.com/wp-content/uploads/2013/05/98a4f-eclipse-project-folder-300x266.png 300w" sizes="(max-width: 238px) 100vw, 238px" /></a><figcaption id="caption-attachment-684" class="wp-caption-text">Eclipse project folder</figcaption></figure></p>
<p><a name="debuggingineclipse"></a></p>
<h3>Debugging in Eclipse</h3>
<p>Programming and Debugging STM32 using UART is possible but clumsy. I&#8217;m lucky enough to have a SEGGER J-Link debugger so everything becomes easy. To start program and debug in Eclipse, right click the project, select &#8220;Debug As&#8221;-&gt;&#8221;Debug Configurations&#8230;&#8221;,  select &#8220;GDB Hardware Debugging&#8221; and press &#8220;New Launch Configuration&#8221; button, set the parameters at &#8220;Main&#8221; tab as follows</p>
<p><figure id="attachment_703" aria-describedby="caption-attachment-703" style="width: 505px" class="wp-caption aligncenter"><a class="thumbnail" href="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/4d7b1-eclipse-debug-main-flash.png" target="_blank" rel="noopener"><img decoding="async" loading="lazy" class=" wp-image-703  " src="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/4d7b1-eclipse-debug-main-flash.png" alt="Eclipse Flash debug configuration (Main)" width="505" height="421" srcset="https://ba0sh1.com/wp-content/uploads/2013/05/4d7b1-eclipse-debug-main-flash.png 842w, https://ba0sh1.com/wp-content/uploads/2013/05/4d7b1-eclipse-debug-main-flash-300x250.png 300w, https://ba0sh1.com/wp-content/uploads/2013/05/4d7b1-eclipse-debug-main-flash-768x640.png 768w" sizes="(max-width: 505px) 100vw, 505px" /></a><figcaption id="caption-attachment-703" class="wp-caption-text">Eclipse Flash debug configuration (Main)</figcaption></figure></p>
<p>The debug configuration name is &#8220;Debug Blank Flash&#8221;, meaning we&#8217;re debugging using on-board Dlash. Make sure &#8220;Using Standard GDB Hardware Debugging Launcher&#8221; is selected at the bottom. For the &#8220;Debugger&#8221; tab, the following settings are used</p>
<p><figure id="attachment_704" aria-describedby="caption-attachment-704" style="width: 505px" class="wp-caption aligncenter"><a class="thumbnail" href="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/72417-eclipse-debug-debugger-flash.png" target="_blank" rel="noopener"><img decoding="async" loading="lazy" class=" wp-image-704  " src="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/72417-eclipse-debug-debugger-flash.png" alt="Eclipse Flash debug configuration (Debugger)" width="505" height="421" srcset="https://ba0sh1.com/wp-content/uploads/2013/05/72417-eclipse-debug-debugger-flash.png 842w, https://ba0sh1.com/wp-content/uploads/2013/05/72417-eclipse-debug-debugger-flash-300x250.png 300w, https://ba0sh1.com/wp-content/uploads/2013/05/72417-eclipse-debug-debugger-flash-768x640.png 768w" sizes="(max-width: 505px) 100vw, 505px" /></a><figcaption id="caption-attachment-704" class="wp-caption-text">Eclipse Flash debug configuration (Debugger)</figcaption></figure></p>
<p>BTW I&#8217;ll be using SEGGER GDB Server so the &#8220;Port number&#8221; is 2331. There are other GDB servers such as OpenOCD, but since I&#8217;m developing under Windows I&#8217;d rather use original SEGGER software.</p>
<p>The &#8220;Startup&#8221; tab is below</p>
<p><figure id="attachment_702" aria-describedby="caption-attachment-702" style="width: 505px" class="wp-caption aligncenter"><a class="thumbnail" href="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/57ca8-eclipse-debug-startup-flash.png" target="_blank" rel="noopener"><img decoding="async" loading="lazy" class=" wp-image-702  " src="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/57ca8-eclipse-debug-startup-flash.png" alt="Eclipse Flash debug configuration (Startup)" width="505" height="528" srcset="https://ba0sh1.com/wp-content/uploads/2013/05/57ca8-eclipse-debug-startup-flash.png 842w, https://ba0sh1.com/wp-content/uploads/2013/05/57ca8-eclipse-debug-startup-flash-287x300.png 287w, https://ba0sh1.com/wp-content/uploads/2013/05/57ca8-eclipse-debug-startup-flash-768x803.png 768w" sizes="(max-width: 505px) 100vw, 505px" /></a><figcaption id="caption-attachment-702" class="wp-caption-text">Eclipse Flash debug configuration (Startup)</figcaption></figure></p>
<p>Code inside the two editors are:</p>
<p>[code language=&#8221;text&#8221;]<br />
monitor speed 30<br />
monitor endian little<br />
monitor reset<br />
monitor speed auto<br />
set remote memory-write-packet-size 1024<br />
set remote memory-write-packet-size fixed<br />
monitor flash download = 1<br />
monitor flash device = STM32F103RC<br />
[/code]</p>
<p>and</p>
<p>[code language=&#8221;text&#8221;]<br />
tbreak main<br />
monitor reset 0<br />
continue<br />
[/code]</p>
<p>For the &#8220;Initialize Command&#8221; part, my development board has a STM32F103RCT6 so the &#8220;flash device&#8221; is set to STM32F103RC.<br />
For the &#8220;Run Commands&#8221; part, take note I&#8217;ve inserted a &#8220;monitor reset 0&#8221;. I found this is necessary to debug RTOSs such as Chibios (wonder why).</p>
<p>Most of the time it is more convenient to debug inside RAM, provided that the chip has enough RAM for the program. To build a program for RAM debugging, set &#8220;RAMBUILD=1&#8221; in the Makefile.</p>
<p>A separate debug configuration is necessary for RAM debugging. Simply duplicate a configuration from the previous Flash debugger and configure the &#8220;Startup&#8221; tab as follows</p>
<p><figure id="attachment_709" aria-describedby="caption-attachment-709" style="width: 505px" class="wp-caption aligncenter"><a class="thumbnail" href="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/7aed2-eclipse-debug-startup-ram.png" target="_blank" rel="noopener"><img decoding="async" loading="lazy" class=" wp-image-709 " src="http://blog.ba0sh1.com/wordpress/wp-content/uploads/2013/05/7aed2-eclipse-debug-startup-ram.png" alt="Eclipse RAM debug configuration (Startup)" width="505" height="528" srcset="https://ba0sh1.com/wp-content/uploads/2013/05/7aed2-eclipse-debug-startup-ram.png 842w, https://ba0sh1.com/wp-content/uploads/2013/05/7aed2-eclipse-debug-startup-ram-287x300.png 287w, https://ba0sh1.com/wp-content/uploads/2013/05/7aed2-eclipse-debug-startup-ram-768x803.png 768w" sizes="(max-width: 505px) 100vw, 505px" /></a><figcaption id="caption-attachment-709" class="wp-caption-text">Eclipse RAM debug configuration (Startup)</figcaption></figure></p>
<p>Similarly the codes are</p>
<p>[code language=&#8221;text&#8221;]<br />
monitor speed 30<br />
monitor endian little<br />
monitor reset<br />
monitor speed auto<br />
monitor writeu32 0xE000ED08 = 0x20000000<br />
[/code]</p>
<p>and</p>
<p>[code language=&#8221;text&#8221;]<br />
tbreak main<br />
monitor reset 0<br />
monitor reg r13 = (0x20000000)<br />
monitor reg pc = (0x20000004)<br />
continue<br />
[/code]</p>
<p>The debug configurations can be added to &#8220;Favourite&#8221; menu for easy launching. But before launching, start &#8220;SEGGER J-Link GDB Server&#8221;.</p>
<p><em>Make sure the &#8220;BOOT0&#8221; and &#8220;BOOT1&#8221; pin on STM32 are correctly configured when choosing debugging from RAM or Flash.</em><br />
<a name="eclipseplugins"></a></p>
<h3>Eclipse Plugins</h3>
<p>There&#8217;s a lot of STM32 Eclipse plugins that make life easier. The plugins I use:</p>
<ol>
<li><a title="EmbSysRegView" href="http://embsysregview.sourceforge.net/">EmbSysRegView</a>  It shows ARM Cortex registers during debug section. Probably the most useful plugin.</li>
<li><a title="StateViewer" href="http://www.highintegritysystems.com/down-loads/stateviewer-plug-in/">StateViewer </a> It displays important information (Tasks, Queues, Timers) is the program uses FreeRTOS. It is a free plugin but the website asks for your information (which I don&#8217;t like). For simplicity the Eclipse software site is &#8220;<a href="http://www.highintegritysystems.com/StateViewer/">http://www.highintegritysystems.com/StateViewer/</a>&#8220;</li>
</ol>
<p>Plugin I do not use:</p>
<ol>
<li><a style="line-height:13px;" title="GNU ARM Eclipse Plug-in" href="http://sourceforge.net/projects/gnuarmeclipse/" target="_blank" rel="noopener">GNU ARM Eclipse Plug-in</a><span style="line-height:13px;"> This plugin automates ARM development under Eclipse. It uses Eclipse managed build system so user do not need to write a Makefile. The reason I do not use this plugin is because it obscures the building process while I like to have everything in proper control.</span></li>
<li><a title="Zylin Embedded CDT" href="http://opensource.zylin.com/embeddedcdt.html" target="_blank" rel="noopener">Zylin Embedded CDT</a> This plugin provides easier settings for hardware GDB. However I do not feel the CDT build-in GDB integration is harder to configure.</li>
<li><a title="ST MicroXplorer" href="http://www.st.com/web/en/catalog/tools/PF251717" target="_blank" rel="noopener">ST MicroXplorer</a> MicroXplorer is a visual tool for planning and configure STM32 mcu pins. It also generates configuration code automatically. MicroXplorer is distributed as a standalone utility and a Eclipse plugin. The Eclipse plugin seems to slow down Eclipse startup significantly. I use the standalone version.</li>
</ol>
<p><a name="attachments"></a></p>
<h3>Downloads</h3>
<p>[attachments size=small docid=&#8221;656,662,661&#8243;]</p>
<p>The post <a rel="nofollow" href="https://ba0sh1.com/2013/05/25/opensource-stm32-development/">Opensource STM32 development</a> appeared first on <a rel="nofollow" href="https://ba0sh1.com">Digital Me</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ba0sh1.com/2013/05/25/opensource-stm32-development/feed/</wfw:commentRss>
			<slash:comments>15</slash:comments>
		
		
			</item>
	</channel>
</rss>
