<?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>Search Results for &#8220;bridge control panel&#8221; &#8211; IoT Expert</title>
	<atom:link href="https://iotexpert.com/search/bridge+control+panel/feed/rss2/" rel="self" type="application/rss+xml" />
	<link>https://iotexpert.com</link>
	<description>Engineering for the Internet of Things</description>
	<lastBuildDate>Tue, 12 Jan 2021 20:12:38 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.7</generator>

<image>
	<url>https://iotexpert.com/wp-content/uploads/2017/01/cropped-Avatar-32x32.jpg</url>
	<title>Search Results for &#8220;bridge control panel&#8221; &#8211; IoT Expert</title>
	<link>https://iotexpert.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Debugging SSD1306 Display Problems</title>
		<link>https://iotexpert.com/debugging-ssd1306-display-problems/</link>
					<comments>https://iotexpert.com/debugging-ssd1306-display-problems/#comments</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Wed, 07 Aug 2019 13:19:13 +0000</pubDate>
				<category><![CDATA[Graphics]]></category>
		<category><![CDATA[MBED OS]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=7593</guid>

					<description><![CDATA[Summary This article explains in detail how to use and debug SSD1306 displays.  In this article, I use the Segger emWin library and MBEDOS, but for all practical purposes this discussion applies to all other interfaces to the board including Arduino, Raspberry Pi, Adafruit, etc.  I will say from the outset that I spent far [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>This article explains in detail how to use and debug SSD1306 displays.  In this article, I use the Segger emWin library and MBEDOS, but for all practical purposes this discussion applies to all other interfaces to the board including Arduino, Raspberry Pi, Adafruit, etc.  I will say from the outset that I spent far far too much time digging into the inner workings of an 11 year old graphics driver.  Oh well, hopefully someone will get some benefit.</p>
<p>A year ago (or so) I designed a user interface board called the CY8CKIT-032 to go with my Cypress WICED WiFi book and class.  This board uses a PSoC 4 Analog co-processor which can do a bunch of cool stuff.  I have a series of articles planned about that board, but that will be for another day.  One of the things that I did was put a 0.96&#8243; I2C OLED Display based on a SSD1306 driver on the board.  These displays are widely available from Alibaba and eBay for &lt;$2.  I think that the displays are being used in inexpensive cells phones in China so there are tons of them and they are CHEAP!  The bad news is that if you google &#8220;ssd1306 problems&#8221; you will find an absolute rogues gallery of unpleasantness.  It seems that tons of people struggle to get these things working.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0744/" rel="attachment wp-att-7604"><img fetchpriority="high" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0744-1024x842.jpg" alt="" width="1024" height="842" class="alignnone size-large wp-image-7604" srcset="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0744-1024x842.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0744-600x493.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0744-300x247.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0744-768x631.jpg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>This whole thing started last week as Cypress released and update to our MBED OS implementation.  This update included releasing a complete set of the Segger emWin drivers.  I had been wanting to step up to a more robust graphics library than the Adafruit library that I used in this <a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/" target="_blank" rel="noopener noreferrer">article</a>.  I was pleased to see that our release included the emWin SPAGE driver which knows how to talk to a bunch of different page based displays including the SSD1306.</p>
<p>But, as always, I had to wrestle with the display a little bit before I got everything working.  This time I wrote down what I did/learned.  So, for this article I will describe</p>
<ul>
<li>The SSD1306 Electrical Interface</li>
<li>The SSD1306 Software Interface</li>
<li>The SSD1306 Driver Registers</li>
<li>The SSD1306 Graphics Data RAM</li>
<li>Reading from the Frame Buffer</li>
<li>My Initialization Sequence</li>
<li>Some Other Initialization Sequences</li>
<li>A Bunch of Screen Problems &amp; How To Fix</li>
</ul>
<h1>The Electrical Interface</h1>
<p>There is not a lot to know about the electrical interface.  The data sheet specifies that the device can use I2C, SPI, 6800 and 8080.  I have not seen either the 6800 or 8080 interface put onto any of these OLED displays.  Like all driver chips, the SSD1306 has an absolute boatload of pins, in fact, 281.  The chip is long and skinny and was made to be mounted either on the display under the glass or on the flex connector.  Of the 281 pins, 128+64=196 are connected to the segments and commons in the display.  The rest of the pins are either capacitors, no-connects, power/ground or data signals.  The data signals are</p>
<ul>
<li>D0-D7 either parallel data for 8080/6800 or SDA/SCL for I2C or MOSI/MISO for SPI</li>
<li>E &#8211; enable signal for 6800 or RD for 8080</li>
<li>R/W# &#8211; Read Write for 6800/8080</li>
<li>CS &#8211; Chip Select for SPI, 8080, 6800</li>
<li>D/C# &#8211; Data or Command for SPI, 6800, 8080 or Slave Address Select for I2C</li>
<li>Reset &#8211; Chip reset</li>
</ul>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-07-28-at-7-28-49-am/" rel="attachment wp-att-7632"><img decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-7.28.49-AM-1024x281.png" alt="" width="1024" height="281" class="alignnone size-large wp-image-7632" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-7.28.49-AM-1024x281.png 1024w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-7.28.49-AM-600x165.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-7.28.49-AM-300x82.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-7.28.49-AM-768x211.png 768w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-7.28.49-AM.png 1936w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>For the I2C configurations it is common to tie the reset pin High and not bring the pin to a connector.  The SA0 is also typically connected via a 0-ohm resistor to either 0 or 1 which configures the device to have the 7-bit address 0x3C or 0x3D or 8-bit 0x78 or 0x7A.  Here is a picture of the back of one of my boards where you can see the 0ohm resistor.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0758/" rel="attachment wp-att-7633"><img decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0758-967x1024.jpg" alt="" width="967" height="1024" class="alignnone size-large wp-image-7633" srcset="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0758-967x1024.jpg 967w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0758-600x636.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0758-283x300.jpg 283w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0758-768x814.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0758.jpg 1059w" sizes="(max-width: 967px) 100vw, 967px" /></a></p>
<p>Sometimes all of the data pins are available on the back of the board.  This lets you move/add/change the 0-ohm resistors to configure the mode of the chip.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/sku_340467_1-2/" rel="attachment wp-att-7636"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/sku_340467_1-1.jpg" alt="" width="479" height="455" class="alignnone size-full wp-image-7636" srcset="https://iotexpert.com/wp-content/uploads/2019/07/sku_340467_1-1.jpg 479w, https://iotexpert.com/wp-content/uploads/2019/07/sku_340467_1-1-300x285.jpg 300w" sizes="(max-width: 479px) 100vw, 479px" /></a> <a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/b9d2d39952c19f77d0cc89703b80c0a0-image-600x600-2/" rel="attachment wp-att-7637"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/b9d2d39952c19f77d0cc89703b80c0a0.image_.600x600-1.jpg" alt="" width="377" height="373" class="alignnone size-large wp-image-7637" srcset="https://iotexpert.com/wp-content/uploads/2019/07/b9d2d39952c19f77d0cc89703b80c0a0.image_.600x600-1.jpg 377w, https://iotexpert.com/wp-content/uploads/2019/07/b9d2d39952c19f77d0cc89703b80c0a0.image_.600x600-1-100x100.jpg 100w, https://iotexpert.com/wp-content/uploads/2019/07/b9d2d39952c19f77d0cc89703b80c0a0.image_.600x600-1-300x297.jpg 300w" sizes="(max-width: 377px) 100vw, 377px" /></a></p>
<p>One thing you should be careful about is the I2C connections.  I looked around on eBay and Alibaba to find a few pictures of the I2C displays.  You should notice that all three of these displays are I2C, but all three of them have a different position and ORDER of VCC/GND/SCL/SDL  When we ordered displays from China to go onto the CY8CKIT-032 we found displays in the same BATCH that had different orders of the VCC/GND.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/muadz9bapvnzwizfk-ndhbg/" rel="attachment wp-att-7626"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/mUADz9BApvNzwiZfK-Ndhbg.jpg" alt="" width="225" height="225" class="alignnone size-full wp-image-7626" srcset="https://iotexpert.com/wp-content/uploads/2019/07/mUADz9BApvNzwiZfK-Ndhbg.jpg 225w, https://iotexpert.com/wp-content/uploads/2019/07/mUADz9BApvNzwiZfK-Ndhbg-100x100.jpg 100w, https://iotexpert.com/wp-content/uploads/2019/07/mUADz9BApvNzwiZfK-Ndhbg-150x150.jpg 150w" sizes="(max-width: 225px) 100vw, 225px" /></a>  <a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/mjvbbenrakthvstgdwuagew/" rel="attachment wp-att-7629"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/mjVBBeNrakthvSTgdwuAGEw.jpg" alt="" width="225" height="225" class="alignnone size-large wp-image-7629" srcset="https://iotexpert.com/wp-content/uploads/2019/07/mjVBBeNrakthvSTgdwuAGEw.jpg 225w, https://iotexpert.com/wp-content/uploads/2019/07/mjVBBeNrakthvSTgdwuAGEw-100x100.jpg 100w, https://iotexpert.com/wp-content/uploads/2019/07/mjVBBeNrakthvSTgdwuAGEw-150x150.jpg 150w" sizes="(max-width: 225px) 100vw, 225px" /></a> <a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/s-l225-2/" rel="attachment wp-att-7630"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/s-l225-2.jpg" alt="" width="225" height="225" class="alignnone size-full wp-image-7630" srcset="https://iotexpert.com/wp-content/uploads/2019/07/s-l225-2.jpg 225w, https://iotexpert.com/wp-content/uploads/2019/07/s-l225-2-100x100.jpg 100w, https://iotexpert.com/wp-content/uploads/2019/07/s-l225-2-150x150.jpg 150w" sizes="(max-width: 225px) 100vw, 225px" /></a></p>
<p>Here is a SPI version that has reset and data/command pin brought out.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/s-l225/" rel="attachment wp-att-7627"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/s-l225.jpg" alt="" width="225" height="225" class="alignnone size-large wp-image-7627" srcset="https://iotexpert.com/wp-content/uploads/2019/07/s-l225.jpg 225w, https://iotexpert.com/wp-content/uploads/2019/07/s-l225-100x100.jpg 100w, https://iotexpert.com/wp-content/uploads/2019/07/s-l225-150x150.jpg 150w" sizes="(max-width: 225px) 100vw, 225px" /></a>  <a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/miivqcnyakhfayi4kzkqyuq/" rel="attachment wp-att-7628"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/miiVQcnyakhfaYI4KZKqYUQ.jpg" alt="" width="225" height="225" class="alignnone size-large wp-image-7628" srcset="https://iotexpert.com/wp-content/uploads/2019/07/miiVQcnyakhfaYI4KZKqYUQ.jpg 225w, https://iotexpert.com/wp-content/uploads/2019/07/miiVQcnyakhfaYI4KZKqYUQ-100x100.jpg 100w, https://iotexpert.com/wp-content/uploads/2019/07/miiVQcnyakhfaYI4KZKqYUQ-150x150.jpg 150w" sizes="(max-width: 225px) 100vw, 225px" /></a></p>
<h1>The Software Interface</h1>
<p>There are two parts to the software interface.</p>
<p>The first part is the command interface.  Inside of the chip there are a bunch of logic circuits which which configure the charge pumps, sequence COMs and SEGs, charge and discharge capacitors etc.  All of these things are configurable to allow for different configurations of screens e.g. different x-y sizes, configuration of what wires are connected to what places on the glass etc.  Before you can get the display to work correctly you must initialize all of these values by sending commands.  All the commands are 1-byte followed by 0 or more command parameters.</p>
<p>The second part is the data interface.  Inside of the SSD1306 chip there is a Graphics Display DRAM &#8211; GDDRAM which has 1 bit for every pixel on the screen. The state machine inside of the chip called the Display Controller will loop through the bits one by one and display them on the correct place on the screen.  This means that your MCU does not need to do anything to keep the display up to date.  When you want a pixel lit up on the screen you just need to write the correct location in the GDDRAM.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-07-28-at-5-04-06-pm/" rel="attachment wp-att-7676"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-5.04.06-PM-917x1024.png" alt="" width="917" height="1024" class="alignnone size-large wp-image-7676" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-5.04.06-PM-917x1024.png 917w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-5.04.06-PM-600x670.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-5.04.06-PM-269x300.png 269w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-5.04.06-PM-768x857.png 768w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-5.04.06-PM.png 1516w" sizes="(max-width: 917px) 100vw, 917px" /></a></p>
<p>For the rest of this article I will focus on the serial interface, I2C.  How do you send commands and data?  Simple.  When you start a transaction you send a control byte which tells the controller what to expect next.  There are four legal control bytes.</p>
<ul>
<li>0b10000000 = 0x80 = multiple commands</li>
<li>0b00000000 = 0x00 = one command</li>
<li>0b11000000 = 0xC0 = multiple data</li>
<li>0b01000000 = 0x40 = one data byte</li>
</ul>
<p>Here is the picture from the datasheet (which I don&#8217;t find particularly illuminating) but it does describe the control byte.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-07-28-at-5-21-23-pm/" rel="attachment wp-att-7677"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-5.21.23-PM-1024x614.png" alt="" width="1024" height="614" class="alignnone size-large wp-image-7677" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-5.21.23-PM-1024x614.png 1024w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-5.21.23-PM-600x360.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-5.21.23-PM-300x180.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-5.21.23-PM-768x461.png 768w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-5.21.23-PM.png 1394w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>To send commands you write to the I2C bus with a control byte, then you send the command, then you send the optional parameters.  If you want to send multiple commands you send the control byte 0x80, the command + parameters as many as you need.</p>
<h1>The SSD1306 Driver Registers</h1>
<p>In order for the driver chip to drive the screen you need to configure:</p>
<ol>
<li>How the driver is electrically connected to the OLED Screen</li>
<li>What are the electrical parameters of the screen</li>
<li>What are the electrical parameters of the system</li>
<li>How you want to address the frame buffer</li>
<li>The automatic scroll configuration settings</li>
<li>The pixel data for the frame buffer, though it will happily display noise.</li>
</ol>
<p>If you bought this screen from eBay, Adafruit, Alibaba etc. then you will get no say in 1-3, the electrical parameters of the system.  Your screen will come prewired with all of the capacitors, OLED etc already attached to your driver commons and segments.  If you didn&#8217;t buy the screen prepackaged, then it is highly unlikely you are reading this article.  What this means is that you need to know the initializing sequence required to get the screen to work properly, then you just send the sequence down the wire from your MCU to the screen.  From looking around on the internet, it appears to me that there in only one parameter that is different in any of the screens that I could find.  Specifically the number of lines on the screen &#8211; either 32 or 64.  Which means that all of these initialization implementations should really on have one difference register 0xA8 should be set to either n-1 aka 31 or 63</p>
<p>The other difference that you will see between different implementations is the memory address mode.  In other words, how do you want to write data into the frame buffer from the MCU.  Many of the open source graphics libraries use &#8220;Horizontal&#8221; mode.  The Segger emWin library that I am using uses &#8220;Page&#8221; mode.  More on this later.</p>
<p>When you look in the data sheet, unfortunately they mix and match the order of the information.  However, from the data sheet, the categories are:</p>
<ol>
<li>Fundamental Commands</li>
<li>Scrolling Commands</li>
<li>Address Setting Commands</li>
<li>Hardware Configuration</li>
<li>Timing and Driving Scheme</li>
<li>Charge Pump</li>
</ol>
<p>I won&#8217;t put screen shots of the whole data sheet into this article, but I will show the command table and make a few clarifications on the text.  Or at least I will clarify places where I got confused.</p>
<p>As to the fundamental commands.  I tried a bunch of different contrast settings on my screens and could not tell the difference between them.  I tried from 0x10 to 0xFF and they all looked the same to me.  The best course of action is to use the default 0x7F.  I don&#8217;t really know why there is a command 0xA5 &#8220;Entire Display ON ignore RAM&#8221;.  The data sheet says &#8220;A5h command forces the entire display to be “ON”, regardless of the contents of the display data RAM&#8221;.  I can&#8217;t think of a single use case for this.  I suppose that if you issue 0xAE the screen will be all black&#8230; and if you issue 0xA5 the screen will be all white?  But why?</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-08-01-at-6-17-14-am/" rel="attachment wp-att-7690"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.17.14-AM-1024x476.png" alt="" width="1024" height="476" class="alignnone size-large wp-image-7690" srcset="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.17.14-AM-1024x476.png 1024w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.17.14-AM-600x279.png 600w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.17.14-AM-300x139.png 300w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.17.14-AM-768x357.png 768w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.17.14-AM.png 1610w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>And my definitions in the C driver file:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">////////////////////////////////////////////////////////////////////////
// Fundamental Command Table Page 28
////////////////////////////////////////////////////////////////////////
#define OLED_SETCONTRAST                              0x81
// 0x81 + 0-0xFF Contrast ... reset = 0x7F

// A4/A5 commands to resume displaying data
// A4 = Resume to RAM content display
// A5 = Ignore RAM content (but why?)
#define OLED_DISPLAYALLONRESUME                       0xA4
#define OLED_DISPLAYALLONIGNORE                       0xA5

// 0xA6/A7 Normal 1=white 0=black Inverse 0=white  1=black
#define OLED_DISPLAYNORMAL                            0xA6
#define OLED_DISPLAYINVERT                            0xA7

// 0xAE/AF are a pair to turn screen off/on
#define OLED_DISPLAYOFF                               0xAE
#define OLED_DISPLAYON                                0xAF</pre>
<p>In the next section of the command table are the &#8220;Scrolling&#8221; commands.  It appears that this graphics chip was setup to display text that is 8-pixels high.  The scrolling commands will let you move the screen up/down and left/right to scroll automatically without having to update the the frame buffer.  In other words it can efficiently scroll the screen without a bunch of load on your MCU CPU or on the data bus between them.  The Adafruit graphics library provides the scrolling commands.  However, I am not using them with the Segger Library.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-08-03-at-8-41-09-am/" rel="attachment wp-att-7698"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-8.41.09-AM-1024x577.png" alt="" width="1024" height="577" class="alignnone size-large wp-image-7698" srcset="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-8.41.09-AM-1024x577.png 1024w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-8.41.09-AM-600x338.png 600w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-8.41.09-AM-300x169.png 300w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-8.41.09-AM-768x433.png 768w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-8.41.09-AM.png 1692w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The next section has the commands to configure how your MCU writes data into the Graphics RAM aka the frame buffer. These commands fall into two categories.  First the address mode.  The address modes help you efficiently write the GDDRAM.  When you send data to the frame buffer you really don&#8217;t want to send</p>
<ul>
<li>address, pixel, address, pixel, &#8230;</li>
</ul>
<p>What you really would like to do is send</p>
<ul>
<li>Address, pixel, pixel, pixel &#8230; (and have the address be automatically incremented</li>
</ul>
<p>At first blush you might think&#8230; why do I need a mode?  Well there are some people who want the x address incremented&#8230; there are some people who want the y-address incremented and there are some people who want to have page address access.  And what do you do when you get to the end of a line? or a column or a page? and what does the end mean?</p>
<p>The second set of commands in this table are the commands to set the starting address before you write data.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-08-01-at-6-16-11-am/" rel="attachment wp-att-7687"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.16.11-AM-1024x733.png" alt="" width="1024" height="733" class="alignnone size-large wp-image-7687" srcset="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.16.11-AM-1024x733.png 1024w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.16.11-AM-600x430.png 600w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.16.11-AM-300x215.png 300w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.16.11-AM-768x550.png 768w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.16.11-AM.png 1634w" sizes="(max-width: 1024px) 100vw, 1024px" /></a>  <a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-08-01-at-6-16-33-am/" rel="attachment wp-att-7689"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.16.33-AM-1024x409.png" alt="" width="1024" height="409" class="alignnone size-large wp-image-7689" srcset="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.16.33-AM-1024x409.png 1024w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.16.33-AM-600x240.png 600w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.16.33-AM-300x120.png 300w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.16.33-AM-768x307.png 768w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.16.33-AM.png 1642w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">////////////////////////////////////////////////////////////////////////
// Address Setting Command Table
////////////////////////////////////////////////////////////////////////

// 00-0F - set lower nibble of page address
// 10-1F - set upper niddle of page address

#define OLED_SETMEMORYMODE                            0x20
#define OLED_SETMEMORYMODE_HORIZONTAL                 0x00
#define OLED_SETMEMORYMODE_VERTICAL                   0x01
#define OLED_SETMEMORYMODE_PAGE                       0x02

// 0x20 + 00 = horizontal, 01 = vertical 2= page &gt;=3=illegal

// Only used for horizonal and vertical address modes
#define OLED_SETCOLUMNADDR                            0x21
// 2 byte Parameter
// 0-127 column start address 
// 0-127 column end address

#define OLED_SETPAGEADDR                              0x22
// 2 byte parameter
// 0-7 page start address
// 0-7 page end Address

// 0xB0 -0xB7 ..... Pick page 0-7</pre>
<p>The hardware configuration registers allow the LED display maker to hookup the common and segment signals in an order that makes sense for the placement of the chip on the OLED glass.  For a 128&#215;64 display there are at least 196 wires, so the routing of these wires may be a total pain in the ass depending on the location of the chip.  For instance the left and right might be swapped&#8230; or half the wires might come out on one side and the other half on the other side.  These registers allow the board designer flexibility in making these connections.  Commands 0xA0, 0xA1, 0xA8, 0xC0, 0xC8, 0xD3, 0xDa will all be fixed based on the layout.  You have no control and they need to be set correctly or something crazy will come out.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-08-01-at-6-15-41-am/" rel="attachment wp-att-7686"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.15.41-AM-1024x768.png" alt="" width="1024" height="768" class="alignnone size-large wp-image-7686" srcset="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.15.41-AM-1024x768.png 1024w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.15.41-AM-600x450.png 600w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.15.41-AM-300x225.png 300w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.15.41-AM-768x576.png 768w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.15.41-AM.png 1662w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">////////////////////////////////////////////////////////////////////////
// Hardware Configuration
////////////////////////////////////////////////////////////////////////

// 40-7F - set address startline from 0-127 (6-bits)
#define OLED_SETSTARTLINE_ZERO                        0x40

// Y Direction
#define OLED_SEGREMAPNORMAL                           0xA0
#define OLED_SEGREMAPINV                              0xA1

#define OLED_SETMULTIPLEX                             0xA8
// 0xA8, number of rows -1 ... e.g. 0xA8, 63

// X Direction
#define OLED_COMSCANINC                               0xC0
#define OLED_COMSCANDEC                               0xC8

// double byte with image wrap ...probably should be 0
#define OLED_SETDISPLAYOFFSET                         0xD3

// Double Byte Hardware com pins configuration
#define OLED_SETCOMPINS                               0xDA
// legal values 0x02, 0x12, 0x022, 0x032
</pre>
<p>The next sections of commands are part of the electrical configuration for the glass.</p>
<p>0xD5 essentially sets up the display update rate by 1) setting the display update clock frequency and 2) setting up a divider for that clock.</p>
<p>0xDB and 0xD9 sets up a parameter that is display dependent.  That being said I tried a bunch of different values and they all look the same to me.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-08-01-at-6-13-52-am/" rel="attachment wp-att-7685"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.13.52-AM-1024x655.png" alt="" width="1024" height="655" class="alignnone size-large wp-image-7685" srcset="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.13.52-AM-1024x655.png 1024w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.13.52-AM-600x384.png 600w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.13.52-AM-300x192.png 300w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.13.52-AM-768x491.png 768w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.13.52-AM.png 1642w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">////////////////////////////////////////////////////////////////////////
// Timing and Driving Scheme Settings
////////////////////////////////////////////////////////////////////////

#define OLED_SETDISPLAYCLOCKDIV                       0xD5
#define OLED_SETPRECHARGE                             0xD9

#define OLED_SETVCOMDESELECT                          0xDB
#define OLED_NOP                                      0xE3
</pre>
<p>These displays require a high voltage to program the liquid crystal in the display.  That voltage can either be supplied by an external pin or by an internal charge pump.  All the displays that I have seen use an internal charge pump.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-08-01-at-6-09-12-am/" rel="attachment wp-att-7684"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.09.12-AM-1024x373.png" alt="" width="1024" height="373" class="alignnone size-large wp-image-7684" srcset="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.09.12-AM-1024x373.png 1024w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.09.12-AM-600x218.png 600w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.09.12-AM-300x109.png 300w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.09.12-AM-768x280.png 768w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-01-at-6.09.12-AM.png 1478w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">////////////////////////////////////////////////////////////////////////
// Charge Pump Regulator
////////////////////////////////////////////////////////////////////////

#define OLED_CHARGEPUMP                               0x8D
#define OLED_CHARGEPUMP_ON                            0x14
#define OLED_CHARGEPUMP_OFF                           0x10
</pre>
<h1>The SSD1306 Graphics Data RAM</h1>
<p>In order to actually get data to display on the screen you need to write 1&#8217;s and 0&#8217;s into the Graphics Data RAM that represents your image.  The memory is actually organized into 8 pages that are each 128 bits wide and 8 bits tall.  This means that if you write 0b10101010 to location (0,0) you will get the first 8 pixels in a column on the screen to be on,off,on,off,on,off,on,off.  Notice that I said vertical column and not row.  Here is a picture from the data sheet.  That shows the pages:</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-08-03-at-9-33-51-am/" rel="attachment wp-att-7709"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.33.51-AM-1024x614.png" alt="" width="1024" height="614" class="alignnone size-large wp-image-7709" srcset="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.33.51-AM-1024x614.png 1024w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.33.51-AM-600x360.png 600w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.33.51-AM-300x180.png 300w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.33.51-AM-768x461.png 768w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.33.51-AM.png 1604w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>And then they show you in the data sheet that the pixels go down from the first row of the page.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-08-03-at-9-50-34-am/" rel="attachment wp-att-7712"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.50.34-AM-1024x303.png" alt="" width="1024" height="303" class="alignnone size-large wp-image-7712" srcset="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.50.34-AM-1024x303.png 1024w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.50.34-AM-600x177.png 600w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.50.34-AM-300x89.png 300w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.50.34-AM-768x227.png 768w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.50.34-AM.png 1542w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>In order to make the writing process easier and lower bandwidth the SSD1306 has three automatic addressing modes.</p>
<ul>
<li>Horizontal &#8211; Set the page address start, end and the column start and end&#8230; bytes write 8 vertical pixels on the page. Each byte write advances the column until it wraps to the next page and resets the column to the &#8220;start&#8221;</li>
<li>Vertical &#8211; Set the page address start, end and the column start and end&#8230; bytes write 8 vertical pixels on the page.  Each byte write advances the page until it wraps vertically where it increments the column and resets the page back to the start page.</li>
<li>Page &#8211; Set the page address and column start/end.  Each byte writes vertically.  Wraps back onto the same page when it hits the end column.</li>
</ul>
<p>In Horizontal and Vertical mode you</p>
<ul>
<li>Set the range of columns that you want to write (using 0x22)</li>
<li>Set the range of pages you want to write (using 0x21)</li>
<li>Write bytes</li>
</ul>
<p>In the page mode you</p>
<ul>
<li>Set the page (remember you can only write one page at a time in page mode) using 0xB0-0xB7</li>
<li>Set the start column using 0x0? and 0x1?</li>
</ul>
<p>Here is a picture from the data sheet of horizontal address mode:</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-08-03-at-9-41-58-am/" rel="attachment wp-att-7710"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.41.58-AM.png" alt="" width="976" height="334" class="alignnone size-full wp-image-7710" srcset="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.41.58-AM.png 976w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.41.58-AM-600x205.png 600w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.41.58-AM-300x103.png 300w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.41.58-AM-768x263.png 768w" sizes="(max-width: 976px) 100vw, 976px" /></a></p>
<p>In this bit of example code I am saying to iterate through the pages 0-&gt;7&#8230; in other words all of the pages.  And to start in column 0.  This example will make 12 columns of pixels each 8 high starting a (0,0) on the screen&#8230;</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">    char horizontalExample[]= {
            0xAE,
            0x20, /// address mode
            0x00, // Horizontal
            0xA4,
            0xAF,
            0x22, //Set page address range
            0,
            7,
            0x21, // column start and end address
            0,
            127,
    };

    I2C_WriteCmdStream(horizontalExample, sizeof(horizontalExample));
    // Write twelve bytes onto screen with 0b10101010
    for(int i=0;i&lt;12;i++)
        I2C_WriteData(0xAA);</pre>
<p>Here is a picture of what it does.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0774-2/" rel="attachment wp-att-7719"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/08/IMG_0774-2-1024x1005.jpg" alt="" width="1024" height="1005" class="alignnone size-large wp-image-7719" srcset="https://iotexpert.com/wp-content/uploads/2019/08/IMG_0774-2-1024x1005.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0774-2-600x589.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0774-2-300x294.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0774-2-768x754.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0774-2.jpg 1075w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Here is a picture from the data sheet of vertical address mode:</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-08-03-at-9-42-06-am/" rel="attachment wp-att-7711"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.42.06-AM.png" alt="" width="952" height="352" class="alignnone size-large wp-image-7711" srcset="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.42.06-AM.png 952w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.42.06-AM-600x222.png 600w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.42.06-AM-300x111.png 300w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-9.42.06-AM-768x284.png 768w" sizes="(max-width: 952px) 100vw, 952px" /></a></p>
<p>This example code sets the page range to 0&#8211;&gt;7  (the whole screen) and the column range 0&#8211;&gt;127 (the whole screen).  Then writes 12 bytes.  You can see it wrap at the bottom and move back to page 0 column 1.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    char verticalExample[]= {
            0xAE,
            0x20, /// address mode
            0x01, //  vertical
            0xA4,
            0xAF,
            0x22, //Set page address range
            0,
            7,
            0x21, // column start and end address
            0,
            127,
    };

    I2C_WriteCmdStream(verticalExample, sizeof(verticalExample));
    // Write twelve bytes onto screen with 0b10101010
    for(int i=0;i&lt;12;i++)
        I2C_WriteData(0xAA); 
</pre>
<p>&nbsp;</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0773/" rel="attachment wp-att-7717"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/08/IMG_0773-1024x943.jpg" alt="" width="1024" height="943" class="alignnone size-large wp-image-7717" srcset="https://iotexpert.com/wp-content/uploads/2019/08/IMG_0773-1024x943.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0773-600x552.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0773-300x276.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0773-768x707.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0773.jpg 1058w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>&nbsp;</p>
<p>In page mode you just set the page and the start and end column.  0xB0 means page 0, 0xB1 means page 1&#8230; 0xB7 means page 7.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-08-03-at-11-01-46-am/" rel="attachment wp-att-7716"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-11.01.46-AM.png" alt="" width="932" height="304" class="alignnone size-full wp-image-7716" srcset="https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-11.01.46-AM.png 932w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-11.01.46-AM-600x196.png 600w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-11.01.46-AM-300x98.png 300w, https://iotexpert.com/wp-content/uploads/2019/08/Screen-Shot-2019-08-03-at-11.01.46-AM-768x251.png 768w" sizes="(max-width: 932px) 100vw, 932px" /></a></p>
<p>You can see that I started from column 0x78 (meaning column 120) and that it wraps back to column 0 on the SAME page.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">    char pageExample[]= {
            0xAE,
            0x20, // address mode
            0x02, // Page mode
            0xA4, // Resume from ram
            0xAF, // Screen on
            0xB0, // Start from page 0
            // Start from column 0x78 aka 120
            0x08, // Column lower nibble address
            0x17  // Column upper nibble address
    };

    I2C_WriteCmdStream(pageExample, sizeof(pageExample));

    // Write twelve bytes onto screen with 0b10101010
    for(int i=0;i&lt;12;i++)
        I2C_WriteData(0xAA);</pre>
<p>Here is what it looks like.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0772/" rel="attachment wp-att-7714"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/08/IMG_0772-1024x1009.jpg" alt="" width="1024" height="1009" class="alignnone size-large wp-image-7714" srcset="https://iotexpert.com/wp-content/uploads/2019/08/IMG_0772-1024x1009.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0772-100x100.jpg 100w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0772-600x591.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0772-300x296.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0772-768x757.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0772.jpg 1155w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Reading from the Frame Buffer</h1>
<p>Now that you know how to write to the Frame Buffer, the next question is how do you read?  For instance if you want to turn on 1 pixel (of a byte) but leave the others alone can you do this? The answer is NO.  In serial mode the device only writes.  In all of the Graphics libraries that I have seen they handle this by having a Frame Buffer in the MCU as well.  Duplicated resources&#8230; oh well.</p>
<h1>My Initialization Sequence</h1>
<p>I have a function that writes an array of bytes to the command registers.  So for me to initialize the screen I just need to set up that array.  Here is my best known setup.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">    const char initializeCmds[]={
        //////// Fundamental Commands
        OLED_DISPLAYOFF,          // 0xAE Screen Off
        OLED_SETCONTRAST,         // 0x81 Set contrast control
        0x7F,                     // 0-FF ... default half way

        OLED_DISPLAYNORMAL,       // 0xA6, //Set normal display 

        //////// Scrolling Commands
        OLED_DEACTIVATE_SCROLL,   // Deactive scroll

        //////// Addressing Commands
        OLED_SETMEMORYMODE,       // 0x20, //Set memory address mode
        OLED_SETMEMORYMODE_PAGE,  // Page

        //////// Hardware Configuration Commands
        OLED_SEGREMAPINV,         // 0xA1, //Set segment re-map 
        OLED_SETMULTIPLEX,        // 0xA8 Set multiplex ratio
        0x3F,                     // Vertical Size - 1
        OLED_COMSCANDEC,          // 0xC0 Set COM output scan direction
        OLED_SETDISPLAYOFFSET,    // 0xD3 Set Display Offset
        0x00,                     //
        OLED_SETCOMPINS,          // 0xDA Set COM pins hardware configuration
        0x12,                     // Alternate com config &amp; disable com left/right
   
        //////// Timing and Driving Settings
        OLED_SETDISPLAYCLOCKDIV,  // 0xD5 Set display oscillator frequency 0-0xF /clock divide ratio 0-0xF
        0x80,                     // Default value
        OLED_SETPRECHARGE,        // 0xD9 Set pre-changed period
        0x22,                     // Default 0x22
        OLED_SETVCOMDESELECT,     // 0xDB, //Set VCOMH Deselected level
        0x20,                     // Default 

        //////// Charge pump regulator
        OLED_CHARGEPUMP,          // 0x8D Set charge pump
        OLED_CHARGEPUMP_ON,       // 0x14 VCC generated by internal DC/DC circuit

        // Turn the screen back on...       
        OLED_DISPLAYALLONRESUME,  // 0xA4, //Set entire display on/off
        OLED_DISPLAYON,           // 0xAF  //Set display on
    };
</pre>
<h1>Some Other Initialization Sequences</h1>
<p>If you look around you will find many different SSD1306 libraries.  You can run <a href="https://github.com/search?q=ssd1306" target="_blank" rel="noopener noreferrer">this</a> search on github.</p>
<p>Here is one example from https://github.com/vadzimyatskevich/SSD1306/blob/master/src/ssd1306.c  This is pretty much the same as mine except that the author put them in some other order than the data sheet.  I am not a huge fan of &#8220;ssd1306Command( SSD1306_SEGREMAP | 0x1)&#8221; but it does work.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">void  ssd1306Init(uint8_t vccstate)
{
  _font = (FONT_INFO*)&amp;ubuntuMono_24ptFontInfo;
  
    // Initialisation sequence
    ssd1306TurnOff();
    //  1. set mux ratio
    ssd1306Command(   SSD1306_SETMULTIPLEX );
    ssd1306Command(   0x3F );
    //  2. set display offset
    ssd1306Command(   SSD1306_SETDISPLAYOFFSET );
    ssd1306Command(   0x0 );
    //  3. set display start line
    ssd1306Command(   SSD1306_SETSTARTLINE | 0x0 ); 
    ssd1306Command( SSD1306_MEMORYMODE);                    // 0x20
    ssd1306Command( 0x00);                                  // 0x0 act like ks0108
    //  4. set Segment re-map A0h/A1h    
    ssd1306Command(   SSD1306_SEGREMAP | 0x1);
    //   5. Set COM Output Scan Direction C0h/C8h
    ssd1306Command(   SSD1306_COMSCANDEC);
    //  6. Set COM Pins hardware configuration DAh, 12
    ssd1306Command(   SSD1306_SETCOMPINS);
    ssd1306Command(   0x12);
    //  7. Set Contrast Control 81h, 7Fh
    ssd1306Command(   SSD1306_SETCONTRAST );
    if (vccstate == SSD1306_EXTERNALVCC) { 
        ssd1306Command(   0x9F );
    } else { 
        ssd1306Command(   0xff );
    }
    //  8. Disable Entire Display On A4h
    ssd1306Command(   SSD1306_DISPLAYALLON_RESUME);
    //  9. Set Normal Display A6h 
    ssd1306Command(   SSD1306_NORMALDISPLAY);
    //  10. Set Osc Frequency  D5h, 80h 
    ssd1306Command(   SSD1306_SETDISPLAYCLOCKDIV);
    ssd1306Command(   0x80);
    //  11. Enable charge pump regulator 8Dh, 14h 
    ssd1306Command(   SSD1306_CHARGEPUMP );
    if (vccstate == SSD1306_EXTERNALVCC) { 
        ssd1306Command(   0x10);
    } else { 
        ssd1306Command(   0x14);
    }
    //  12. Display On AFh 
    ssd1306TurnOn();

}</pre>
<p>Here is another example from git@github.com:lexus2k/ssd1306.git</p>
<p>https://github.com/lexus2k/ssd1306/blob/master/src/lcd/oled_ssd1306.c</p>
<p>Honestly if I had found this originally I would not have gone to all the trouble.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">static const uint8_t PROGMEM s_oled128x64_initData[] =
{
#ifdef SDL_EMULATION
    SDL_LCD_SSD1306,
    0x00,
#endif
    SSD1306_DISPLAYOFF, // display off
    SSD1306_MEMORYMODE, HORIZONTAL_ADDRESSING_MODE, // Page Addressing mode
    SSD1306_COMSCANDEC,             // Scan from 127 to 0 (Reverse scan)
    SSD1306_SETSTARTLINE | 0x00,    // First line to start scanning from
    SSD1306_SETCONTRAST, 0x7F,      // contast value to 0x7F according to datasheet
    SSD1306_SEGREMAP | 0x01,        // Use reverse mapping. 0x00 - is normal mapping
    SSD1306_NORMALDISPLAY,
    SSD1306_SETMULTIPLEX, 63,       // Reset to default MUX. See datasheet
    SSD1306_SETDISPLAYOFFSET, 0x00, // no offset
    SSD1306_SETDISPLAYCLOCKDIV, 0x80,// set to default ratio/osc frequency
    SSD1306_SETPRECHARGE, 0x22,     // switch precharge to 0x22 // 0xF1
    SSD1306_SETCOMPINS, 0x12,       // set divide ratio
    SSD1306_SETVCOMDETECT, 0x20,    // vcom deselect to 0x20 // 0x40
    SSD1306_CHARGEPUMP, 0x14,       // Enable charge pump
    SSD1306_DISPLAYALLON_RESUME,
    SSD1306_DISPLAYON,
};</pre>
<h1>Debug: Test the Hardware</h1>
<p>If a your screen is not working, the first thing to do is use a multimeter and make sure that VCC=SCL=SDA=3.3V.  (in the picture below my camera caught the screen refresh partially through&#8230; It looks fine at normal speed).  I have the red probe attached to the SCL.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0759/" rel="attachment wp-att-7641"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0759-1024x870.jpg" alt="" width="1024" height="870" class="alignnone size-large wp-image-7641" srcset="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0759-1024x870.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0759-600x510.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0759-300x255.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0759-768x653.jpg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>I would then run the <a href="https://iotexpert.com/?s=bridge+control" target="_blank" rel="noopener noreferrer">bridge control panel</a> and make sure that the device is responding.  You can do this by pressing &#8220;List&#8221;.  In the picture below you can see that there are two devices attached to the bus,  my screen is set to 0x78/0x3C.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-07-28-at-8-51-00-am/" rel="attachment wp-att-7640"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-8.51.00-AM-1024x818.png" alt="" width="1024" height="818" class="alignnone size-large wp-image-7640" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-8.51.00-AM-1024x818.png 1024w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-8.51.00-AM-600x480.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-8.51.00-AM-300x240.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-8.51.00-AM-768x614.png 768w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-8.51.00-AM.png 1674w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>If you don&#8217;t have the bridge control panel then you can implement I2Cdetect using your development kit.   Read about it <a href="https://iotexpert.com/2019/08/05/i2c-detect-with-psoc-6/" target="_blank" rel="noopener noreferrer">here</a>.</p>
<p><a href="https://iotexpert.com/2019/08/05/i2c-detect-with-psoc-6/screen-shot-2019-07-28-at-10-50-21-am/" rel="attachment wp-att-7658"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-10.50.21-AM-1024x852.png" alt="" width="1024" height="852" class="alignnone size-large wp-image-7658" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-10.50.21-AM-1024x852.png 1024w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-10.50.21-AM-600x499.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-10.50.21-AM-300x250.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-10.50.21-AM-768x639.png 768w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-10.50.21-AM.png 1214w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The next thing to do is attach a logic analyzer and make sure that the startup commands are coming out of your MCU correctly.  Notice that the 00, 0xAE, 0x81&#8230; are exactly the configuration sequence that I wrote in the driver code above.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/screen-shot-2019-07-28-at-11-46-45-am/" rel="attachment wp-att-7674"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.46.45-AM-1024x558.png" alt="" width="1024" height="558" class="alignnone size-large wp-image-7674" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.46.45-AM-1024x558.png 1024w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.46.45-AM-600x327.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.46.45-AM-300x163.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.46.45-AM-768x418.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Debug: Test the Firmware</h1>
<p>If your screen is still not working here are some problems and what to do about them.</p>
<ul>
<li><strong>Speckled Screen</strong></li>
<li><strong>Solid Screen</strong></li>
<li><strong>Screen Flipped in the Y direction</strong></li>
<li><strong>Screen Flipped in the X Direction</strong></li>
<li><strong>Screen Flipped in both Directions</strong></li>
<li><strong>Screen is Inverted</strong></li>
<li><strong>Image is Partially off the Screen</strong></li>
<li><strong>Image is Wrapped on the Screen</strong></li>
<li><strong>Black Screen</strong></li>
<li><strong>Screen Has Gone Crazy</strong></li>
</ul>
<p><span style="text-decoration: underline;"><strong>Speckled Screen</strong></span></p>
<p>If you have the speckled screen this means that your screen is displaying an uninitialized frame buffer which the SSD people call the GDDRAM.  These are basically the random 0 and 1s that are the startup values in the SSD1306.  If this is happening then your graphic data is probably not being transferred between your MCU and the SSD1306.  This almost certainly means you have a problem in your porting layer.</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0743/" rel="attachment wp-att-7594"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0743-1024x931.jpg" alt="" width="1024" height="931" class="alignnone size-large wp-image-7594" srcset="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0743-1024x931.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0743-600x545.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0743-300x273.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0743-768x698.jpg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<div>
<div>
<p><span style="text-decoration: underline;"><strong>Speckled Screen</strong></span></p>
<p>If your screen is solid white that probably means you turned the screen back on without resuming from the graphics ram.  You did this:</p>
</div>
</div>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">OLED_DISPLAYALLONIGNORE,  // 0xA5, //Set entire display on/off</pre>
<p>instead of this:</p>
<div>
<div>
<pre class="EnlighterJSRAW" data-enlighter-language="c">OLED_DISPLAYALLONRESUME,  // 0xA4, //Set entire display on/off</pre>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0771/" rel="attachment wp-att-7702"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/08/IMG_0771-1024x824.jpg" alt="" width="1024" height="824" class="alignnone size-large wp-image-7702" srcset="https://iotexpert.com/wp-content/uploads/2019/08/IMG_0771-1024x824.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0771-600x483.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0771-300x241.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0771-768x618.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/08/IMG_0771.jpg 1556w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p><span style="text-decoration: underline;"><strong>Screen Flipped in the Y direction</strong></span></p>
</div>
<div>The commands C0/C8 set the direction in which the com lines are scanned.  Either from top to bottom or bottom to top.  Change C0&#8211;&gt;C8 to the other way.</div>
<div>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#define OLED_COMSCANINC                               0xC0
#define OLED_COMSCANDEC                               0xC8</pre>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0746/" rel="attachment wp-att-7607"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0746-1024x924.jpg" alt="" width="1024" height="924" class="alignnone size-large wp-image-7607" srcset="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0746-1024x924.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0746-600x542.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0746-300x271.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0746-768x693.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0746.jpg 1667w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
</div>
</div>
<p><span style="text-decoration: underline;"><strong>Screen Flipped in the X Direction</strong></span></p>
<p>In the X-Direction the A0/A1 set the configuration of scanning.  Try using A0&#8211;&gt;A8 or the other way.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">// X Direction Scanning 
#define OLED_SEGREMAPNORMAL                           0xA0
#define OLED_SEGREMAPINV                              0xA1</pre>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0745/" rel="attachment wp-att-7608"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0745-1024x781.jpg" alt="" width="1024" height="781" class="alignnone size-large wp-image-7608" srcset="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0745-1024x781.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0745-600x458.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0745-300x229.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0745-768x586.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0745.jpg 1597w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p><span style="text-decoration: underline;"><strong>Screen Flipped in both Directions</strong></span></p>
<p>If it is flipped in both X and Y direction then flip both of the direction registers.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">// Y Direction
#define OLED_SEGREMAPNORMAL                           0xA0
#define OLED_SEGREMAPINV                              0xA1

// X Direction
#define OLED_COMSCANINC                               0xC0
#define OLED_COMSCANDEC                               0xC8</pre>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0748/" rel="attachment wp-att-7610"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0748-947x1024.jpg" alt="" width="947" height="1024" class="alignnone size-large wp-image-7610" srcset="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0748-947x1024.jpg 947w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0748-600x649.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0748-277x300.jpg 277w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0748-768x831.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0748.jpg 1249w" sizes="(max-width: 947px) 100vw, 947px" /></a></p>
<p><span style="text-decoration: underline;"><strong>Screen is Inverted</strong></span></p>
<p>If your screen is inverted then try A8&#8211;&gt;A6</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">#define OLED_DISPLAYNORMAL                            0xA6
#define OLED_DISPLAYINVERT                            0xA7</pre>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0749/" rel="attachment wp-att-7611"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0749-1024x972.jpg" alt="" width="1024" height="972" class="alignnone size-large wp-image-7611" srcset="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0749-1024x972.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0749-600x570.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0749-300x285.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0749-768x729.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0749.jpg 1370w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p><span style="text-decoration: underline;"><strong>Image is Partially off the Screen</strong></span></p>
<p>If your image is off the screen the you probably have the wrong value for MULTIPLEX.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">#define OLED_SETMULTIPLEX                             0xA8</pre>
<p>The parameter is supposed to be the number of lines on the screen -1.  In my case the screen is 128&#215;64 so my valued should be 63 aka 0x3F</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">        OLED_SETMULTIPLEX,        // 0xA8 Set multiplex ratio
        0x3F,                     // Vertical Size - 1</pre>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0750/" rel="attachment wp-att-7613"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0750-1024x984.jpg" alt="" width="1024" height="984" class="alignnone size-large wp-image-7613" srcset="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0750-1024x984.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0750-600x577.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0750-300x288.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0750-768x738.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0750.jpg 1389w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p><span style="text-decoration: underline;"><strong>Image is Wrapped on the Screen</strong></span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">// Double byte CMD image wrap ...probably should be 0
#define OLED_SETDISPLAYOFFSET                         0xD3</pre>
<p>The offset value allows the board designer to hook up the rows in a crazy fashion.   My screen has the top row to the top row number.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">        OLED_SETDISPLAYOFFSET,    // 0xD3 Set Display Offset
        0x00,                     //
</pre>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0751/" rel="attachment wp-att-7614"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0751-1024x1012.jpg" alt="" width="1024" height="1012" class="alignnone size-large wp-image-7614" srcset="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0751-1024x1012.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0751-100x100.jpg 100w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0751-600x593.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0751-300x296.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0751-768x759.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0751.jpg 1351w" sizes="(max-width: 1024px) 100vw, 1024px" />\</a></p>
<p><span style="text-decoration: underline;"><strong>Black Screen</strong></span></p>
<p>If you screen is totally dead&#8230;</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0752/" rel="attachment wp-att-7615"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0752-953x1024.jpg" alt="" width="953" height="1024" class="alignnone size-large wp-image-7615" srcset="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0752-953x1024.jpg 953w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0752-600x644.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0752-279x300.jpg 279w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0752-768x825.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0752.jpg 1352w" sizes="(max-width: 953px) 100vw, 953px" /></a></p>
<p>Then the charge pump may be off</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">        //////// Charge pump regulator
        OLED_CHARGEPUMP,          // 0x8D Set charge pump
        0x14,                     // VCC generated by internal DC/DC circuit
</pre>
<p>or maybe the screen is off&#8230; try turning it on.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">        OLED_DISPLAYON,           // 0xAF  //Set display on</pre>
<p>or maybe you haven&#8217;t displayed anything. The screen is off trying sending a screen invert</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#define OLED_DISPLAYINVERT                            0xA7
</pre>
<p><span style="text-decoration: underline;"><strong>The Screen Has Gone Crazy</strong></span></p>
<p>The register 0xDA SetComPins register will make some crazy results of it isn&#8217;t set correctly.  For my 0.96&#8243; inch screen it needs to be set to 0x12</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">// Double Byte Hardware com pins configuration
#define OLED_SETCOMPINS                               0xDA
// legal values 0x02, 0x12, 0x022, 0x032</pre>
<p>This is what happens with 0x02 [If you see the note below from Ivan, 0x02 is apparently for 128&#215;32 and this screen is 128&#215;64=0x12]</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0755/" rel="attachment wp-att-7617"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0755-1024x1016.jpg" alt="" width="1024" height="1016" class="alignnone size-large wp-image-7617" srcset="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0755-1024x1016.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0755-100x100.jpg 100w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0755-600x595.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0755-150x150.jpg 150w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0755-300x298.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0755-768x762.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0755.jpg 1369w" sizes="(max-width: 1024px) 100vw, 1024px" /></a> <a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0757/" rel="attachment wp-att-7618"></a></p>
<p>And 0x22</p>
<p><a href="https://iotexpert.com/?attachment_id=7619" rel="attachment wp-att-7619"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0756-999x1024.jpg" alt="" width="999" height="1024" class="alignnone size-large wp-image-7619" srcset="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0756-999x1024.jpg 999w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0756-600x615.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0756-293x300.jpg 293w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0756-768x787.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0756.jpg 1345w" sizes="(max-width: 999px) 100vw, 999px" /></a></p>
<p>Finally 0x32</p>
<p><a href="https://iotexpert.com/2019/08/07/debugging-ssd1306-display-problems/img_0757/" rel="attachment wp-att-7618"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0757-1024x1024.jpg" alt="" width="1024" height="1024" class="alignnone size-large wp-image-7618" srcset="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0757-1024x1024.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0757-300x300.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0757-100x100.jpg 100w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0757-600x600.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0757-150x150.jpg 150w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0757-768x768.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0757.jpg 1238w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>This was absolutely the craziest rabbit hole that I have ventured down. Nicholas has talked to me 10 times about doing this and he thinks I’m crazy.  Oh well.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/debugging-ssd1306-display-problems/feed/</wfw:commentRss>
			<slash:comments>53</slash:comments>
		
		
			</item>
		<item>
		<title>I2C Detect with PSoC 6</title>
		<link>https://iotexpert.com/i2c-detect-with-psoc-6/</link>
					<comments>https://iotexpert.com/i2c-detect-with-psoc-6/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 05 Aug 2019 12:30:10 +0000</pubDate>
				<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=7642</guid>

					<description><![CDATA[Summary In this article I explain how to use a PSoC 6 SCB to implement I2C Detect. Recently,  I wrote about using the Raspberry PI I2C bus master to talk to a PSoC 4 I2C Slave.  In that project I used a program on the Raspberry Pi called &#8220;I2CDetect&#8221; which probes the I2C bus and [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>In this article I explain how to use a PSoC 6 SCB to implement I2C Detect.</p>
<p>Recently,  I wrote about using the Raspberry PI I2C bus master to talk to a PSoC 4 I2C Slave.  In that project I used a program on the Raspberry Pi called &#8220;I2CDetect&#8221; which probes the I2C bus and prints out devices that are attached.  Here is what the output looks like:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">pi@iotexpertpi:~/pyGetData $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- 08 -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
pi@iotexpertpi:~/pyGetData $ 
</pre>
<p>You can do this same thing by using the bridge control panel (which comes as part of PSoC Creator).  I have used this program a bunch of times on this blog and you can search for all of those <a href="https://iotexpert.com/?s=bridge+control+panel" target="_blank" rel="noopener noreferrer">here</a>.</p>
<p><a href="https://iotexpert.com/?attachment_id=7640" rel="attachment wp-att-7640"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-8.51.00-AM-1024x818.png" alt="" width="1024" height="818" class="alignnone size-large wp-image-7640" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-8.51.00-AM-1024x818.png 1024w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-8.51.00-AM-600x480.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-8.51.00-AM-300x240.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-8.51.00-AM-768x614.png 768w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-8.51.00-AM.png 1674w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>But how does it work?  Simple, it uses the I2C bus master to iterate through all of the addresses 0-0x7F and</p>
<ul>
<li>Send a start</li>
<li>Send the address</li>
<li>Send a write</li>
<li>If you get ACK print out the address</li>
<li>If you get a NAK print out &#8212;</li>
<li>Send a stop</li>
</ul>
<p>You can easily do this using the PSoC 6 (or 4) Serial Communication Block.  Here is an implementation in Modus Toolbox 1.1 where I</p>
<ol>
<li>Create the project and configure the middleware</li>
<li>Implement probe</li>
<li>Implement the main loop</li>
<li>Test</li>
</ol>
<h1>Create the Project, Configure the Hardware and Middleware</h1>
<p>Start by creating a new project.  In this case I have a CY8CKIT_062_WIFI_BT.  But this will work on any PSoC6s.</p>
<p><a href="https://iotexpert.com/?attachment_id=7649" rel="attachment wp-att-7649"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.39.37-AM-1024x667.png" alt="" width="1024" height="667" class="alignnone size-large wp-image-7649" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.39.37-AM-1024x667.png 1024w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.39.37-AM-600x391.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.39.37-AM-300x195.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.39.37-AM-768x500.png 768w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.39.37-AM.png 1842w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>I just start with the empty project.</p>
<p><a href="https://iotexpert.com/?attachment_id=7650" rel="attachment wp-att-7650"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.39.59-AM-1024x668.png" alt="" width="1024" height="668" class="alignnone size-large wp-image-7650" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.39.59-AM-1024x668.png 1024w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.39.59-AM-600x392.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.39.59-AM-300x196.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.39.59-AM-768x501.png 768w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.39.59-AM.png 1842w" sizes="(max-width: 1024px) 100vw, 1024px" /></a> <a href="https://iotexpert.com/?attachment_id=7651" rel="attachment wp-att-7651"></a></p>
<p>Click Finish to make the project.</p>
<p><a href="https://iotexpert.com/?attachment_id=7651" rel="attachment wp-att-7651"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.40.09-AM-1024x667.png" alt="" width="1024" height="667" class="alignnone size-large wp-image-7651" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.40.09-AM-1024x667.png 1024w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.40.09-AM-600x391.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.40.09-AM-300x195.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.40.09-AM-768x500.png 768w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.40.09-AM.png 1834w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Double click on the &#8220;design.modus&#8221; or click &#8220;Configure Device&#8221; from the quick panel.</p>
<p><a href="https://iotexpert.com/?attachment_id=7661" rel="attachment wp-att-7661"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.03.53-AM.png" alt="" width="832" height="288" class="alignnone size-full wp-image-7661" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.03.53-AM.png 832w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.03.53-AM-600x208.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.03.53-AM-300x104.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.03.53-AM-768x266.png 768w" sizes="(max-width: 832px) 100vw, 832px" /></a></p>
<p>Here is the design.modus</p>
<p><a href="https://iotexpert.com/?attachment_id=7662" rel="attachment wp-att-7662"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.03.45-AM.png" alt="" width="850" height="456" class="alignnone size-large wp-image-7662" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.03.45-AM.png 850w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.03.45-AM-600x322.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.03.45-AM-300x161.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.03.45-AM-768x412.png 768w" sizes="(max-width: 850px) 100vw, 850px" /></a></p>
<p>When the configurator starts you need to enable the SCB that is connected to the Kitprog bridge.  You can figure this out by looking on the back of your development kit where there is a little table.  In the picture below you can see that the UART is connected to P5.0 and P5.1</p>
<p><a href="https://iotexpert.com/?attachment_id=7663" rel="attachment wp-att-7663"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0760-1024x915.jpg" alt="" width="1024" height="915" class="alignnone size-large wp-image-7663" srcset="https://iotexpert.com/wp-content/uploads/2019/07/IMG_0760-1024x915.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0760-600x536.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0760-300x268.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0760-768x686.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/07/IMG_0760.jpg 1855w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Which SCB is P5.0/P5.1 connected to?  The answer is SCB5.  But how do you figure that out?  Click on the Pins table.  Then select P5[0] and then Digital In/Out and you can see that the SCB 5 UART RX is attached to that pin.</p>
<p><a href="https://iotexpert.com/?attachment_id=7664" rel="attachment wp-att-7664"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.08.41-AM-1024x1014.png" alt="" width="1024" height="1014" class="alignnone size-large wp-image-7664" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.08.41-AM-1024x1014.png 1024w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.08.41-AM-100x100.png 100w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.08.41-AM-600x594.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.08.41-AM-150x150.png 150w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.08.41-AM-300x297.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.08.41-AM-768x760.png 768w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.08.41-AM.png 1420w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Cancel that and go to SCB 5.  Enable it.  Select the UART personality.  Give it the name &#8220;STDIO&#8221;.  Pick a clock divider (in this case I picked 1&#8230; but it doesn&#8217;t matter as the configurator will pick the right divide value).  Then pick the Rx/Tx to be P5[0] and P5[1]</p>
<p><a href="https://iotexpert.com/?attachment_id=7652" rel="attachment wp-att-7652"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.40.56-AM-850x1024.png" alt="" width="850" height="1024" class="alignnone size-large wp-image-7652" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.40.56-AM-850x1024.png 850w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.40.56-AM-600x723.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.40.56-AM-249x300.png 249w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.40.56-AM-768x925.png 768w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.40.56-AM.png 1532w" sizes="(max-width: 850px) 100vw, 850px" /></a></p>
<p>Next you need to turn on the I2C Master.  On my board the SCB bus that I want to use is connected to P6[0] P6[1].  The bus I want is the standard Arduino I2C pins.  I can see that from the back of the development kit (just like above).  These pins are connected to SCB3 (which I figured out just like I did with the UART).</p>
<p>Enable SCB3. Select the I2C personality.  Give it the name I2CBUS. Select Master. Make it 400kbs.  Assign a clock divider (in this case 0).  Assign the SCL and SDA pins to P6[0] and P6[1]</p>
<p><a href="https://iotexpert.com/?attachment_id=7654" rel="attachment wp-att-7654"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.42.41-AM-935x1024.png" alt="" width="935" height="1024" class="alignnone size-large wp-image-7654" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.42.41-AM-935x1024.png 935w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.42.41-AM-600x657.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.42.41-AM-274x300.png 274w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.42.41-AM-768x841.png 768w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.42.41-AM.png 1538w" sizes="(max-width: 935px) 100vw, 935px" /></a></p>
<p>Hit save.</p>
<p>For this example I want to be able to use printf.  So I right click on the &#8220;Select Middleware&#8221; from the quick panel.</p>
<p><a href="https://iotexpert.com/?attachment_id=7661" rel="attachment wp-att-7661"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.03.53-AM.png" alt="" width="832" height="288" class="alignnone size-full wp-image-7661" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.03.53-AM.png 832w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.03.53-AM-600x208.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.03.53-AM-300x104.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.03.53-AM-768x266.png 768w" sizes="(max-width: 832px) 100vw, 832px" /></a></p>
<p>Then I add &#8220;Retarget I/O&#8221;.</p>
<p><a href="https://iotexpert.com/?attachment_id=7665" rel="attachment wp-att-7665"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.35.24-AM-1024x984.png" alt="" width="1024" height="984" class="alignnone size-large wp-image-7665" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.35.24-AM-1024x984.png 1024w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.35.24-AM-600x577.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.35.24-AM-300x288.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.35.24-AM-768x738.png 768w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-9.35.24-AM.png 1708w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Once that is done you will have &#8220;stdio_user.h&#8221; and &#8220;stdio_user.c&#8221; in your Source directory:</p>
<p><a href="https://iotexpert.com/?attachment_id=7666" rel="attachment wp-att-7666"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.17.43-AM.png" alt="" width="834" height="550" class="alignnone size-full wp-image-7666" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.17.43-AM.png 834w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.17.43-AM-600x396.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.17.43-AM-300x198.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.17.43-AM-768x506.png 768w" sizes="(max-width: 834px) 100vw, 834px" /></a></p>
<p>In order to turn on printf you need to modify stdio_user.h so that it uses the right SCB for printing.  But what is that SCB?  Simple we called it &#8220;STDIO&#8221; in the configurator.  Here is the change you need to make:</p>
<pre class="start-line:171 EnlighterJSRAW" data-enlighter-language="c" ">#include "cy_device_headers.h"
#include "cycfg.h"

/* Must remain uncommented to use this utility */
#define IO_STDOUT_ENABLE
#define IO_STDIN_ENABLE
#define IO_STDOUT_UART      STDIO_HW
#define IO_STDIN_UART       STDIO_HW</pre>
<p>Edit main.c.  Add a function called &#8220;probe&#8221; which will</p>
<ol>
<li>Print a header (line 15-19)</li>
<li>Iterate through all of the addresses (line 22)</li>
<li>If you have hit the end of a line setup the next line (lines 24-25)</li>
<li>Send a start and write (line 27)</li>
<li>If you get a CY_SCB_SUCCESS then print the address (line 30)</li>
<li>Otherwise print a &#8220;&#8211;&#8221; (line 34)</li>
</ol>
<pre class="start-line:9 lang:c decode:true">// Print the probe table
void probe()
{
	uint32_t rval;

	// Setup the screen and print the header
	printf("\n\n   ");
	for(unsigned int i=0;i&lt;0x10;i++)
	{
		printf("%02X ",i);
	}

	// Iterate through the address starting at 0x00
	for(uint32_t i2caddress=0;i2caddress&lt;0x80;i2caddress++)
	{
		if(i2caddress % 0x10 == 0 )
			printf("\n%02X ",(unsigned int)i2caddress);

		rval = Cy_SCB_I2C_MasterSendStart(I2CBUS_HW,i2caddress,CY_SCB_I2C_WRITE_XFER,10,&amp;I2CBUS_context);
		if(rval == CY_SCB_I2C_SUCCESS ) // If you get ACK then print the address
		{
			printf("%02X ",(unsigned int)i2caddress);
		}
		else //  Otherwise print a --
		{
			printf("-- ");
		}
		Cy_SCB_I2C_MasterSendStop(I2CBUS_HW,0,&amp;I2CBUS_context);
	}
	printf("\n");
}
</pre>
<p>For all of this to work you need to have two context global variables which are used by PDL to save state.</p>
<pre class="start-line:5 EnlighterJSRAW" data-enlighter-language="c"">cy_stc_scb_uart_context_t STDIO_context;
cy_stc_scb_i2c_context_t I2CBUS_context;</pre>
<p>Create a main function to:</p>
<ul>
<li>initialize the two SCBs 45-50</li>
<li>The API call setvbuf on line 47 just turns off buffering on stdin so that every character will come directly to getc</li>
<li>print the header (line 54-56)</li>
<li>the clear screen line just send the VT100 escape sequence to clear the screen and go home.  Almost all terminal programs are essentially VT100 emulators.</li>
<li>run the probe one time (line 57)</li>
<li>go into an infinite loop looking for key presses (line 59-61)</li>
<li>if they press &#8216;p&#8217; then call the probe function (line 64)</li>
<li>if they press &#8216;?&#8217; then printout help (line 69)</li>
</ul>
<pre class="start-line:40 EnlighterJSRAW" data-enlighter-language="c"">int main(void)
{
    /* Set up the device based on configurator selections */
    init_cycfg_all();

    Cy_SCB_UART_Init(STDIO_HW,&amp;STDIO_config,&amp;STDIO_context);
    Cy_SCB_UART_Enable(STDIO_HW);
    setvbuf( stdin, NULL, _IONBF, 0 ); // Turn off stdin buffering

    Cy_SCB_I2C_Init(I2CBUS_HW,&amp;I2CBUS_config,&amp;I2CBUS_context);
    Cy_SCB_I2C_Enable(I2CBUS_HW);

    __enable_irq();

    printf("\033[2J\033[H"); // clear the screen
    printf("I2C Detect\n");
    printf("Press p for probe, ? for help\n");
    probe(); // Do an initial probe

    while(1)
    {
    		char c = getchar();
    		switch(c)
    		{
    		case 'p':
			probe();
    		break;
    		case '?':
    			printf("------------------\n");
			printf("Command\n");
    			printf("p\tProbe\n");
    			printf("?\tHelp\n");

    			break;
    		}

    }
}
</pre>
<p>Once I program this I get a nice output.  Notice that these are all 7-bit addresses.</p>
<p><a href="https://iotexpert.com/?attachment_id=7658" rel="attachment wp-att-7658"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-10.50.21-AM-1024x852.png" alt="" width="1024" height="852" class="alignnone size-large wp-image-7658" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-10.50.21-AM-1024x852.png 1024w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-10.50.21-AM-600x499.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-10.50.21-AM-300x250.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-10.50.21-AM-768x639.png 768w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-10.50.21-AM.png 1214w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>If I connect a logic analyzer you can see the bus behavior.  Start with a bunch of 0 &#8211; nak, 1-nak &#8230;.</p>
<p><a href="https://iotexpert.com/?attachment_id=7671" rel="attachment wp-att-7671"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.41.41-AM-1024x622.png" alt="" width="1024" height="622" class="alignnone size-large wp-image-7671" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.41.41-AM-1024x622.png 1024w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.41.41-AM-600x364.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.41.41-AM-300x182.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.41.41-AM-768x466.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>until finally it hits 3C when it get an ACK</p>
<p><a href="https://iotexpert.com/?attachment_id=7672" rel="attachment wp-att-7672"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.42.09-AM-1024x623.png" alt="" width="1024" height="623" class="alignnone size-large wp-image-7672" srcset="https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.42.09-AM-1024x623.png 1024w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.42.09-AM-600x365.png 600w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.42.09-AM-300x182.png 300w, https://iotexpert.com/wp-content/uploads/2019/07/Screen-Shot-2019-07-28-at-11.42.09-AM-768x467.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Here is the whole program</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">#include "cy_device_headers.h"
#include "cycfg.h"
#include &lt;stdio.h&gt;

cy_stc_scb_uart_context_t STDIO_context;
cy_stc_scb_i2c_context_t I2CBUS_context;

// Print the probe table
void probe()
{
	uint32_t rval;

	// Setup the screen and print the header
	printf("\n\n   ");
	for(unsigned int i=0;i&lt;0x10;i++)
	{
		printf("%02X ",i);
	}

	// Iterate through the address starting at 0x00
	for(uint32_t i2caddress=0;i2caddress&lt;0x80;i2caddress++)
	{
		if(i2caddress % 0x10 == 0 )
			printf("\n%02X ",(unsigned int)i2caddress);

		rval = Cy_SCB_I2C_MasterSendStart(I2CBUS_HW,i2caddress,CY_SCB_I2C_WRITE_XFER,10,&amp;I2CBUS_context);
		if(rval == CY_SCB_I2C_SUCCESS ) // If you get ACK then print the address
		{
			printf("%02X ",(unsigned int)i2caddress);
		}
		else //  Otherwise print a --
		{
			printf("-- ");
		}
		Cy_SCB_I2C_MasterSendStop(I2CBUS_HW,0,&amp;I2CBUS_context);
	}
	printf("\n");
}

int main(void)
{
    /* Set up the device based on configurator selections */
    init_cycfg_all();

    Cy_SCB_UART_Init(STDIO_HW,&amp;STDIO_config,&amp;STDIO_context);
    Cy_SCB_UART_Enable(STDIO_HW);
    setvbuf( stdin, NULL, _IONBF, 0 ); // Turn off stdin buffering

    Cy_SCB_I2C_Init(I2CBUS_HW,&amp;I2CBUS_config,&amp;I2CBUS_context);
    Cy_SCB_I2C_Enable(I2CBUS_HW);

    __enable_irq();

    printf("\033[2J\033[H"); // clear the screen
    printf("I2C Detect\n");
    printf("Press p for probe, ? for help\n");
    probe(); // Do an initial probe

    while(1)
    {
    		char c = getchar();
    		switch(c)
    		{
    		case 'p':
			probe();
    		break;
    		case '?':
    			printf("------------------\n");
			printf("Command\n");
    			printf("p\tProbe\n");
    			printf("?\tHelp\n");

    			break;
    		}

    }
}
</pre>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/i2c-detect-with-psoc-6/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>CY8CKIT-028-EPD and Modus Toolbox 1.1</title>
		<link>https://iotexpert.com/cy8ckit-028-epd-and-modus-toolbox-1-1/</link>
					<comments>https://iotexpert.com/cy8ckit-028-epd-and-modus-toolbox-1-1/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 15 Apr 2019 21:50:36 +0000</pubDate>
				<category><![CDATA[CY8CKIT-028-EPD]]></category>
		<category><![CDATA[CY8CKIT-062-BLE]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=6666</guid>

					<description><![CDATA[Summary One of my very influential readers is working on a project where he wants to use the CY8CKIT-028-EPD.  But, he wants to use Modus Toolbox 1.1 instead of PSoC Creator and he observed, correctly, that Cypress doesn&#8217;t have a MTB code example project for the CY8CKIT-028-EPD.  I knew that we had a working code [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>One of my very influential readers is working on a project where he wants to use the <a href="https://www.cypress.com/documentation/development-kitsboards/e-ink-display-shield-board-cy8ckit-028-epd" target="_blank" rel="noopener noreferrer">CY8CKIT-028-EPD</a>.  But, he wants to use Modus Toolbox 1.1 instead of PSoC Creator and he observed, correctly, that Cypress doesn&#8217;t have a MTB code example project for the CY8CKIT-028-EPD.  I knew that we had a working code example in PSoC Creator (<a href="https://www.cypress.com/documentation/code-examples/ce23727-psoc-6-e-ink-display-interface-emwin-graphics-library" target="_blank" rel="noopener noreferrer">CE223727</a>), so I decided to do a port to MTB1.1.  This turned out to be a bit of an adventure which required me to dig out a logic analyzer to solve self inflicted problems.  Here is a picture I took while sorting it out.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/img_0408/" rel="attachment wp-att-6668"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/IMG_0408-e1555270252695-1024x768.jpg" alt="" width="1024" height="768" class="alignnone wp-image-6668 size-large" srcset="https://iotexpert.com/wp-content/uploads/2019/04/IMG_0408-e1555270252695-1024x768.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/04/IMG_0408-e1555270252695-scaled-600x450.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/04/IMG_0408-e1555270252695-300x225.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/04/IMG_0408-e1555270252695-768x576.jpg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>There are a few things in the PSoC Creator example code which I didn&#8217;t really like, so, for the final solution, I would like it to be</p>
<ul>
<li>In Modus Toolbox 1.1</li>
<li>Using FreeRTOS</li>
<li>Using the Segger emWin graphics library</li>
<li>Getting the best response time</li>
<li>Using DMA to drive the display</li>
</ul>
<p>For this article I will go through these steps:</p>
<ol>
<li>Build CE223727 EmWin_Eink_Display in PSoC Creator</li>
<li>Explain the PSoC Creator Project</li>
<li>Create a new MTB Project &amp; add the FreeRTOS, Segger emWin and stdio middleware</li>
<li>Configure the device for the correct pins, clocks and peripherals</li>
<li>Setup FreeRTOS and Standard I/O</li>
<li>Copy the driver files into the MTB project from the PSoC Creator workspace</li>
<li>Port the drivers and eInkTask to work in MTB</li>
<li>Program and Test</li>
<li>(Part 2) Update the driver to remove the hardware timer</li>
<li>(Part 2) Update the example to remove polled switch and use a semaphore</li>
<li>(Part 2) Update the driver to use DMA</li>
<li>(Part 2) Explain how the EINK EPD Display Works</li>
</ol>
<p>If you lack patience and you just want a working project, you can download it from the <a href="https://github.com/iotexpert/eink-emwin-mtb1-1" target="_blank" rel="noopener noreferrer">IoT Expert GitHub</a> site. git@github.com:iotexpert/eink-emwin-mtb1-1.git</p>
<h1>First build CE223727 EmWin_Eink_Display in PSoC Creator</h1>
<p>Start by finding the code example project for the Eink Display.  In PSoC Creator on the File-&gt;Code Example menu you will be able to pick out the code example.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-4-53-44-pm/" rel="attachment wp-att-6679"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.53.44-PM.png" alt="" width="242" height="163" class="alignnone size-large wp-image-6679" /></a></p>
<p>There are a bunch of code examples, so the easiest way to find them is the filter based on &#8220;emwin&#8221;.  I did this because I knew we had used the Segger emWin Graphics library.  Notice in the picture below there are two emWin examples.  One with a &#8220;world&#8221; beside it and one without.  The world symbol means that it is on the internet and you will need to download it.  You can do that by clicking the world button.  Probably, you will find that your CE223727 EmWin_EInk_Display will have a world beside it and you will need to download it before you can make the project.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-4-53-26-pm/" rel="attachment wp-att-6680"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.53.26-PM.png" alt="" width="626" height="478" class="alignnone size-large wp-image-6680" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.53.26-PM.png 626w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.53.26-PM-600x458.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.53.26-PM-300x229.png 300w" sizes="(max-width: 626px) 100vw, 626px" /></a></p>
<p>Once you click create project it will ask you about the project.  Just click &#8220;next&#8221;</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-4-54-18-pm/" rel="attachment wp-att-6678"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.54.18-PM.png" alt="" width="626" height="471" class="alignnone size-large wp-image-6678" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.54.18-PM.png 626w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.54.18-PM-600x451.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.54.18-PM-300x226.png 300w" sizes="(max-width: 626px) 100vw, 626px" /></a></p>
<p>Then give your project (and workspace) a name.  I called the workspace &#8220;EPDExample&#8221; and the project &#8220;CE22&#8230;.&#8221;</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-4-54-40-pm/" rel="attachment wp-att-6677"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.54.40-PM.png" alt="" width="626" height="466" class="alignnone size-large wp-image-6677" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.54.40-PM.png 626w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.54.40-PM-600x447.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.54.40-PM-300x223.png 300w" sizes="(max-width: 626px) 100vw, 626px" /></a></p>
<p>After all of that is done you will have a schematic (and all of the other stuff required for the project).</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-4-55-50-pm/" rel="attachment wp-att-6675"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.55.50-PM-1024x791.png" alt="" width="1024" height="791" class="alignnone size-large wp-image-6675" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.55.50-PM-1024x791.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.55.50-PM-600x464.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.55.50-PM-300x232.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.55.50-PM-768x593.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.55.50-PM.png 1126w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>When you click the program button it will ask you which MCU target to program (pick either, it doesnt matter)</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-4-55-28-pm/" rel="attachment wp-att-6676"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.55.28-PM.png" alt="" width="557" height="394" class="alignnone size-large wp-image-6676" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.55.28-PM.png 557w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.55.28-PM-300x212.png 300w" sizes="(max-width: 557px) 100vw, 557px" /></a></p>
<p>After a while, your console window should look like this.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-4-59-13-pm/" rel="attachment wp-att-6681"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.59.13-PM-1024x174.png" alt="" width="1024" height="174" class="alignnone size-large wp-image-6681" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.59.13-PM-1024x174.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.59.13-PM-600x102.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.59.13-PM-300x51.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.59.13-PM-768x130.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-4.59.13-PM.png 1198w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>And you development kit should do its thing.</p>
<h1><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/img_0429/" rel="attachment wp-att-6682"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/IMG_0429-1024x632.jpg" alt="" width="1024" height="632" class="alignnone size-large wp-image-6682" srcset="https://iotexpert.com/wp-content/uploads/2019/04/IMG_0429-1024x632.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/04/IMG_0429-600x371.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/04/IMG_0429-300x185.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/04/IMG_0429-768x474.jpg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></h1>
<h1>Explain the PSoC Creator Project</h1>
<p>Now, lets have a look at the project.  Starting on the upper left hand part of the schematic you find that the interface to the EPD is via a SPI.  The SPI slave select is controlled with the Pervasive driver firmware rather than letting the SPI block directly control it.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-5-12-52-pm/" rel="attachment wp-att-6688"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.12.52-PM.png" alt="" width="436" height="232" class="alignnone size-full wp-image-6688" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.12.52-PM.png 436w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.12.52-PM-300x160.png 300w" sizes="(max-width: 436px) 100vw, 436px" /></a></p>
<p>The SPI is configured to be 16 megabits per second with CPHA=0 and CPOL=0.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-5-09-40-pm/" rel="attachment wp-att-6686"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.09.40-PM.png" alt="" width="795" height="892" class="alignnone size-large wp-image-6686" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.09.40-PM.png 795w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.09.40-PM-600x673.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.09.40-PM-267x300.png 267w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.09.40-PM-768x862.png 768w" sizes="(max-width: 795px) 100vw, 795px" /></a></p>
<p>I didn&#8217;t notice this at first, but in the picture above you can see that the actual speed of the SPI is 8.33 mbs.  That isn&#8217;t 16mbs for sure.  But why the gap?  The first thing to know is that in order for the SPI block to work correctly the input clock must be set at the desired datarate times the oversample.  What is oversample?  That is a scheme to get rid of glitchy-ness in the input signal.  In this case it will take 6 input samples to determine if the input is a 1 or a 0.  (median filter I think).  With this configuration the input clock to the SCB needs to be 16mbs * 6 = 96mhz.</p>
<p>But what is the input clock frequency?  If you click on the dwr-&gt;clocks you will see this screen which shows that the input clock is 50Mhz (the last line highlighted in blue).  Further more you can see that the source clock for the SCB is &#8220;Clk_Peri&#8221;.  When you divide 50mhz source clock rate by 6 oversample you will find that the actual bitrate is 8.33kbs.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-5-15-57-pm/" rel="attachment wp-att-6691"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.15.57-PM.png" alt="" width="786" height="777" class="alignnone size-large wp-image-6691" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.15.57-PM.png 786w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.15.57-PM-100x100.png 100w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.15.57-PM-600x593.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.15.57-PM-300x297.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.15.57-PM-768x759.png 768w" sizes="(max-width: 786px) 100vw, 786px" /></a></p>
<p>But where does the 50mhz come from?  Well, the clock system is driven by the &#8220;IMO&#8221;.  IMO stands for internal main oscillator and it is a trimmed RC oscillator built into the chip. (thanks Tim).  This oscillator runs into an FLL which up converts it to 100MHz.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-5-17-08-pm/" rel="attachment wp-att-6689"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.17.08-PM.png" alt="" width="768" height="554" class="alignnone size-full wp-image-6689" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.17.08-PM.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.17.08-PM-600x433.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.17.08-PM-300x216.png 300w" sizes="(max-width: 768px) 100vw, 768px" /></a></p>
<p>That signal is then run into the &#8220;Clk_Peri&#8221; divider which divides it by two to yield a clock of 50MHz.  Which is not all that close to 96MHz&#8230; and means that our SPI runs at the wrong speed.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-5-16-57-pm/" rel="attachment wp-att-6690"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.16.57-PM.png" alt="" width="779" height="445" class="alignnone size-large wp-image-6690" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.16.57-PM.png 779w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.16.57-PM-600x343.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.16.57-PM-300x171.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.16.57-PM-768x439.png 768w" sizes="(max-width: 779px) 100vw, 779px" /></a></p>
<p>But what does the EPD driver chip actually want?  You can find the documentation for this EPD on the Pervasive <a href="http://www.pervasivedisplays.com/products/271" target="_blank" rel="noopener noreferrer">website</a>.  That web page also has a link to the Product Specification <a href="http://www.pervasivedisplays.com/LiteratureRetrieve.aspx?ID=238025">2.7&#8243; TFT EPD Panel (E2271CS021) Rev.01</a> as well as the driver chip <a href="http://www.pervasivedisplays.com/_literature_220873/COG_Driver_Interface_Timing_for_small_size_G2_V231">COG Driver Interface Timing for small size G2 V231</a></p>
<p>When you look in the timing document you will find that the actual chip can take up to a 20Mhz input clock.  This means that our code example actually updates the screen at 42% (8.33/20) of what it could.  That gives us a chance to make things faster&#8230; which I will do after the port to MTB.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-5-25-08-pm/" rel="attachment wp-att-6692"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.25.08-PM.png" alt="" width="743" height="207" class="alignnone size-full wp-image-6692" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.25.08-PM.png 743w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.25.08-PM-600x167.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.25.08-PM-300x84.png 300w" sizes="(max-width: 743px) 100vw, 743px" /></a></p>
<p>The next sectin of the schematic has a TCPWM that is configured as a timer.  This has an input clock of 2kHz.</p>
<p>&nbsp;</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-5-10-00-pm/" rel="attachment wp-att-6685"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.10.00-PM.png" alt="" width="445" height="255" class="alignnone size-large wp-image-6685" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.10.00-PM.png 445w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.10.00-PM-300x172.png 300w" sizes="(max-width: 445px) 100vw, 445px" /></a></p>
<p>And is setup to divide by 2 which will yield a counter that updates every 1ms.  The author of this code example used the TCPWM to time operations inside of the driver (which I will also replace with something better)</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-5-10-09-pm/" rel="attachment wp-att-6684"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.10.09-PM.png" alt="" width="626" height="476" class="alignnone size-full wp-image-6684" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.10.09-PM.png 626w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.10.09-PM-600x456.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.10.09-PM-300x228.png 300w" sizes="(max-width: 626px) 100vw, 626px" /></a></p>
<p>Lastly there are some GPIOs that control various control pins on the display.  I don&#8217;t really know what all of the pins do, but will sort it out in the next article.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-5-47-16-pm/" rel="attachment wp-att-6694"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.47.16-PM.png" alt="" width="499" height="639" class="alignnone size-full wp-image-6694" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.47.16-PM.png 499w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.47.16-PM-234x300.png 234w" sizes="(max-width: 499px) 100vw, 499px" /></a></p>
<p>And all of the pins are assigned like this:</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-5-09-03-pm/" rel="attachment wp-att-6687"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.09.03-PM.png" alt="" width="670" height="297" class="alignnone size-large wp-image-6687" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.09.03-PM.png 670w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.09.03-PM-600x266.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.09.03-PM-300x133.png 300w" sizes="(max-width: 670px) 100vw, 670px" /></a></p>
<h1>Create a new MTB project &amp; Add the Middleware</h1>
<p>It is time to start the project in MTB.  Start up Modus Toolbox 1.1 and select File-&gt;New-&gt;ModusToobox IDE Application    <a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-8-57-36-am/" rel="attachment wp-att-6701"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.57.36-AM-1024x173.png" alt="" width="1024" height="173" class="alignnone size-large wp-image-6701" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.57.36-AM-1024x173.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.57.36-AM-600x101.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.57.36-AM-300x51.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.57.36-AM-768x129.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.57.36-AM.png 1614w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Then select the CY8CKIT-062-BLE Development Kit.  This kit comes with the CY8CKIT-028-EPD EINK Shield that you can see in the pictures above.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-8-58-04-am/" rel="attachment wp-att-6700"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.04-AM-1024x489.png" alt="" width="1024" height="489" class="alignnone size-large wp-image-6700" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.04-AM-1024x489.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.04-AM-600x287.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.04-AM-300x143.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.04-AM-768x367.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.04-AM.png 2030w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>I decide to call my project &#8220;EHKEink&#8221; and I derive my project from the &#8220;EmptyPSoC6App&#8221; template.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-8-58-32-am/" rel="attachment wp-att-6699"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.32-AM-1024x490.png" alt="" width="1024" height="490" class="alignnone size-large wp-image-6699" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.32-AM-1024x490.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.32-AM-600x287.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.32-AM-300x144.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.32-AM-768x367.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.32-AM.png 2032w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Once that is done, Let it rip.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-8-58-51-am/" rel="attachment wp-att-6698"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.51-AM-1024x718.png" alt="" width="1024" height="718" class="alignnone size-large wp-image-6698" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.51-AM-1024x718.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.51-AM-600x421.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.51-AM-300x210.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.51-AM-768x538.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-8.58.51-AM.png 1224w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>And you should end up with a screen that looks like this. On the left in the workspace explorer you see the main app project.  In the middle you see the readme file which explains how this project is configured.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-9-01-13-am-2/" rel="attachment wp-att-6703"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.01.13-AM-1-1024x626.png" alt="" width="1024" height="626" class="alignnone size-large wp-image-6703" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.01.13-AM-1-1024x626.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.01.13-AM-1-600x367.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.01.13-AM-1-300x183.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.01.13-AM-1-768x469.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The next step is to add the &#8220;Middleware&#8221; that we need to make this project work.  You can do this by clicking the select Middleware button from the ModusToolbox quick panel.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-9-13-02-am/" rel="attachment wp-att-6704"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.13.02-AM.png" alt="" width="708" height="852" class="alignnone size-full wp-image-6704" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.13.02-AM.png 708w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.13.02-AM-600x722.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.13.02-AM-249x300.png 249w" sizes="(max-width: 708px) 100vw, 708px" /></a></p>
<p>For this project we need</p>
<ul>
<li>FreeRTOS</li>
<li>Retarget I/O</li>
<li>Segger emWin Core, OS, no Touch, Soft FP</li>
<li>Segger emWin display driver BitPlains</li>
</ul>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-9-18-52-am/" rel="attachment wp-att-6708"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.18.52-AM-1024x911.png" alt="" width="1024" height="911" class="alignnone size-large wp-image-6708" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.18.52-AM-1024x911.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.18.52-AM-600x534.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.18.52-AM-300x267.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.18.52-AM-768x683.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.18.52-AM.png 1972w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The middleware selector will bring in all of the drivers you selected into your project.  You can see that it also adds the FreeRTOS configuration file &#8220;FreeRTOSConfig.h&#8221; as well as &#8220;stdio_user.c&#8221; etc.  These files endup in the source folder and are for you to edit.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-9-19-50-am/" rel="attachment wp-att-6707"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.19.50-AM.png" alt="" width="718" height="788" class="alignnone size-full wp-image-6707" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.19.50-AM.png 718w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.19.50-AM-600x658.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.19.50-AM-273x300.png 273w" sizes="(max-width: 718px) 100vw, 718px" /></a></p>
<p>While I was working on this, I found a bug in the emWin middleware, specifically the the configuration files for BitPlains get included twice.  To fix this you need to change the project properties and remove the path to &#8220;..components/psoc6mw/emWin/code/drivers/BitPlains/config&#8221;.  To do this, select the project in the workspace explorer then right click and select properties.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-9-22-04-am/" rel="attachment wp-att-6710"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.22.04-AM-543x1024.png" alt="" width="543" height="1024" class="alignnone size-large wp-image-6710" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.22.04-AM-543x1024.png 543w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.22.04-AM-600x1131.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.22.04-AM-159x300.png 159w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.22.04-AM-768x1447.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.22.04-AM.png 916w" sizes="(max-width: 543px) 100vw, 543px" /></a></p>
<p>Then select &#8220;C/C++ General &#8211;&gt; Paths and Symbols&#8221;.  Select the &#8220;&#8230;BitPlains/config&#8221; path and click &#8220;Delete&#8221;</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-9-22-43-am/" rel="attachment wp-att-6709"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.22.43-AM-1024x541.png" alt="" width="1024" height="541" class="alignnone size-large wp-image-6709" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.22.43-AM-1024x541.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.22.43-AM-600x317.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.22.43-AM-300x158.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.22.43-AM-768x405.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Configure the device in MTB</h1>
<p>Modus Toolbox does not have a &#8220;schematic&#8221; or a &#8220;dwr&#8221; like PSoC Creator.  In order to achieve the same functionality we built the &#8220;Configurator&#8221;.  This tool will let you setup all of the peripherals in your project.  To run it select &#8220;Configure Device&#8221; in the MTB Quick Panel.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-9-29-54-am/" rel="attachment wp-att-6712"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.29.54-AM.png" alt="" width="714" height="938" class="alignnone size-full wp-image-6712" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.29.54-AM.png 714w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.29.54-AM-600x788.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.29.54-AM-228x300.png 228w" sizes="(max-width: 714px) 100vw, 714px" /></a></p>
<p>Remember from the PSoC Creator Schematic we need to have:</p>
<ul>
<li>A bunch of pins</li>
<li>A SPI</li>
<li>A Timer</li>
<li>Plus I want a UART to connect to standard I/O.</li>
</ul>
<p>First, click on the &#8220;Pins&#8221; tab.  This lets you set all of the configuration information for each of the pins on the chip.  I will go one by one enabling the pins and setting them as digital inputs or output.  I am going to give all of the pins that exact same names that they had in the PSoC Creator Project because I know the author of that project used PDL.  When you give a pin a name in the configurator it will generate #defines or c structures based on the name.  This will make the source code the original PSoC Creator author wrote almost exactly compatible with MTB.</p>
<p>Here is an example of the first output pin which is P0[2] and is named CY_EINK_DispIoEn.  For the output pins you need to do four things.</p>
<ol>
<li>Enable the checkbox next to the pin name. (in this case P0[2])</li>
<li>Give the pin a name (CY_EINK_DispIoEn)</li>
<li>Set the drive mode (Strong Drive, Input buffer off)</li>
<li>Set the initial state of the pin (High (1))</li>
</ol>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-9-48-55-am/" rel="attachment wp-att-6716"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.48.55-AM-1024x889.png" alt="" width="1024" height="889" class="alignnone size-large wp-image-6716" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.48.55-AM-1024x889.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.48.55-AM-600x521.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.48.55-AM-300x260.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.48.55-AM-768x667.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.48.55-AM.png 1726w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Now, you need to go one by one turning on all of the output pins (Im not showing you screen shots of all of them)</p>
<p>There are two input pins for this project SW2 P0[4] and CY_EINK_DispBusy P5[3].  For these pins I will:</p>
<ol>
<li>Enable the pin checkbox</li>
<li>Give the pin a name (in this case SW2)</li>
<li>Resistive Pull-Up, Input buffer on.  Note for P5[3] the pullup resistor is not needed</li>
</ol>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-9-52-01-am/" rel="attachment wp-att-6718"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.52.01-AM-1024x894.png" alt="" width="1024" height="894" class="alignnone size-large wp-image-6718" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.52.01-AM-1024x894.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.52.01-AM-600x524.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.52.01-AM-300x262.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.52.01-AM-768x670.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.52.01-AM.png 1698w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Now that the digital pins are configured, you can setup the STDIO Uart.  This will be used to send debugging messages to the console Uart which is attached to your computer via a USB&lt;-&gt;UART bridge in KitProg 3.</p>
<p>Start by enabling SCB5 and giving it the name &#8220;UART&#8221;.  Make sure that the baud rate is set to 115200 and the rest to 8n1<a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-9-57-26-am/" rel="attachment wp-att-6720"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.57.26-AM-820x1024.png" alt="" width="820" height="1024" class="alignnone size-large wp-image-6720" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.57.26-AM-820x1024.png 820w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.57.26-AM-600x749.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.57.26-AM-240x300.png 240w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.57.26-AM-768x959.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.57.26-AM.png 1190w" sizes="(max-width: 820px) 100vw, 820px" /></a></p>
<p>Scroll down the window and pick out the RX and TX Pins plus the clock (any of the 8-bit clock dividers will do.  In this case I chose Divider 0)</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-9-58-51-am/" rel="attachment wp-att-6721"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.58.51-AM-1024x657.png" alt="" width="1024" height="657" class="alignnone size-large wp-image-6721" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.58.51-AM-1024x657.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.58.51-AM-600x385.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.58.51-AM-300x192.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.58.51-AM-768x493.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-9.58.51-AM.png 1244w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Now, you need to setup the SPI.  To do this turn on SCB 6, set it to SPI, give it the name &#8220;CY_EINK_SPIM&#8221;, set it to &#8220;Master&#8221;, fix the data rate to 1000<a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-10-01-18-am/" rel="attachment wp-att-6722"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.01.18-AM-1024x993.png" alt="" width="1024" height="993" class="alignnone size-large wp-image-6722" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.01.18-AM-1024x993.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.01.18-AM-600x582.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.01.18-AM-300x291.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.01.18-AM-768x745.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.01.18-AM.png 1524w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Then scroll down to the &#8220;Connections&#8221; section and assign the pins</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-3-48-22-pm/" rel="attachment wp-att-6744"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-3.48.22-PM-1024x588.png" alt="" width="1024" height="588" class="alignnone size-large wp-image-6744" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-3.48.22-PM-1024x588.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-3.48.22-PM-600x345.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-3.48.22-PM-300x172.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-3.48.22-PM-768x441.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-3.48.22-PM.png 1146w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The last bit of hardware we need is a timer with a 1000kHz input clock, in other words a millisecond timer.  To do this start by enabling TCPWM[1] 16-bit counter.  Call it &#8220;CY_EINK_Timer&#8221; which was the same name as the PSoC Creator project.  Then setup</p>
<ul>
<li>As a &#8220;Timer Counter&#8221;.</li>
<li>One shot</li>
<li>Up count</li>
<li>Period is 65535 (aka the max)</li>
<li>And pick &#8220;Clock signal&#8221; as 16 bit Divider</li>
</ul>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-12-26-51-pm/" rel="attachment wp-att-6736"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-12.26.51-PM-1024x858.png" alt="" width="1024" height="858" class="alignnone size-large wp-image-6736" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-12.26.51-PM-1024x858.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-12.26.51-PM-600x503.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-12.26.51-PM-300x251.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-12.26.51-PM-768x644.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-12.26.51-PM.png 1592w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Given that we want it to count milliseconds and the input has a 128 bit pre-divider&#8230; we need for the input clock to be setup to 128khz.  Click on &#8220;Peripheral clocks&#8221; then select &#8220;16 Bit Divider 0&#8221;.  Notice that the input frequency is 72Mhz and we need 128Khz&#8230; to get this a divider of 562 is required.  72mhz/128khz = 562</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-12-35-10-pm/" rel="attachment wp-att-6737"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-12.35.10-PM-1024x901.png" alt="" width="1024" height="901" class="alignnone size-large wp-image-6737" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-12.35.10-PM-1024x901.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-12.35.10-PM-600x528.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-12.35.10-PM-300x264.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-12.35.10-PM-768x676.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-12.35.10-PM.png 1412w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Setup FreeRTOS and Standard I/O</h1>
<p>The next step is to setup the &#8220;plumbing&#8221;.  In this projet we are using FreeRTOS and Standard I/O. To configure FreeRTOS just edit the &#8220;FreeRTOSConfig.h&#8221; and remove the &#8220;warning&#8221;</p>
<pre class="start-line:45 EnlighterJSRAW" data-enlighter-language="c"">#warning This is a template. Modify it according to your project and remove this line. 
</pre>
<p>Enable mutexes on line 57</p>
<pre class="start-line:57 EnlighterJSRAW" data-enlighter-language="c"">#define configUSE_MUTEXES                       1
</pre>
<p>Make the heap bigger on line 70</p>
<pre class="start-line:70 EnlighterJSRAW" data-enlighter-language="c"">#define configTOTAL_HEAP_SIZE                   1024*48
</pre>
<p>Change the memory scheme to 4 on line 194</p>
<pre class="start-line:194 EnlighterJSRAW" data-enlighter-language="c"">#define configHEAP_ALLOCATION_SCHEME                (HEAP_ALLOCATION_TYPE4)
</pre>
<p>To enable the UART to be used for Standard I/O, edit &#8220;stdio_user.h&#8221; and add the includes for &#8220;cycfg.h&#8221;.  Then update the output and input Uart to be &#8220;UART_HW&#8221; (which is the name you gave it in the configurator)</p>
<pre class="start-line:172 EnlighterJSRAW" data-enlighter-language="c"">#include "cycfg.h"
/* Must remain uncommented to use this utility */
#define IO_STDOUT_ENABLE
#define IO_STDIN_ENABLE
#define IO_STDOUT_UART      UART_HW
#define IO_STDIN_UART       UART_HW
</pre>
<p>Now make a few edits to main.c to</p>
<ul>
<li>Add includes for the configuration, rtos and standard i/o</li>
<li>Create a context for the UART</li>
<li>Create a blinking LED Task</li>
<li>In main start the UART and start the blinking LED task.</li>
</ul>
<pre class="start-line:27 EnlighterJSRAW" data-enlighter-language="c"">#include "cy_device_headers.h"
#include "cycfg.h"
#include "FreeRTOS.h"
#include "task.h"
#include &lt;stdio.h&gt;

cy_stc_scb_uart_context_t UART_context;

void blinkTask(void *arg)
{
	(void)arg;

    for(;;)
    {
    		vTaskDelay(500);
    		Cy_GPIO_Inv(LED_RED_PORT,LED_RED_PIN);
    		printf("blink\n");
    }
}
int main(void)
{
    init_cycfg_all();
    __enable_irq();

    Cy_SCB_UART_Init(UART_HW,&amp;UART_config,&amp;UART_context);
	Cy_SCB_UART_Enable(UART_HW);

  	xTaskCreate( blinkTask,"blinkTask", configMINIMAL_STACK_SIZE,  0,  1, 0  );
  	vTaskStartScheduler();
  	while(1);// Will never get here
}
</pre>
<p>As I edited the code I notice that it can&#8217;t find &#8220;LED_RED&#8221; which made me realize that I forgot to add the LED_RED attached to P0[3] in the configuration.  So, I go back and update P0[3] to be LED_RED as strong drive digital output.</p>
<p>Finally just to make sure that it is all working lets program the kit.  When I press &#8220;EHKEink Program&#8221; form the quickpanel&#8230;<a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-10-45-20-am/" rel="attachment wp-att-6725"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.45.20-AM.png" alt="" width="710" height="880" class="alignnone size-full wp-image-6725" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.45.20-AM.png 710w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.45.20-AM-600x744.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.45.20-AM-242x300.png 242w" sizes="(max-width: 710px) 100vw, 710px" /></a></p>
<p>I get this message in the console.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-10-46-38-am/" rel="attachment wp-att-6726"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.46.38-AM-1024x493.png" alt="" width="1024" height="493" class="alignnone size-large wp-image-6726" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.46.38-AM-1024x493.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.46.38-AM-600x289.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.46.38-AM-300x145.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.46.38-AM-768x370.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.46.38-AM.png 1100w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>But how can that be?  I have my kit plugged in?  In order to program your kit using Modus you need &#8220;KitProg3&#8221;.  PSoC Creator can program you kit with KitProg3 only if it is in the CMSIS-DAP HID mode.  To switch you development kit to KitProg3, you can use the program &#8220;fw-loader&#8221; which comes with MTB.  You can see what firmware you have by running &#8220;fw-loader &#8211;device-list&#8221;.  To change to KitProg 2 run &#8220;fw-loader &#8211;update-kp2&#8221; and to update to KitProg3 run &#8220;fw-loader &#8211;update-kp3&#8221;</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-14-at-5-35-26-pm/" rel="attachment wp-att-6693"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.35.26-PM.png" alt="" width="980" height="523" class="alignnone size-full wp-image-6693" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.35.26-PM.png 980w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.35.26-PM-600x320.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.35.26-PM-300x160.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-14-at-5.35.26-PM-768x410.png 768w" sizes="(max-width: 980px) 100vw, 980px" /></a></p>
<p>Now when i program I get both the LED blinking and the console printing blink.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-10-37-24-am/" rel="attachment wp-att-6728"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.37.24-AM-1024x700.png" alt="" width="1024" height="700" class="alignnone size-large wp-image-6728" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.37.24-AM-1024x700.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.37.24-AM-600x410.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.37.24-AM-300x205.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.37.24-AM-768x525.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.37.24-AM.png 1190w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Copy the files into the MTB project</h1>
<p>Next, I want to bring over the drivers from the PSoC Creator project.  They reside in folder called &#8220;eInk Library&#8221; inside of the PSoC Creator project.  You can copy them by navigating to the PSoC Creator workspace, then typing ctrl-c in the File Explorer, then clicking the &#8220;Source&#8221; directory in your Eclipse WorkSpace explorer and typing ctrl-v<a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-10-56-36-am/" rel="attachment wp-att-6730"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.56.36-AM-1024x596.png" alt="" width="1024" height="596" class="alignnone size-large wp-image-6730" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.56.36-AM-1024x596.png 1024w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.56.36-AM-600x349.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.56.36-AM-300x174.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-10.56.36-AM-768x447.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>You will also need the four files &#8220;GUIConf.c&#8221;, &#8220;GUIConf.h&#8221;, &#8220;LCDConf.h&#8221; and &#8220;LCDConf.c&#8221;.  Copy and paste them into the emWin_config directory.</p>
<p>For this project I am going to use the code that existed in &#8220;main.c&#8221; from the original PSoC Creator project.  But I want it to be a task (and a few other changes).  To facilitate things, I will copy it as well. Then rename it to eInkTask.c.  And finally, the file &#8220;Cypress Logo Full Color_png1bpp.c&#8221; needs to be copied as well.</p>
<p>After all of those copies you should have your project looking something like this:</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-3-58-04-pm/" rel="attachment wp-att-6745"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-3.58.04-PM.png" alt="" width="710" height="820" class="alignnone size-full wp-image-6745" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-3.58.04-PM.png 710w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-3.58.04-PM-600x693.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-3.58.04-PM-260x300.png 260w" sizes="(max-width: 710px) 100vw, 710px" /></a></p>
<h1>Port the Drivers and eInkTask</h1>
<p>Now we need to fix all of the driver code.  Big picture you will need to take the following actions.</p>
<ul>
<li>Update the Project settings to include the new folders (emWin_config and emWin Library)</li>
<li>Replace the PSoC Creator #include &lt;project.h&gt; with MTB #include &#8220;cycfg.h&#8221;</li>
<li>Update the files to have #include &#8220;FreeRTOS.h&#8221; and &#8220;task.h&#8221; where appropriate</li>
<li>Replace all of the CyDelay&#8217;s with vTaskDelays</li>
<li>Fix the old PSoC Creator component calls for the timer with PDL calls</li>
</ul>
<p>First go to the project settings (remember, click on the project then select properties).  Then pick &#8220;C/C++ Build Settings&#8221; then &#8220;GNU ARM Cross C Compiler&#8221; and &#8220;includes&#8221;  Press the little green &#8220;+&#8221; to add the new directories</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-11-29-00-am/" rel="attachment wp-att-6732"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-11.29.00-AM-1003x1024.png" alt="" width="1003" height="1024" class="alignnone size-large wp-image-6732" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-11.29.00-AM-1003x1024.png 1003w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-11.29.00-AM-600x612.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-11.29.00-AM-294x300.png 294w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-11.29.00-AM-768x784.png 768w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-11.29.00-AM.png 1546w" sizes="(max-width: 1003px) 100vw, 1003px" /></a></p>
<p>You can select both directories at once.</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/screen-shot-2019-04-15-at-11-28-31-am/" rel="attachment wp-att-6733"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-11.28.31-AM.png" alt="" width="794" height="782" class="alignnone size-large wp-image-6733" srcset="https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-11.28.31-AM.png 794w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-11.28.31-AM-600x591.png 600w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-11.28.31-AM-300x295.png 300w, https://iotexpert.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-15-at-11.28.31-AM-768x756.png 768w" sizes="(max-width: 794px) 100vw, 794px" /></a></p>
<p>Next edit  <strong>eInkTask.c</strong></p>
<p>Update #include &#8220;project.h&#8221; to be #include &#8220;cycfg.h&#8221; on line 59.  Add &#8220;FreeRTOS.h&#8221; and &#8220;task.h&#8221; to the includes.</p>
<pre class="start-line:59 EnlighterJSRAW" data-enlighter-language="c"">#include "cycfg.h"
#include "GUI.h"
#include "pervasive_eink_hardware_driver.h"
#include "cy_eink_library.h"
#include "LCDConf.h"
#include "FreeRTOS.h"
#include "task.h"
#include &lt;stdio.h&gt;</pre>
<p>Find and replace &#8220;CyDelay&#8221; with &#8220;vTaskDelay&#8221;</p>
<p>Update the PSoC Creator component call  _Read with the pdl calls Cy_GPIO_Read on line 661</p>
<pre class="start-line:661 EnlighterJSRAW" data-enlighter-language="c"">void WaitforSwitchPressAndRelease(void)
{
    /* Wait for SW2 to be pressed */
    while(Cy_GPIO_Read(SW2_PORT,SW2_PIN) != 0);
    
    /* Wait for SW2 to be released */
    while(Cy_GPIO_Read(SW2_PORT,SW2_PIN) == 0);
}</pre>
<p>Update the &#8220;int main(void)&#8221; to be &#8220;void eInkTask(void *arg)&#8221; on line 687</p>
<pre class="start-line:687 EnlighterJSRAW" data-enlighter-language="c" ">void eInkTask(void *arg)
{
	(void)arg;</pre>
<p>Remove &#8221; __enable_irq(); /* Enable global interrupts. */&#8221; from the old main on line 695.</p>
<p>In the file <strong>cy_eink_psoc_interface.h</strong></p>
<p>Update the #include &lt;project.h&gt; to be #include &#8220;cycfg.h&#8221; on line 59.</p>
<p>In the file <strong>cy_eink_psoc_interface.c</strong></p>
<p>Create a context for the SPIM by adding on line 58:</p>
<pre class="start-line:58 EnlighterJSRAW" data-enlighter-language="c" ">cy_stc_scb_spi_context_t CY_EINK_SPIM_context;
</pre>
<p>The three timer functions in this file use the old PSoC Creator component timer interface APIs rather than the PDL interface.  So you will need to change Cy_EINK_TimerInit, Cy_EINK_GetTimeTick and Cy_EINK_TimerStop to use PDL.</p>
<p>Here is Cy_EINK_TimerInit</p>
<pre class="start-line:76 EnlighterJSRAW" data-enlighter-language="c" ">void Cy_EINK_TimerInit(void)
{   
    /* Clear the counter value and the counter variable */
    //CY_EINK_Timer_SetCounter(0);

    Cy_TCPWM_Counter_Init (CY_EINK_Timer_HW, CY_EINK_Timer_NUM, &amp;CY_EINK_Timer_config);
    Cy_TCPWM_Counter_SetCounter	(	CY_EINK_Timer_HW, CY_EINK_Timer_NUM,0);
    
    Cy_TCPWM_Enable_Multiple(	CY_EINK_Timer_HW,CY_EINK_Timer_MASK);
    /* Initialize the Timer */
    //CY_EINK_Timer_Start();
    Cy_TCPWM_TriggerStart	(	CY_EINK_Timer_HW,CY_EINK_Timer_MASK);
}
</pre>
<p>And Cy_EINK_GetTimeTick</p>
<pre class="start-line:106 EnlighterJSRAW" data-enlighter-language="c"">uint32_t Cy_EINK_GetTimeTick(void)
{
    /* Variable used to store the time tick */
    uint32_t timingCount;
    
    /* Read the current time tick from the E-INK Timer */
    //timingCount = CY_EINK_Timer_GetCounter();
    timingCount = Cy_TCPWM_Counter_GetCounter	(CY_EINK_Timer_HW, CY_EINK_Timer_NUM);


    /* Return the current value of time tick */
    return(timingCount);
}</pre>
<p>And Cy_EINK_TimerStop</p>
<pre class="start-line:136 EnlighterJSRAW" data-enlighter-language="c"">void Cy_EINK_TimerStop(void)
{
    /* Stop the E-INK Timer */
    //CY_EINK_Timer_Disable();
	Cy_TCPWM_Counter_Disable(CY_EINK_Timer_HW, CY_EINK_Timer_NUM);

}</pre>
<p>In  the file LCDConf.h change the include to stdint.h and make the type uint8_t instead of uint8</p>
<pre class="start-line:48 EnlighterJSRAW" data-enlighter-language="c"">#include  &lt;stdint.h&gt;
    
void LCD_CopyDisplayBuffer(uint8_t * destination, int count);</pre>
<p>In the file <strong>LCDConf.c</strong> remove the #include &#8220;<span>syslib</span>/cy_syslib.h&#8221; (I have no idea why it is/was there) and then add &#8220;<span>#include</span><span> </span>&lt;stdint.h&gt;&#8221;  On line 219 change &#8220;uint8&#8221; to be &#8220;uint8_t&#8221;</p>
<pre class="start-line:219 EnlighterJSRAW" data-enlighter-language="c" ">void LCD_CopyDisplayBuffer(uint8_t * destination, int count)
</pre>
<p>In the file <strong>cy_eink_fonts.h</strong> change the &#8220;#include &lt;project.h&gt;&#8221; to be</p>
<pre class="start-line:56 EnlighterJSRAW" data-enlighter-language="c" ">#include &lt;stdint.h&gt;
#include &lt;stdbool.h&gt;</pre>
<p>In <strong>main.c</strong> add an external reference to the eInkTask on line 36 (yes this is really ugly Alan)</p>
<pre class="start-line:36 EnlighterJSRAW" data-enlighter-language="c" ">extern void eInkTask(void *);
</pre>
<p>And start the eInkTask on line 58.  Notice that I put in 10K for the stacksize&#8230; but I dont actually know how much it takes.</p>
<pre class="start-line:58 EnlighterJSRAW" data-enlighter-language="c"">  	xTaskCreate( eInkTask,"eInkTask", 1024*10,  0,  1, 0  );
</pre>
<h1>Program &amp; Test the MTB Project</h1>
<p>When you program the development kit you should have</p>
<ol>
<li>A blinking RED LED</li>
<li>The ability to scroll through a bunch of screens using the SW2 button.</li>
</ol>
<p>Here is a picture</p>
<p><a href="https://iotexpert.com/2019/04/15/cy8ckit-028-epd-and-modus-toolbox-1-1/img_0433/" rel="attachment wp-att-6747"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/04/IMG_0433-1024x608.jpg" alt="" width="1024" height="608" class="alignnone size-large wp-image-6747" srcset="https://iotexpert.com/wp-content/uploads/2019/04/IMG_0433-1024x608.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/04/IMG_0433-600x356.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/04/IMG_0433-300x178.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/04/IMG_0433-768x456.jpg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>In the next article I will:</p>
<ol>
<li>Speed up the SPI</li>
<li>Get rid of the hardware timer</li>
<li>Explain more about the EINK.</li>
</ol>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/cy8ckit-028-epd-and-modus-toolbox-1-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Matrix Orbital GTT43A: PSoC 4 Interface</title>
		<link>https://iotexpert.com/matrix-orbital-gtt43a-psoc-4-interface/</link>
					<comments>https://iotexpert.com/matrix-orbital-gtt43a-psoc-4-interface/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Thu, 24 May 2018 12:00:10 +0000</pubDate>
				<category><![CDATA[CY8CKIT-044]]></category>
		<category><![CDATA[Matrix Orbital]]></category>
		<category><![CDATA[PSoC 4200]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=5143</guid>

					<description><![CDATA[Summary In the last several articles I have written about how to use and talk to the Matrix Orbital GTT43A.  Now it is time to write some code.  The PSoC4 program that I am going to show you has evolved over time as I added stuff to it.  For instance, while I was working on [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>In the last several articles I have written about how to use and talk to the <a href="https://www.matrixorbital.com/gtt43a" target="_blank" rel="noopener">Matrix Orbital GTT43A</a>.  Now it is time to write some code.  The PSoC4 program that I am going to show you has evolved over time as I added stuff to it.  For instance, while I was working on this program I ran into a problem where the I2C Bus would hang (the subject of the next article).  As such, some of the code that is in this program was written to help me debug that problem.  With that said, I wanted a program that:</p>
<ol>
<li>Is command line driven i.e. I can interact with my program via serial commands through the PC COM Port</li>
<li>Can read 1 byte at a time (like I do on the bridge control panel)</li>
<li>Can test the &#8220;read whole packet&#8221; code</li>
<li>Can selectively send commands via a I2C or the UART</li>
<li>Send test commands to the display e.g. reset, clear</li>
<li>Test the display generated messages (like button presses)</li>
</ol>
<p>All of this code was built to run on the <a href="http://www.cypress.com/documentation/development-kitsboards/cy8ckit-044-psoc-4-m-series-pioneer-kit" target="_blank" rel="noopener">CY8CKIT-044</a> which has a PSoC 4200M MCU</p>
<h1>Schematic &amp; Pin Assignment</h1>
<p>All PSoC 4 projects start with a schematic.  In my schematic I have a UART setup to talk to the KitProg (called UART) and serve as the command processor, an I2C which directly attaches to the I2C bus that drives the display, and a UART that is also attached to the display which I called SCRUART.</p>
<p>The I2CFAIL pin in the schematic I used to help me debug the I2C problem (the subject of the next article)</p>
<p><a href="https://iotexpert.com/?attachment_id=5254" rel="attachment wp-att-5254"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-21-at-12.29.07-PM.png" alt="PSoC 4200m Schematic" width="347" height="349" class="alignnone wp-image-5254 size-full" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-21-at-12.29.07-PM.png 347w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-21-at-12.29.07-PM-100x100.png 100w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-21-at-12.29.07-PM-150x150.png 150w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-21-at-12.29.07-PM-298x300.png 298w" sizes="(max-width: 347px) 100vw, 347px" /></a></p>
<p>The pin assignment has the UART attached to the KitProg UART, the I2C attached to KitProg and the Display.  The SCRUART is attached to UART on the Display.</p>
<p><a href="https://iotexpert.com/?attachment_id=5253" rel="attachment wp-att-5253"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-21-at-12.29.18-PM.png" alt="PSoC 4200M Pin Assignment" width="456" height="204" class="alignnone wp-image-5253 size-full" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-21-at-12.29.18-PM.png 456w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-21-at-12.29.18-PM-300x134.png 300w" sizes="(max-width: 456px) 100vw, 456px" /></a></p>
<p>&nbsp;</p>
<h1>Main Event Loop</h1>
<p>The main event loop has the following parts</p>
<ol>
<li>Read a character from the keyboard</li>
<li>Process the keyboard command character</li>
<li>Read data from the screen
<ol>
<li>If you are in packet mode read a whole packet</li>
<li>If you are in streaming mode read one byte</li>
</ol>
</li>
</ol>
<p>There are three system modes.</p>
<ol>
<li>IDLE = Dont read from the screen</li>
<li>PACKET = Read whole packets (poll for complete packets)</li>
<li>STREAMING = read bytes (polling)</li>
</ol>
<p>I also have setup the program to read/write bytes to the UART and I2C.  This is called the &#8220;comInterface&#8221;.</p>
<p>The enumerated type systemMode is used to setup the polling mode (each time through the main loop, what does it do?).</p>
<pre class="start-line:18 lang:c decode:true">typedef enum {
    MODE_IDLE,
    MODE_PACKET,
    MODE_STREAMING
} systemMode_t;

systemMode_t systemMode=MODE_IDLE;

typedef enum {
    INTERFACE_I2C,
    INTERFACE_UART
} cominterface_t;

cominterface_t comInterface=INTERFACE_I2C;
</pre>
<p>The actual main section of the code</p>
<ol>
<li>Starts by initializing the UART, SCRUART and I2C.</li>
<li>On line 299 it reads a character, then switches on the character to figure out which command the user has type.</li>
</ol>
<p>You can see that &#8216;u&#8217; and &#8216;U&#8217; change the communication interface from UART to I2C and back.</p>
<pre class="start-line:285 lang:c decode:true">int main(void)
{
    CyGlobalIntEnable; /* Enable global interrupts. */
    uint32 returncode;
    
    UART_Start();
    UART_UartPutString("Started\r\n");
    I2C_Start();
    SCRUART_Start();
    
    char c;
     
    for(;;)
    {
        c = UART_UartGetChar();
        switch(c)
        {
            case 0:
            break;
            
            case 'u':
                UART_UartPutString("I2C Mode\r\n");
                comInterface = INTERFACE_I2C;
            break;
            
            case 'U':
                UART_UartPutString("UART Mode\r\n");
                comInterface = INTERFACE_UART;
            break;
</pre>
<p>The end of the loop handles the &#8220;?&#8221; case&#8230; in other words print out all of the commands.  Then based on the system mode, it either reads a whole message packet from the display or it reads only byte.</p>
<pre class="start-line:398 lang:c decode:true">           case '?':
                UART_UartPutString("------Communication Mode------\r\n");
                UART_UartPutString("u\tI2C Mode\r\n");
                UART_UartPutString("U\tUART Mode\r\n");
                
                UART_UartPutString("------GTT43A Commands------\r\n");
                UART_UartPutString("N\tDefault Comm None\r\n");
                UART_UartPutString("I\tDefault Comm I2C\r\n");
                UART_UartPutString("S\tDefault Comm Serial\r\n");
                
                UART_UartPutString("e\tEcho abc\r\n");
                UART_UartPutString("R\tReset\r\n");
                UART_UartPutString("c\tSend Clear Screen\r\n");
                
                UART_UartPutString("------Communcation Commands------\r\n");
                UART_UartPutString("r\tRead one byte if IDLE\r\n");
                UART_UartPutString("p\tRead Packet if IDLE\r\n");
                
                UART_UartPutString("------System Mode------\r\n");
                UART_UartPutString("0\tTurn I2C polling off \r\n");
                UART_UartPutString("1\tTurn on I2C packet polling\r\n");
                UART_UartPutString("2\tRead i2c bytes \r\n");
                
                UART_UartPutString("------I2C Debugging------\r\n");
                UART_UartPutString("s\tPrint SCB Status\r\n");
                UART_UartPutString("z\tSend I2C Reset Sequence\r\n");
                UART_UartPutString("x\tPrint I2C SCL and SDA value\r\n");
            break;
        }
        
        switch(systemMode)
        {
            case MODE_IDLE:
            break;
            
            case MODE_PACKET:
                readPacket();
            break;
                
            case MODE_STREAMING:
                readByte();
            break;
        }</pre>
<p>I created three keys (0,1,2) to change the system mode, from IDLE, to reading whole packets to reading bytes.</p>
<pre class="start-line:361 lang:c decode:true ">            // System Modes
            case '0':
                    I2CFAIL_Write(0);
                    UART_UartPutString("Packet Poling Off\r\n");
                    systemMode = MODE_IDLE;
                break;
               
            case '1':
                    I2CFAIL_Write(0);
                    UART_UartPutString("Packet Poling On\r\n");
                    systemMode = MODE_PACKET;
            break;
            case '2':
                    I2CFAIL_Write(0);
                    UART_UartPutString("Read continuous\r\n");
                    systemMode = MODE_STREAMING;
                    break;
</pre>
<p>While I was trying to figure out how things worked I wanted to be able to do one thing at a time. So I create &#8216;r&#8217; to read one byte (like Bridge Control Panel) and &#8216;p&#8217; to read a whole packet.  Notice that you really really only want to do this why you are not polling the display.</p>
<pre class="start-line:347 EnlighterJSRAW" data-enlighter-language="c" ">            // If you are IDLE you can read 1 byte with 'r' or read a whole packet with 'p'
            case 'r':  // Read byte
                if(systemMode != MODE_IDLE)
                    break;
                readByte(&amp;data);
                
            break;
            case 'p': // read packet
                if(systemMode == MODE_IDLE)
                    readPacketI2C();
            break;
</pre>
<p>The last section of commands send various GTT2.0 commands to the display.  Notice that the writePacket function knows which system interface to use (either I2C or UART).</p>
<p>First, I declare some commands, just an array of bytes.</p>
<pre class="start-line:6 lang:c decode:true ">// These commands come the GTT 2.0 and GTT2.5 Protocol Manuals
uint8 clearCMD[] = { 0x58 };
uint8 resetCMD[] = { 0x01};
uint8 comI2CCMD[] = { 0x05, 0x02};
uint8 comNONECMD[] = { 0x05, 0x00};
uint8 comSERIALCMD[] = { 0x05, 0x01};
uint8 comECHOCMD[] = {0xFF,'a','b','c', 0};
</pre>
<p>Then I use them:</p>
<pre class="start-line:318 EnlighterJSRAW" data-enlighter-language="c" ">            case 'e':
                UART_UartPutString("Send Echo Command\r\n");
                writePacket(sizeof(comECHOCMD) , comECHOCMD);
            break;
                
            case 'c':
                UART_UartPutString("Sent Clear String\r\n");
                writePacket(sizeof(clearCMD),clearCMD);
            break;
            case 'R':
                UART_UartPutString("Sent Reset String\r\n");
                writePacket(sizeof(resetCMD),resetCMD);
            break;
            case 'I':
                UART_UartPutString("I2C Communcation Channel\r\n");
                writePacket(sizeof(comI2CCMD),comI2CCMD);
            break;
            case 'N':
                UART_UartPutString("NONE Communcation Channel\r\n");
                writePacket(sizeof(comNONECMD),comNONECMD);
            break;</pre>
<h1>Read Byte</h1>
<p>In order to read one byte from the display I first determine which mode Im in, then call the appropriate sub-function.</p>
<pre class="start-line:269 lang:c decode:true ">uint32_t readByte(uint8_t *data)
{
    uint32_t returncode=0;
    switch(comInterface)
    {
        case INTERFACE_I2C:
            returncode = readByteI2C(data);
        break;
        case INTERFACE_UART:
            returncode = readByteUART(data);
        break;
    }
    sprintf(buff,"Returncode = %X Data=%d\r\n",(unsigned int)returncode,*data);
    UART_UartPutString(buff);

    return returncode;
}</pre>
<p>The first sub function to read bytes via I2C.  To read a byte with no error checking you have to</p>
<ol>
<li>Send a Start</li>
<li>Send the address</li>
<li>Send the Read bit</li>
<li>Clock it 8 times (this is exactly what the I2CMasterReadByte function does)</li>
<li>Send an NAK</li>
<li>Send a Stop</li>
</ol>
<p>I ran into an I2C issue which I will talk about in the next article, however, if I see an error from any of these commands Ill put the system into MODE_IDLE and throw an error.  In addition I write a 1 to the I2CFAIL pin, which I am using to trigger the Oscilliscope (so I can see what is happening)</p>
<pre class="start-line:221 lang:c decode:true ">uint32_t readByteI2C(uint8_t *data)
{
    uint32 returncode;
    returncode = I2C_I2CMasterSendStart(I2CADDR,I2C_I2C_READ_XFER_MODE , I2CTIMEOUT);
    if(returncode)
    {
        sprintf(buff,"send start error %lX status %lX\r\n",returncode,I2C_I2CMasterStatus());
        UART_UartPutString(buff);
        I2CFAIL_Write(1);
        systemMode = MODE_IDLE;
        goto cnt;
    }
            
    returncode = I2C_I2CMasterReadByte(I2C_I2C_ACK_DATA,data,I2CTIMEOUT);
    if(returncode)
    {
        sprintf(buff,"read byte error %lX status %lX sda=%d scl =%d\r\n",returncode,I2C_I2CMasterStatus(),I2C_sda_Read(),I2C_scl_Read());
        UART_UartPutString(buff);
        I2CFAIL_Write(1);
        systemMode = MODE_IDLE;
        goto cnt;
    }
            
    returncode = I2C_I2CMasterSendStop(I2CTIMEOUT);
    if(returncode)
    {
        sprintf(buff,"send stop error %lX status %lX\r\n",returncode,I2C_I2CMasterStatus());
        UART_UartPutString(buff);
        I2CFAIL_Write(1);
        systemMode = MODE_IDLE;
        goto cnt;
    }
    
    cnt:
    return returncode;
}
</pre>
<h1>Read Packet</h1>
<p>For the packet read code I did the same thing as the byte read code.  Specifically I wrote an overall get packet, then called the correct read packet based on the</p>
<p>If you read the source code that Matrix Orbital gives you for drivers, you will find that it reads one byte at a time.  The problem with doing this is that you</p>
<ol>
<li>Send a start</li>
<li>Send an I2C address</li>
<li>Send a read bit</li>
<li>Read the ACK</li>
<li>Read a byte</li>
<li>Send a NAK</li>
<li>Send a stop</li>
</ol>
<p>The problem with this approach is that it uses 11 bit-times extra per byte of overhead (steps 1-4) which kinda sucks.  So I wanted to write a complete packet reader.  My packet reader will</p>
<ol>
<li>Send a start</li>
<li>Send an I2C address</li>
<li>Send a read bit</li>
<li>Read the ACK</li>
<li>Read a byte  [This is the 254 that marks the start of the packet]</li>
<li>ACK</li>
<li>Read a byte [This is the command which identifies the packet]</li>
<li>ACK</li>
<li>Read a byte [The MSB of the Length]</li>
<li>ACK</li>
<li>Read a byte [The LSB of the Length]</li>
<li>NAK</li>
<li>If there is a length then:</li>
<li>Send the start</li>
<li>Send an I2C address</li>
<li>Send a read bit</li>
<li>Read the ACK</li>
<li>read length -1 bytes</li>
<li>ACK</li>
<li>Read the last byte</li>
<li>Send a NAK</li>
<li>Send a stop</li>
</ol>
<p>By spec you are supposed to NAK your last read byte to indicate that your read transaction is over&#8230; that means you have to NAK the last Length byte because there could be 0 bytes to read, in which case you would need to stop.  It would have been nice if the protocol let you send only one start, but Im pretty sure it was designed for UART, which doesn&#8217;t suffer from this problem.  Also as a side note, Im pretty sure that the MCU they are using doesn&#8217;t really care, but Im not willing to implement it incorrectly.</p>
<p>Here is the code:</p>
<pre class="start-line:93 lang:c decode:true ">void readPacketI2C()
{
    int length;
    int command;
    uint8_t data;
    uint32_t returncode;
    
    returncode = I2C_I2CMasterSendStart(I2CADDR,I2C_I2C_READ_XFER_MODE , I2CTIMEOUT);
    returncode |= I2C_I2CMasterReadByte(I2C_I2C_NAK_DATA,&amp;data,I2CTIMEOUT);
    returncode |= I2C_I2CMasterSendStop(I2CTIMEOUT);
    
    // Something bad happened on the I2C Bus ....
    if(returncode)
    {
        systemMode = MODE_IDLE; 
        sprintf(buff,"I2C Return Code %X\r\n",(unsigned int)returncode);
        UART_UartPutString(buff);
    }
 
    // The screen returns a 0 when there is nothing in the buffer.
    if(data == 0)
    {
        return;
    }

    // This is bad because there was something other than a packet start byte
    if(data != 252)
    {
        sprintf(buff,"bad data = %d\r\n",data);
        UART_UartPutString(buff);
        systemMode = MODE_IDLE; // put it into nothing mode...
        return;
    }
    
    // We know that we have a command
    returncode = I2C_I2CMasterSendStart(I2CADDR,I2C_I2C_READ_XFER_MODE , I2CTIMEOUT);
    returncode |= I2C_I2CMasterReadByte(I2C_I2C_ACK_DATA,&amp;data,I2CTIMEOUT); // command
    command = data;
    
    returncode |= I2C_I2CMasterReadByte(I2C_I2C_ACK_DATA,&amp;data,I2CTIMEOUT); // length
    length = data&lt;&lt;8;
    returncode |= I2C_I2CMasterReadByte(I2C_I2C_NAK_DATA,&amp;data,I2CTIMEOUT); // length
    length = length + data;
    returncode |= I2C_I2CMasterSendStop(I2CTIMEOUT);
    
    // If the packet has any data... then read it.
    if(length != 0)
    {
        returncode |= I2C_I2CMasterSendStart(I2CADDR,I2C_I2C_READ_XFER_MODE , I2CTIMEOUT);
    
        for(int i=0;i&lt;length-1; i++)
        {
            I2C_I2CMasterReadByte(I2C_I2C_ACK_DATA,&amp;data,I2CTIMEOUT); // length
            inbuff[i] = data;
        }

        // Read the last byte
        I2C_I2CMasterReadByte(I2C_I2C_NAK_DATA,&amp;data,I2CTIMEOUT); // length
        inbuff[length-1] = data;
        returncode |= I2C_I2CMasterSendStop(I2CTIMEOUT);
        
        I2C_I2CMasterSendStop(I2CTIMEOUT);
    }
      
    sprintf(buff,"command = %d length = %d bytes= ",command,length);
    UART_UartPutString(buff);
    for(int i=0;i&lt;length;i++)
    {
        sprintf(buff,"%d ",inbuff[i]);
        UART_UartPutString(buff);
    }
    UART_UartPutString("\r\n");
    
}
</pre>
<p><span><p>You can "git" these projects from</p>
<p>https://github.com/iotexpert/GTT43A</p>
<p>And the driver library from </p>
<p>https://github.com/iotexpert/GTT-Client-Library</p>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Title</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://iotexpert.com/2018/05/15/matrix-orbital-gtt43a-a-cool-display/">Matrix Orbital GTT43: A Cool Display</a></td>
</tr>

<tr><td ><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/">Matrix Orbital GTT43A: Serial Interface</a></td>
</tr>

<tr><td ><a href="https://iotexpert.com/2018/05/22/matrix-orbital-gtt43a-gtt-scripts/">Matrix Orbital GTT43A: GTT Scripts</a></td>
</tr>

<tr><td ><a href="https://iotexpert.com/2018/05/24/matrix-orbital-gtt43a-psoc-4-interface/" target="_blank" rel="noopener">Matrix Orbital GTT43A: A PSoC 4 Interface</a></td>
</tr>

<tr><td >Matrix Orbital GTT43A: Debugging the I2C</td>
</tr>

<tr><td >Matrix Orbital GTT43A: GTT Driver Library - Part 1</td>
</tr>

<tr><td >Matrix Orbital GTT43A: GTT Driver Library - Part 1</td>
</tr>

<tr><td >Matrix Orbital GTT43A: PSoC 6 using RTOS and the GTT Driver Library</td>
</tr>
</tbody></table></div></p></span></p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/matrix-orbital-gtt43a-psoc-4-interface/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Matrix Orbital GTT43A: GTT Scripts</title>
		<link>https://iotexpert.com/matrix-orbital-gtt43a-gtt-scripts/</link>
					<comments>https://iotexpert.com/matrix-orbital-gtt43a-gtt-scripts/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Tue, 22 May 2018 10:25:43 +0000</pubDate>
				<category><![CDATA[Matrix Orbital]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=5194</guid>

					<description><![CDATA[Summary As I have been working my way through understanding the Matrix Orbital displays, I think that the whole scheme for programming them is very clever.  The bottom line of this article is that Matrix Orbital created a command language for making things work in the display, then the built the rest of their toolset [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>As I have been working my way through understanding the Matrix Orbital displays, I think that the whole scheme for programming them is very clever.  The bottom line of this article is that Matrix Orbital created a command language for making things work in the display, then the built the rest of their toolset around that language.  In this article Ill show you how it is all connected.</p>
<h1>A Buffer Full of Mystery</h1>
<p>While I was trying to understand how the GTT Support Tool works, I send a &#8220;Reset Module&#8221; also known as {254, 1}.  When I ran the script, the screen rebooted, and then the serial monitor dumped out a boat load of stuff.  You can see it in the picture below:</p>
<p><a href="https://iotexpert.com/2018/05/22/matrix-orbital-gtt43a-gtt-scripts/screen-shot-2018-05-15-at-3-26-28-pm/" rel="attachment wp-att-5200"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.26.28-PM-1024x404.png" alt="" width="1024" height="404" class="alignnone size-large wp-image-5200" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.26.28-PM-1024x404.png 1024w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.26.28-PM-600x237.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.26.28-PM-300x118.png 300w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.26.28-PM-768x303.png 768w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.26.28-PM.png 1133w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>This was not very different than when I first attached to the screen using the Bridge Control Panel.  Here are the first I2C reads after the reboot.</p>
<p><a href="https://iotexpert.com/2018/05/22/matrix-orbital-gtt43a-gtt-scripts/screen-shot-2018-05-15-at-3-23-02-pm/" rel="attachment wp-att-5199"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.23.02-PM.png" alt="" width="868" height="706" class="alignnone size-full wp-image-5199" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.23.02-PM.png 868w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.23.02-PM-600x488.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.23.02-PM-300x244.png 300w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.23.02-PM-768x625.png 768w" sizes="(max-width: 868px) 100vw, 868px" /></a></p>
<p>So, what is all of this stuff?  The answer to that question resides in how this whole thing is put together.</p>
<h1>GTT Scripts</h1>
<p>All interactions with the display are done via the command language.  There are multiple paths for sending commands to the screen, the ones we have talked about so far, I2C, USB and UART.  And the one path that I have not specifically talked about but works exactly the same way, the mass storage sd-card.</p>
<p>When you design a screen in GTT Designer, what it does is take that screen, and spit out a text based command language.  Here is a screenshot of that for the test project that I am working on.</p>
<p><a href="https://iotexpert.com/2018/05/22/matrix-orbital-gtt43a-gtt-scripts/screen-shot-2018-05-15-at-3-37-04-pm/" rel="attachment wp-att-5201"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.37.04-PM.png" alt="" width="698" height="644" class="alignnone size-full wp-image-5201" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.37.04-PM.png 698w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.37.04-PM-600x554.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.37.04-PM-300x277.png 300w" sizes="(max-width: 698px) 100vw, 698px" /></a></p>
<p>Then GTT Designer compiles the text into a binary file with the GTT2.0 and GTT2.5 commands.  You can look at the binary file with a binary file editor.  Here it is for Screen1.bin</p>
<p><a href="https://iotexpert.com/2018/05/22/matrix-orbital-gtt43a-gtt-scripts/screen-shot-2018-05-15-at-3-38-45-pm/" rel="attachment wp-att-5202"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.38.45-PM.png" alt="" width="637" height="503" class="alignnone size-full wp-image-5202" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.38.45-PM.png 637w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.38.45-PM-600x474.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.38.45-PM-300x237.png 300w" sizes="(max-width: 637px) 100vw, 637px" /></a></p>
<p>And you should recognize the bytes you see.  Look at the top and you will see {FE, 05, 00} which in decimal is {254, 05, 00} and if you look in the GTT20 manual you will find that is &#8220;Set Communication Channel to None&#8221;.  Here is the screenshot from the manual.</p>
<p><a href="https://iotexpert.com/2018/05/22/matrix-orbital-gtt43a-gtt-scripts/screen-shot-2018-05-15-at-3-40-43-pm/" rel="attachment wp-att-5203"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.40.43-PM.png" alt="" width="811" height="411" class="alignnone size-full wp-image-5203" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.40.43-PM.png 811w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.40.43-PM-600x304.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.40.43-PM-300x152.png 300w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.40.43-PM-768x389.png 768w" sizes="(max-width: 811px) 100vw, 811px" /></a></p>
<p>But, what happens when the device boots?  Well, they followed the lead from MS-DOS and created a file called &#8220;autoexec&#8221;.  And, if you look in that file they so graciously tell you what happens.</p>
<p><a href="https://iotexpert.com/2018/05/22/matrix-orbital-gtt43a-gtt-scripts/screen-shot-2018-05-15-at-3-42-19-pm/" rel="attachment wp-att-5204"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.42.19-PM.png" alt="" width="595" height="413" class="alignnone size-full wp-image-5204" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.42.19-PM.png 595w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-3.42.19-PM-300x208.png 300w" sizes="(max-width: 595px) 100vw, 595px" /></a></p>
<p>How cool is that?  All of these commands are just the things that you did on the project setting and the display settings.  And the last line of the file launches just launches Screen1.bin, which is just the binary file of the commands it takes to load the Screen1.</p>
<p>Now back to the original question.  What is the buffer full of mystery?  Simple, it is the output of all of the commands (if they make output) that are in the autoexec binary and the screen1 binary.  If you had happened to set the default channel to &#8220;none&#8221; you will find that the buffer doesnt have anything in it&#8230; which should make sense.</p>
<p>So, when the manual says to delete the autoexec at the top level directory in order to reset the board.  All that does it remove all of the settings that you created in your project.</p>
<p>The only thing that I wish is that they gave you access to the txt&#8211;&gt;bin compiler.  But oh well.</p>
<p><span><p>You can "git" these projects from</p>
<p>https://github.com/iotexpert/GTT43A</p>
<p>And the driver library from </p>
<p>https://github.com/iotexpert/GTT-Client-Library</p>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Title</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://iotexpert.com/2018/05/15/matrix-orbital-gtt43a-a-cool-display/">Matrix Orbital GTT43: A Cool Display</a></td>
</tr>

<tr><td ><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/">Matrix Orbital GTT43A: Serial Interface</a></td>
</tr>

<tr><td ><a href="https://iotexpert.com/2018/05/22/matrix-orbital-gtt43a-gtt-scripts/">Matrix Orbital GTT43A: GTT Scripts</a></td>
</tr>

<tr><td ><a href="https://iotexpert.com/2018/05/24/matrix-orbital-gtt43a-psoc-4-interface/" target="_blank" rel="noopener">Matrix Orbital GTT43A: A PSoC 4 Interface</a></td>
</tr>

<tr><td >Matrix Orbital GTT43A: Debugging the I2C</td>
</tr>

<tr><td >Matrix Orbital GTT43A: GTT Driver Library - Part 1</td>
</tr>

<tr><td >Matrix Orbital GTT43A: GTT Driver Library - Part 1</td>
</tr>

<tr><td >Matrix Orbital GTT43A: PSoC 6 using RTOS and the GTT Driver Library</td>
</tr>
</tbody></table></div></p></span></p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/matrix-orbital-gtt43a-gtt-scripts/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Matrix Orbital GTT43A: Serial Interface</title>
		<link>https://iotexpert.com/matrix-orbital-gtt43a-serial-interface/</link>
					<comments>https://iotexpert.com/matrix-orbital-gtt43a-serial-interface/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Thu, 17 May 2018 12:00:46 +0000</pubDate>
				<category><![CDATA[Matrix Orbital]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=5090</guid>

					<description><![CDATA[Summary In this article I will show you how to interact with the Matrix Orbital GTT43A display using the GTT Support Tool via the KitProg UART on a CY8CKIT-044  and the Bridge Control Panel via I2C.  This article will be broken up into four parts Building a Test Project in GTT Designer GTT Protocol 2.0 [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>In this article I will show you how to interact with the Matrix Orbital <a href="https://www.matrixorbital.com/gtt43a" target="_blank" rel="noopener">GTT43A</a> display using the GTT Support Tool via the KitProg UART on a CY8CKIT-044  and the Bridge Control Panel via I2C.  This article will be broken up into four parts</p>
<ol>
<li>Building a Test Project in GTT Designer</li>
<li>GTT Protocol 2.0</li>
<li>GTT Protocol 2.5</li>
<li>GTT Support Tool</li>
<li>Bridge Control Panel</li>
</ol>
<h1>Build a Test Project</h1>
<p>In order to understand the whole serial interface, I will build a very simple project with two buttons.  You can find this project in my GitHub site at git@github.com:iotexpert/GTT43A</p>
<p>Start up a new project called &#8220;BasicTest&#8221;.  Accept the defaults for Project settings.  On the Display Settings screen change the &#8220;Default Channel&#8221; to Serial and the Flow Control to Off.  I am using the CY8CKIT-044 to talk to the screen.  On that development kit there is a KitProg which serves as a programmer (for the PSoC 4200M) and as a serial bridge.  That serial bridge does not have the flow control pins turned on.  If you leave the flow control on, the screen will never transmit and you will need to poke your eyeballs out trying to figure out why.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-12-at-12-09-44-pm/" rel="attachment wp-att-5153"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.09.44-PM.png" alt="" class="alignnone size-large wp-image-5153" width="286" height="594" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.09.44-PM.png 286w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.09.44-PM-144x300.png 144w" sizes="(max-width: 286px) 100vw, 286px" />  </a><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-15-at-10-35-00-am/" rel="attachment wp-att-5170"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-10.35.00-AM.png" alt="" class="alignnone size-full wp-image-5170" width="285" height="593" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-10.35.00-AM.png 285w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-10.35.00-AM-144x300.png 144w" sizes="(max-width: 285px) 100vw, 285px" /></a></p>
<p>Drag a Circle Button (GTT2.5) onto the screen.  Change the Text value (on the right panel) to &#8220;GTT25&#8221;</p>
<p><a href="https://iotexpert.com/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-12-at-12-10-55-pm/" rel="attachment wp-att-5151"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.10.55-PM-1024x718.png" alt="" class="alignnone wp-image-5151 size-large" width="1024" height="718" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.10.55-PM-1024x718.png 1024w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.10.55-PM-600x421.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.10.55-PM-300x210.png 300w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.10.55-PM-768x538.png 768w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.10.55-PM.png 1228w" sizes="(max-width: 1024px) 100vw, 1024px" /></a> <a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-12-at-12-03-38-pm/" rel="attachment wp-att-5149"></a></p>
<p>Now click on the &#8220;Legacy&#8221; tab and drag a &#8220;Circle Button&#8221; onto the screen.  Then change the text label to &#8220;Legacy&#8221;.  In addition change the &#8220;ID&#8221; from &#8220;Auto&#8221; to &#8220;2&#8221;.  I noticed that later in this article that if the button ID is &#8220;auto&#8221; it will not be identified in the messages.  Im not sure if this is a bug or my lack of understanding.</p>
<h1><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-12-at-12-03-38-pm/" rel="attachment wp-att-5149"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.03.38-PM-1024x664.png" alt="" class="alignnone size-large wp-image-5149" width="1024" height="664" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.03.38-PM-1024x664.png 1024w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.03.38-PM-600x389.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.03.38-PM-300x195.png 300w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.03.38-PM-768x498.png 768w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.03.38-PM.png 1246w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></h1>
<p>When I click &#8220;Deploy&#8221; I end up with this error message.  This appears to be a bug in the GTT Designer.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-12-at-12-12-22-pm/" rel="attachment wp-att-5154"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.12.22-PM.png" alt="" class="alignnone size-full wp-image-5154" width="422" height="270" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.12.22-PM.png 422w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.12.22-PM-300x192.png 300w" sizes="(max-width: 422px) 100vw, 422px" /></a></p>
<p>Click on the &#8220;Font&#8221; and go to the directory where the Font is supposed to be&#8230; and find that it is actually empty.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-12-at-12-15-01-pm/" rel="attachment wp-att-5156"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.15.01-PM.png" alt="" class="alignnone size-large wp-image-5156" width="769" height="652" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.15.01-PM.png 769w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.15.01-PM-600x509.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.15.01-PM-300x254.png 300w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.15.01-PM-768x651.png 768w" sizes="(max-width: 769px) 100vw, 769px" /></a></p>
<p>So.  I navigate up a directory and then down into &#8220;LibraSans&#8221; instead of &#8220;libra-sans-modern&#8221;.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-12-at-12-15-19-pm/" rel="attachment wp-att-5155"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.15.19-PM.png" alt="" class="alignnone size-full wp-image-5155" width="771" height="652" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.15.19-PM.png 771w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.15.19-PM-600x507.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.15.19-PM-300x254.png 300w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.15.19-PM-768x649.png 768w" sizes="(max-width: 771px) 100vw, 771px" /></a></p>
<p>Once that is done press &#8220;Deploy&#8221;, and I get Success!</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-12-at-12-45-19-pm/" rel="attachment wp-att-5157"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.45.19-PM.png" alt="" class="alignnone size-full wp-image-5157" width="585" height="441" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.45.19-PM.png 585w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.45.19-PM-300x226.png 300w" sizes="(max-width: 585px) 100vw, 585px" /></a></p>
<p>Now that I have the project built I need to wire the whole mess together.  I am going to use a <a href="http://www.cypress.com/documentation/development-kitsboards/cy8ckit-044-psoc-4-m-series-pioneer-kit" target="_blank" rel="noopener">CY8CKIT-044</a>.  This development kit has a PSoC4200M.  Although the project is using a PSoC6, I didnt have any level translators at my house (bad Alan) and I wanted to get going &#8230; so I used the 5V tolerant PSoC 4. [note: it turns out that the MCU used on the display has 5V tolerant serial I/Os but is a 3.3v MCU so I could have used it directly on the PSoC 6 without this work around]  On the far left of the development kit, right next to the USB is the KitProg connector.  This connector has an I2C Master and a UART Bridge.  In addition I can connect the I2C pins to PSoC, the Display and the Bridge.  Here is the schematic for the whole mess.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/schematic-5/" rel="attachment wp-att-5162"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/schematic-1024x595.png" alt="" class="alignnone size-large wp-image-5162" width="1024" height="595" srcset="https://iotexpert.com/wp-content/uploads/2018/05/schematic-1024x595.png 1024w, https://iotexpert.com/wp-content/uploads/2018/05/schematic-600x349.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/schematic-300x174.png 300w, https://iotexpert.com/wp-content/uploads/2018/05/schematic-768x446.png 768w, https://iotexpert.com/wp-content/uploads/2018/05/schematic.png 1165w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>When you look on the back of the CY8CKIT-044 you can see the same wiring diagram on the silkscreen.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/img_5885/" rel="attachment wp-att-5164"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/IMG_5885-1005x1024.jpg" alt="" class="alignnone size-large wp-image-5164" width="1005" height="1024" srcset="https://iotexpert.com/wp-content/uploads/2018/05/IMG_5885-1005x1024.jpg 1005w, https://iotexpert.com/wp-content/uploads/2018/05/IMG_5885-600x611.jpg 600w, https://iotexpert.com/wp-content/uploads/2018/05/IMG_5885-294x300.jpg 294w, https://iotexpert.com/wp-content/uploads/2018/05/IMG_5885-768x783.jpg 768w, https://iotexpert.com/wp-content/uploads/2018/05/IMG_5885.jpg 1841w" sizes="(max-width: 1005px) 100vw, 1005px" /></a></p>
<p>Here is a picture of the development kit.  You can see the top green/yellow wires go to P40/P41 (that is the I2C Bus) and the other green/yellow set goes to P12[6] and P12[7] that is the KitProg UART.  I suppose I should have used different colors for I2C and UART&#8230; oh well.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/img_5887/" rel="attachment wp-att-5165"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/IMG_5887-e1526145924226-1024x768.jpg" alt="" class="alignnone wp-image-5165 size-large" width="1024" height="768" srcset="https://iotexpert.com/wp-content/uploads/2018/05/IMG_5887-e1526145924226-1024x768.jpg 1024w, https://iotexpert.com/wp-content/uploads/2018/05/IMG_5887-e1526145924226-600x450.jpg 600w, https://iotexpert.com/wp-content/uploads/2018/05/IMG_5887-e1526145924226-300x225.jpg 300w, https://iotexpert.com/wp-content/uploads/2018/05/IMG_5887-e1526145924226-768x576.jpg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>And finally the whole mess.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/img_5884/" rel="attachment wp-att-5160"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/IMG_5884-768x1024.jpg" alt="" class="alignnone size-large wp-image-5160" width="768" height="1024" srcset="https://iotexpert.com/wp-content/uploads/2018/05/IMG_5884-768x1024.jpg 768w, https://iotexpert.com/wp-content/uploads/2018/05/IMG_5884-600x800.jpg 600w, https://iotexpert.com/wp-content/uploads/2018/05/IMG_5884-225x300.jpg 225w, https://iotexpert.com/wp-content/uploads/2018/05/IMG_5884-scaled.jpg 1920w" sizes="(max-width: 768px) 100vw, 768px" /></a></p>
<h1>GTT43A Protocol 2.0</h1>
<p>They way that the system works is you can send a command data packet to the display via one of the serial interfaces and then if there is a response required,  it will respond with a response data packet.  In addition when some event occurs on the display (like a touch screen button being pressed) it will send you a response data packet.</p>
<p>There are two GTT Protocols, one called 2.0 and one called 2.5.  First the <a href="https://www.matrixorbital.com/index.php?route=extension/module/product_downloads/get&amp;did=17" target="_blank" rel="noopener">2.0 protocol</a>.  You send messages in the GTT2.0 command data packet format.  That format is simple:</p>
<ol>
<li>254 &#8211; 1 byte</li>
<li>Message ID (look in the manual for all of the legal message codes) &#8211; 1 byte</li>
<li>Optional data 0-n bytes</li>
</ol>
<p>If there is a required response, the screen will respond with a data packet in the following format</p>
<ol>
<li>252 &#8211; 1 byte</li>
<li>Message ID &#8211; 1 byte</li>
<li>Length MSB &#8211; 1 byte</li>
<li>Length LSB &#8211; 1 byte</li>
<li>Optional Data &#8211; 0&#8211;&gt;65535 bytes</li>
</ol>
<p>The total length of the response will be (length msb) &lt;&lt; 8 | length lsb &#8211; big endian.</p>
<p>For example a command with no optional data &#8230;. like reset will look like this { 252, 1 }. [obviously dont send the braces or the comma]</p>
<p>A command with some optional data is &#8220;Set Backlight Brightness&#8221;. If you want the brightness set to 23% you would send is {252, 153, 23}.</p>
<p>An example of a command that will respond with a response data packet is &#8220;Get Module Type&#8221; where you would send {254, 55 } and the screen would respond with {252, 55, 00 02 147 01}.  Here is the picture from the manual.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-15-at-10-55-02-am/" rel="attachment wp-att-5171"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-10.55.02-AM.png" alt="" class="alignnone size-full wp-image-5171" width="817" height="365" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-10.55.02-AM.png 817w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-10.55.02-AM-600x268.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-10.55.02-AM-300x134.png 300w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-10.55.02-AM-768x343.png 768w" sizes="(max-width: 817px) 100vw, 817px" /></a></p>
<p>When you look at the picture above there are several things to be <strong>VERY</strong> careful about.</p>
<p>First, the Matrix Orbital people appear to think in decimal not hex.  So they show you {252,55,00,02,147,01) instead of (0xFE, 0x37, 0x00, 0x02, 0x93, 0x01}.  Notice that my GTT43A value is decimal 37633 which is also known as Hex 0x9301.  I  often found myself typing hex when I mean decimal and vice versa.</p>
<p>The second thing to be careful about is that they send values in big endian&#8230; so if you are using an ARM processor be aware as ARM is almost always little endian.</p>
<p>The third thing to be careful about is that the length parameter in the message is always 16-bit Big Endian even though the documentation often shortens this to &#8220;Length&#8221;</p>
<p>Lastly, if they send you a 16-bit value it will show up as big endian, and they will probably show it to you in decimal (like table 14 above).  Which can look kinda weird in decimal as it is two bytes.</p>
<h1>GTT43A Protocol 2.5</h1>
<p>As I worked on understanding what the screen is doing, I noticed that I was getting message codes that were not documented in the GTT2.0 Manual.  For example when you press a button you will get {252,235,0,5,21,0,0,1,1}.  When you look at this packet you can recognize the 252&#8230; and the message code 235 &#8230; and the length seems to make sense 5 &#8230; but the rest of the message is less clear.</p>
<p>So I called technical support, which is excellent, and Daniel agreed to send me a prerelease of the new manual.  When you look at the manual you will find:</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-15-at-11-23-41-am/" rel="attachment wp-att-5173"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-11.23.41-AM.png" alt="" class="alignnone size-full wp-image-5173" width="421" height="293" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-11.23.41-AM.png 421w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-11.23.41-AM-300x209.png 300w" sizes="(max-width: 421px) 100vw, 421px" /></a></p>
<p>Which makes good sense as I pressed a button, and the object ID was &#8220;1&#8221;.  The pre release version of the manual that I got seems to be missing information, but Im hopeful they will get it done and released soon.  But for now, I can work with it.  If you need a copy of the manual you will need to contact them directly.</p>
<h1>GTT Support Tool</h1>
<p>When you install GTT Designer, it will also install a program called the GTT Support Tool.  This tool will allow you to send and receive GTT messages to/from the screen.   I have the screen attached to the UART on the KitProg Serial bridge (with jumper wires).  This means I will see the screen in the Device Manger under the Ports-&gt;KitProg (see the COM5)</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-15-at-12-14-47-pm/" rel="attachment wp-att-5178"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.14.47-PM.png" alt="" class="alignnone size-full wp-image-5178" width="349" height="572" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.14.47-PM.png 349w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.14.47-PM-183x300.png 183w" sizes="(max-width: 349px) 100vw, 349px" /></a></p>
<p>You can run the GTT Support Tool from the Start menu or from the Tools menu on the GTT Designer.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-15-at-12-09-46-pm/" rel="attachment wp-att-5177"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.09.46-PM.png" alt="" class="alignnone size-large wp-image-5177" width="437" height="303" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.09.46-PM.png 437w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.09.46-PM-300x208.png 300w" sizes="(max-width: 437px) 100vw, 437px" /></a></p>
<p>When the tool starts you can pick out which ComPort to talk to and setup the Flow Control (meaning use or not CTS/RTS).  The KitProg on the 4200M does not have the CTS/RTS so you need to disable it or things will not work.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-15-at-12-10-14-pm/" rel="attachment wp-att-5176"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.10.14-PM.png" alt="" class="alignnone size-large wp-image-5176" width="752" height="560" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.10.14-PM.png 752w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.10.14-PM-600x447.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.10.14-PM-300x223.png 300w" sizes="(max-width: 752px) 100vw, 752px" /></a></p>
<p>When you press the &#8220;Test Connection&#8221; it will send a message via the UART/ComPort and wait for a response. I am not sure, but I suspect that it is sending a &#8220;Get Module&#8221; command.  In the picture below you can see that I got both the send and the receive message to work.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-15-at-12-10-32-pm/" rel="attachment wp-att-5175"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.10.32-PM.png" alt="" class="alignnone size-full wp-image-5175" width="755" height="559" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.10.32-PM.png 755w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.10.32-PM-600x444.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.10.32-PM-300x222.png 300w" sizes="(max-width: 755px) 100vw, 755px" /></a></p>
<p>I was struggling over the weekend to get the communication to work correctly.  Specifically I was not getting return messages.  It turned out that the project that you build in the GTT Designer must have &#8220;Flow Control&#8221; turned off and the Default Channel set to Serial or the serial communication responses will not work.  Remember you can set this on the &#8220;Display Settings&#8221;</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-15-at-12-26-36-pm/" rel="attachment wp-att-5180"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.26.36-PM.png" alt="" class="alignnone size-full wp-image-5180" width="281" height="214" /></a></p>
<p>You can also send the commands to set the communication channel and flow control, but I found it easier to get the project to the correct settings in the GTT Designer.</p>
<p>One you have a functional connection you can click on the &#8220;Commands&#8221; tab.  On the left of the screen you will see a list of commands (well&#8230; actually on GTT2.0 commands).  On the right side of the screen you will see your &#8220;script&#8221;, which obviously starts blank.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-15-at-12-29-50-pm/" rel="attachment wp-att-5181"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.29.50-PM.png" alt="" class="alignnone size-full wp-image-5181" width="714" height="746" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.29.50-PM.png 714w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.29.50-PM-600x627.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.29.50-PM-287x300.png 287w" sizes="(max-width: 714px) 100vw, 714px" /></a></p>
<p>The first thing that you should do is press the little split screen button just to the right of the red &#8220;X&#8221;.  When you do this it will bring up a new window that will show what is sent, and what is received.  Obviously it starts blank.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-15-at-12-32-44-pm/" rel="attachment wp-att-5182"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.32.44-PM.png" alt="" class="alignnone size-full wp-image-5182" width="639" height="441" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.32.44-PM.png 639w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.32.44-PM-600x414.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.32.44-PM-300x207.png 300w" sizes="(max-width: 639px) 100vw, 639px" /></a></p>
<p>Now you can double click on a command, like &#8220;Get Module Version&#8221; and it will bring up the command.  When you press &#8220;OK&#8221; it will add it to the script.  You CAN change the command and it will add it the script (but with a misleading name)</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-15-at-12-31-37-pm/" rel="attachment wp-att-5184"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.31.37-PM.png" alt="" class="alignnone size-full wp-image-5184" width="711" height="742" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.31.37-PM.png 711w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.31.37-PM-600x626.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.31.37-PM-287x300.png 287w" sizes="(max-width: 711px) 100vw, 711px" /></a></p>
<p>Here is what the window looks like after I add the &#8220;Get Module Type&#8221; command.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-15-at-12-37-29-pm/" rel="attachment wp-att-5185"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.37.29-PM.png" alt="" class="alignnone size-full wp-image-5185" width="716" height="209" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.37.29-PM.png 716w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.37.29-PM-600x175.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.37.29-PM-300x88.png 300w" sizes="(max-width: 716px) 100vw, 716px" /></a></p>
<p>In order to Run the command, you need to click in the script window and then press the green run button.  If you have not clicked in the script window it will not run. Once you have run the command your viewer window will look like this.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-15-at-12-40-35-pm/" rel="attachment wp-att-5187"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.40.35-PM.png" alt="" class="alignnone size-full wp-image-5187" width="639" height="443" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.40.35-PM.png 639w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.40.35-PM-600x416.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.40.35-PM-300x208.png 300w" sizes="(max-width: 639px) 100vw, 639px" /></a></p>
<p>In the window above you can see that I wrote to the serial port a {254,55} and the screen responded {252,55,0,2,147,14}.  When you decode this message don&#8217;t forget that the data above is in decimal.  In this the example the message the 147,14 is actually 0x930E which is 37646.  Unfortunately 37646 is not documented in the GTT 2.0 protocol manual (but my screen is a GTT43A).</p>
<p>Another cool thing that that happens in the Debug view is that it shows events that are initiated from the screen.  For instance in the picture below I pressed the &#8220;GTT25&#8221; button from my example project.  It show the button press and the button release.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-15-at-12-57-06-pm/" rel="attachment wp-att-5192"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.57.06-PM.png" alt="" class="alignnone size-full wp-image-5192" width="328" height="342" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.57.06-PM.png 328w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-15-at-12.57.06-PM-288x300.png 288w" sizes="(max-width: 328px) 100vw, 328px" /></a></p>
<p>&nbsp;</p>
<h1>Bridge Control Panel</h1>
<p>For my real project I want to interact with the GTT43A via I2C.  For this kind of thing I always like to use the Bridge Control Panel first. I have written a bunch of <a href="https://iotexpert.com/?s=bridge+control+panel" target="_blank" rel="noopener">articles</a> about using BCP to debug.  This allows me to act as an I2C Master and see how the device acts as a slave.  The first thing that I do is press &#8220;List Devices&#8221; on the BCP.  It shows me that there are a number of things connected to the I2C bus.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-16-at-10-21-07-am/" rel="attachment wp-att-5209"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-16-at-10.21.07-AM.png" alt="" class="alignnone size-full wp-image-5209" width="867" height="703" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-16-at-10.21.07-AM.png 867w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-16-at-10.21.07-AM-600x487.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-16-at-10.21.07-AM-300x243.png 300w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-16-at-10.21.07-AM-768x623.png 768w" sizes="(max-width: 867px) 100vw, 867px" /></a></p>
<p>You might recall that from the Display Settings that the default I2C address is 80.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-16-at-10-25-45-am/" rel="attachment wp-att-5210"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-16-at-10.25.45-AM.png" alt="" class="alignnone size-full wp-image-5210" width="284" height="274" /></a></p>
<p>That 80 is also known as 0x50 (here we go with the Hex / Decimal thing again).  Moreover that 80 (0x50) is an 8-Bit address, in other words shifted left 1 from the 7-bit address of 0x28.</p>
<p>After I verified that the screen was attached to the bridge control panel.  The next thing to do was to set the default communication via I2C.  Here is the section of the documentation</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-12-at-12-01-40-pm/" rel="attachment wp-att-5147"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.01.40-PM.png" alt="" class="alignnone size-full wp-image-5147" width="755" height="375" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.01.40-PM.png 755w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.01.40-PM-600x298.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.01.40-PM-300x149.png 300w" sizes="(max-width: 755px) 100vw, 755px" /></a></p>
<p>This means that I need to send {0xFE, ox05, 0x02}.  When I send that command I get ACKs &#8230; good.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-12-at-12-00-25-pm/" rel="attachment wp-att-5146"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.00.25-PM.png" alt="" class="alignnone size-large wp-image-5146" width="867" height="760" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.00.25-PM.png 867w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.00.25-PM-600x526.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.00.25-PM-300x263.png 300w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-12-at-12.00.25-PM-768x673.png 768w" sizes="(max-width: 867px) 100vw, 867px" /></a></p>
<p>The next thing that I do is test to make sure that the legacy button is working correctly.  When I press it and then read some bytes I get</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-16-at-10-31-33-am/" rel="attachment wp-att-5211"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-16-at-10.31.33-AM.png" alt="" class="alignnone size-full wp-image-5211" width="868" height="703" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-16-at-10.31.33-AM.png 868w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-16-at-10.31.33-AM-600x486.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-16-at-10.31.33-AM-300x243.png 300w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-16-at-10.31.33-AM-768x622.png 768w" sizes="(max-width: 868px) 100vw, 868px" /></a></p>
<p>Then I press the GTT 25 Button and get {FC,EB,00,05,15,00,00,01,01} and then {FC,EB,00,05,14,00,00,01,00} in other words a press of button ID 1 and then a release of button ID 1.</p>
<p><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/screen-shot-2018-05-16-at-10-33-27-am/" rel="attachment wp-att-5212"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-16-at-10.33.27-AM.png" alt="" class="alignnone size-full wp-image-5212" width="860" height="805" srcset="https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-16-at-10.33.27-AM.png 860w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-16-at-10.33.27-AM-600x562.png 600w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-16-at-10.33.27-AM-300x281.png 300w, https://iotexpert.com/wp-content/uploads/2018/05/Screen-Shot-2018-05-16-at-10.33.27-AM-768x719.png 768w" sizes="(max-width: 860px) 100vw, 860px" /></a></p>
<p>Now that we understand the command protocol and we know how to talk to the screen, in the next article Ill talk about GTT Scripts.</p>
<p><span><p>You can "git" these projects from</p>
<p>https://github.com/iotexpert/GTT43A</p>
<p>And the driver library from </p>
<p>https://github.com/iotexpert/GTT-Client-Library</p>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Title</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://iotexpert.com/2018/05/15/matrix-orbital-gtt43a-a-cool-display/">Matrix Orbital GTT43: A Cool Display</a></td>
</tr>

<tr><td ><a href="https://iotexpert.com/2018/05/17/matrix-orbital-gtt43a-serial-interface/">Matrix Orbital GTT43A: Serial Interface</a></td>
</tr>

<tr><td ><a href="https://iotexpert.com/2018/05/22/matrix-orbital-gtt43a-gtt-scripts/">Matrix Orbital GTT43A: GTT Scripts</a></td>
</tr>

<tr><td ><a href="https://iotexpert.com/2018/05/24/matrix-orbital-gtt43a-psoc-4-interface/" target="_blank" rel="noopener">Matrix Orbital GTT43A: A PSoC 4 Interface</a></td>
</tr>

<tr><td >Matrix Orbital GTT43A: Debugging the I2C</td>
</tr>

<tr><td >Matrix Orbital GTT43A: GTT Driver Library - Part 1</td>
</tr>

<tr><td >Matrix Orbital GTT43A: GTT Driver Library - Part 1</td>
</tr>

<tr><td >Matrix Orbital GTT43A: PSoC 6 using RTOS and the GTT Driver Library</td>
</tr>
</tbody></table></div></p></span></p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/matrix-orbital-gtt43a-serial-interface/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Bosch BMI160 w/PSoC 6 CY8CKIT-028-EPD</title>
		<link>https://iotexpert.com/bosch-bmi160-psoc-6-cy8ckit-028-epd/</link>
					<comments>https://iotexpert.com/bosch-bmi160-psoc-6-cy8ckit-028-epd/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Tue, 06 Feb 2018 13:00:04 +0000</pubDate>
				<category><![CDATA[CY8CKIT-028-EPD]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=4946</guid>

					<description><![CDATA[Summary I have been working on a bunch of PSoC 6 projects in preparation for some new videos and for use at Embedded World.  For one of those project I need a motion sensitive remote control&#8230; and conveniently enough we put a Bosch BMI160 motion sensor onto the new CY8CKIT-028-EPD shield that comes with the [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>I have been working on a bunch of PSoC 6 projects in preparation for some new videos and for use at Embedded World.  For one of those project I need a motion sensitive remote control&#8230; and conveniently enough we put a <a href="https://www.bosch-sensortec.com/bst/products/all_products/bmi160" target="_blank" rel="noopener">Bosch BMI160</a> motion sensor onto the new CY8CKIT-028-EPD shield that comes with the CY8CKIT-062-BLE development kit.</p>
<p>In this article I will show you how to make a complete test system using PSoC 6 to talk to the BMI160.  The steps are:</p>
<ol>
<li>Clone the Bosch BMI160 Driver Library</li>
<li>Create a new PSoC 6 project &amp; add the driver library</li>
<li>Create the HAL for the Bosch Driver</li>
<li>Create the main firmware and test</li>
</ol>
<h1>Clone the Bosch BMI160 Driver Library</h1>
<p>When I started this, I knew that the board had a motion sensor but I didnt know what kind.  I assumed that it was an I2C based sensor, so I attached the bridge control panel and probed the I2C bus.  But this is what it said:</p>
<p><a href="https://iotexpert.com/?attachment_id=4951" rel="attachment wp-att-4951"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.47.35-AM-1024x818.png" alt="Bridge Control Panel" width="1024" height="818" class="alignnone wp-image-4951 size-large" srcset="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.47.35-AM-1024x818.png 1024w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.47.35-AM-600x479.png 600w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.47.35-AM-300x240.png 300w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.47.35-AM-768x614.png 768w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.47.35-AM.png 1692w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>So&#8230; what the hell?  Then I looked at the board to try to figure out what was going on&#8230; and low and behold&#8230; the board that I had was a prototype that was done before we added the motion sensor.  Here it is:</p>
<p><a href="https://iotexpert.com/?attachment_id=4979" rel="attachment wp-att-4979"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/IMG_5716-e1517838436841-1024x768.jpg" alt="" width="1024" height="768" class="alignnone wp-image-4979 size-large" srcset="https://iotexpert.com/wp-content/uploads/2018/02/IMG_5716-e1517838436841-1024x768.jpg 1024w, https://iotexpert.com/wp-content/uploads/2018/02/IMG_5716-e1517838436841-600x450.jpg 600w, https://iotexpert.com/wp-content/uploads/2018/02/IMG_5716-e1517838436841-300x225.jpg 300w, https://iotexpert.com/wp-content/uploads/2018/02/IMG_5716-e1517838436841-768x576.jpg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>And here is a board with the sensor on it.</p>
<p><a href="https://iotexpert.com/?attachment_id=4950" rel="attachment wp-att-4950"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/IMG_5692-e1517672737625-1024x768.jpg" alt="CY8CKIT-028-EPD with Bosch BMI160" width="1024" height="768" class="alignnone wp-image-4950 size-large" srcset="https://iotexpert.com/wp-content/uploads/2018/02/IMG_5692-e1517672737625-1024x768.jpg 1024w, https://iotexpert.com/wp-content/uploads/2018/02/IMG_5692-e1517672737625-600x450.jpg 600w, https://iotexpert.com/wp-content/uploads/2018/02/IMG_5692-e1517672737625-300x225.jpg 300w, https://iotexpert.com/wp-content/uploads/2018/02/IMG_5692-e1517672737625-768x576.jpg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>When I plug in that board and test it with the Bridge Control Panel I get:</p>
<p><a href="https://iotexpert.com/?attachment_id=4952" rel="attachment wp-att-4952"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.47.06-AM-1024x818.png" alt="" width="1024" height="818" class="alignnone wp-image-4952 size-large" srcset="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.47.06-AM-1024x818.png 1024w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.47.06-AM-600x479.png 600w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.47.06-AM-300x240.png 300w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.47.06-AM-768x613.png 768w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.47.06-AM.png 1696w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The next thing that I did was look at the schematics.  OK, you can see that the Inertial Measurement Unit (IMU) is a BMI160 that is connected to the I2C bus.  The other cool thing is that the devkit team hooked up the two interrupt lines.  These lines are typically used for the IMU to signal the PSoC 6 that something has happened (like maybe the user started moving).</p>
<p><a href="https://iotexpert.com/?attachment_id=4947" rel="attachment wp-att-4947"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.31.56-AM-897x1024.png" alt="" width="897" height="1024" class="alignnone wp-image-4947 size-large" srcset="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.31.56-AM-897x1024.png 897w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.31.56-AM-600x685.png 600w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.31.56-AM-263x300.png 263w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.31.56-AM-768x877.png 768w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.31.56-AM.png 902w" sizes="(max-width: 897px) 100vw, 897px" /></a></p>
<p>After looking at the schematics, the next step was to look at the BMI160 <a href="https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BMI160-DS000-07.pdf" target="_blank" rel="noopener">datasheet</a> and try to figure out how to interface with the device. Typically these devices have a boatload of registers with a mind boggling number of bit fields.  This is always the un-fun part of the process.  But this time when I went to the BMI160 device page on Bosch&#8217;s website, there was a button that says &#8220;Documents and Drivers&#8221; and when you click it, there is a link to GitHub with a <a href="https://github.com/BoschSensortec/BMI160_driver" target="_blank" rel="noopener">BMI160 driver</a>.  Score!</p>
<p><a href="https://iotexpert.com/?attachment_id=4948" rel="attachment wp-att-4948"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.40.22-AM-1024x792.png" alt="" width="1024" height="792" class="alignnone wp-image-4948 size-large" srcset="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.40.22-AM-1024x792.png 1024w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.40.22-AM-600x464.png 600w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.40.22-AM-300x232.png 300w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.40.22-AM-768x594.png 768w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-10.40.22-AM.png 1712w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>To make this work you just &#8220;git clone <span>git@github.com:BoschSensortec/BMI160_driver.git&#8221;</span></p>
<h1>Create New PSoC 6 project &amp; with Bosch BMI160 driver library</h1>
<p>So, lets get on with testing it.  First create a new PSoC 63 Project</p>
<p><a href="https://iotexpert.com/?attachment_id=4959" rel="attachment wp-att-4959"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.18.53-PM.png" alt="" width="623" height="466" class="alignnone wp-image-4959 size-full" srcset="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.18.53-PM.png 623w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.18.53-PM-600x449.png 600w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.18.53-PM-300x224.png 300w" sizes="(max-width: 623px) 100vw, 623px" /></a></p>
<p>Use a blank schematic</p>
<p><a href="https://iotexpert.com/?attachment_id=4958" rel="attachment wp-att-4958"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.19.07-PM.png" alt="" width="624" height="465" class="alignnone wp-image-4958 size-full" srcset="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.19.07-PM.png 624w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.19.07-PM-600x447.png 600w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.19.07-PM-300x224.png 300w" sizes="(max-width: 624px) 100vw, 624px" /></a></p>
<p>Give it a name</p>
<p><a href="https://iotexpert.com/?attachment_id=4957" rel="attachment wp-att-4957"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.19.54-PM.png" alt="" width="622" height="468" class="alignnone wp-image-4957 size-full" srcset="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.19.54-PM.png 622w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.19.54-PM-600x451.png 600w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.19.54-PM-300x226.png 300w" sizes="(max-width: 622px) 100vw, 622px" /></a></p>
<p>Add the Retarget I/O and FreeRTOS (from the build settings menu)</p>
<p><a href="https://iotexpert.com/?attachment_id=4956" rel="attachment wp-att-4956"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.20.17-PM.png" alt="" width="698" height="667" class="alignnone wp-image-4956 size-full" srcset="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.20.17-PM.png 698w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.20.17-PM-600x573.png 600w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.20.17-PM-300x287.png 300w" sizes="(max-width: 698px) 100vw, 698px" /></a></p>
<p>Add a UART and an I2C Master</p>
<p><a href="https://iotexpert.com/?attachment_id=4955" rel="attachment wp-att-4955"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.20.46-PM.png" alt="" width="516" height="454" class="alignnone wp-image-4955 size-full" srcset="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.20.46-PM.png 516w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.20.46-PM-300x264.png 300w" sizes="(max-width: 516px) 100vw, 516px" /></a></p>
<p>To get the I2C to be a master you need to double click it and change it into a master</p>
<p><a href="https://iotexpert.com/?attachment_id=4960" rel="attachment wp-att-4960"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.25.19-PM.png" alt="" width="628" height="478" class="alignnone wp-image-4960 size-full" srcset="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.25.19-PM.png 628w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.25.19-PM-600x457.png 600w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.25.19-PM-300x228.png 300w" sizes="(max-width: 628px) 100vw, 628px" /></a></p>
<p>Then assign the pins</p>
<p><a href="https://iotexpert.com/?attachment_id=4954" rel="attachment wp-att-4954"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.21.08-PM.png" alt="" width="1108" height="844" class="alignnone wp-image-4954 size-full" srcset="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.21.08-PM.png 1108w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.21.08-PM-600x457.png 600w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.21.08-PM-300x229.png 300w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.21.08-PM-768x585.png 768w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.21.08-PM-1024x780.png 1024w" sizes="(max-width: 1108px) 100vw, 1108px" /></a></p>
<p>Run &#8220;Build -&gt; Generate Application&#8221; to get all of the PDL firmware you need.</p>
<p>Edit stdio_user.h to use the UART (scan down the stdio_user.h to find the right place)</p>
<pre class="lang:c decode:true">#include "project.h"
/* Must remain uncommented to use this utility */
#define IO_STDOUT_ENABLE
#define IO_STDIN_ENABLE
#define IO_STDOUT_UART      UART_1_HW
#define IO_STDIN_UART       UART_1_HW</pre>
<p>Add the &#8220;BMI_driver&#8221; directory to the include path of the CM4 project.  (To get to this menu right click the project and pick &#8220;build settings&#8221;)</p>
<p><a href="https://iotexpert.com/?attachment_id=4961" rel="attachment wp-att-4961"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.31.53-PM.png" alt="" width="1052" height="732" class="alignnone wp-image-4961 size-full" srcset="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.31.53-PM.png 1052w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.31.53-PM-600x417.png 600w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.31.53-PM-300x209.png 300w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.31.53-PM-768x534.png 768w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.31.53-PM-1024x713.png 1024w" sizes="(max-width: 1052px) 100vw, 1052px" /></a></p>
<p>Add the Bosch Driver files to the project</p>
<p><a href="https://iotexpert.com/?attachment_id=4963" rel="attachment wp-att-4963"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.44.09-PM.png" alt="" width="442" height="291" class="alignnone wp-image-4963 size-full" srcset="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.44.09-PM.png 442w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.44.09-PM-300x198.png 300w" sizes="(max-width: 442px) 100vw, 442px" /></a></p>
<p>&nbsp;</p>
<p><a href="https://iotexpert.com/?attachment_id=4962" rel="attachment wp-att-4962"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.44.28-PM.png" alt="" width="957" height="866" class="alignnone wp-image-4962 size-full" srcset="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.44.28-PM.png 957w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.44.28-PM-600x543.png 600w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.44.28-PM-300x271.png 300w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.44.28-PM-768x695.png 768w" sizes="(max-width: 957px) 100vw, 957px" /></a></p>
<h1>Create the HAL for the Bosch driver</h1>
<p>It is simple to use the Bosch driver.  All you need to do is update the HAL.</p>
<ol>
<li>Provide a function to write I2C registers</li>
<li>Provide a function to read I2C registers</li>
<li>Provide a function to delay for a specified number of milliseconds</li>
<li>Create a structure to hold initialization information and function pointers</li>
</ol>
<p>This device implements what Cypress calls the &#8220;EZI2C&#8221; protocol which is also known as an I2C EEPROM protocol.  The device is organized as an array of registers.  Each register has an address from 0-&gt;0xFF (a single byte of addresses).  To write to a register you need to</p>
<ol>
<li>Send an I2C Start</li>
<li>Send the 7-bit I2C address</li>
<li>Send a write bit (aka a 0)</li>
<li>Send the register address you want to write to (dont confuse I2C address with the internal BMI160 address)</li>
<li>Send the 8-bit value that you want to write</li>
<li>Send a stop</li>
</ol>
<p>A cool thing with EZI2C is that it keeps track of the address, and automatically increments the register address each time you write.  This means you can write a sequence of address without having to do a complete transaction for each address.</p>
<p>Given that introduction the write function is simple:</p>
<pre class="lang:c decode:true " title="I2C Write Function">static int8_t BMI160BurstWrite(uint8_t dev_addr, uint8_t reg_addr,uint8_t *data, uint16_t len)
{
    
    Cy_SCB_I2C_MasterSendStart(I2C_1_HW,dev_addr,CY_SCB_I2C_WRITE_XFER,0,&amp;I2C_1_context);
    Cy_SCB_I2C_MasterWriteByte(I2C_1_HW,reg_addr,0,&amp;I2C_1_context);
    for(int i = 0;i&lt;len; i++)
    { 
        Cy_SCB_I2C_MasterWriteByte(I2C_1_HW,data[i],0,&amp;I2C_1_context);
    }
    
    Cy_SCB_I2C_MasterSendStop(I2C_1_HW,0,&amp;I2C_1_context);
    
    return 0;
}</pre>
<p>In order to read you do a similar transaction to write.  Specifically the steps are:</p>
<ol>
<li>Send an I2C Start</li>
<li>Send the 7-bit I2c address</li>
<li>Send a WRITE bit aka 0</li>
<li>Send the address of the register you want to read</li>
<li>Send an I2C re-start</li>
<li>Read a byte</li>
<li>Send a NAK</li>
<li>Send a stop</li>
</ol>
<p>The read transaction is similar to the write in that you can continue to read sequential bytes by sending an ACK.  The last byte you read should be NAK-ed to tell the remote device that you are done reading. Given that the code is also straight forward.</p>
<pre class="lang:c decode:true " title="I2C Read Function">// This function supports the BMP180 library and read I2C Registers
static int8_t BMI160BurstRead(uint8_t dev_addr, uint8_t reg_addr,uint8_t *data, uint16_t len)
{
    
    Cy_SCB_I2C_MasterSendStart(I2C_1_HW,dev_addr,CY_SCB_I2C_WRITE_XFER,0,&amp;I2C_1_context);
    Cy_SCB_I2C_MasterWriteByte(I2C_1_HW,reg_addr,0,&amp;I2C_1_context);
    Cy_SCB_I2C_MasterSendReStart(I2C_1_HW,dev_addr,CY_SCB_I2C_READ_XFER,0,&amp;I2C_1_context);
    for(int i = 0;i&lt;len-1; i++)
    {
        Cy_SCB_I2C_MasterReadByte(I2C_1_HW,CY_SCB_I2C_ACK,&amp;data[i],0,&amp;I2C_1_context);
    }
    Cy_SCB_I2C_MasterReadByte(I2C_1_HW,CY_SCB_I2C_NAK,&amp;data[len-1],0,&amp;I2C_1_context);
    
    Cy_SCB_I2C_MasterSendStop(I2C_1_HW,0,&amp;I2C_1_context);
    
    
    return 0;
}
</pre>
<p>There is one error with both my read and write functions.  And that error is?  No error checking.  I have seen some intermittent weirdness in which the I2C bus gets locked that ends up requiring a reset to fix.  This could be prevented by checking error codes on the I2C functions.</p>
<p>Now that we have a read and write function we can setup our device:  To do this:</p>
<ol>
<li>Setup a structure of type bmi160_dev</li>
<li>Initialize the function pointers</li>
<li>Initialize the settings for the device</li>
<li>Finally send the settings</li>
</ol>
<pre class="lang:c decode:true">static struct bmi160_dev bmi160Dev;

static void sensorsDeviceInit(void)
{

  int8_t rslt;
  vTaskDelay(500); // guess

  /* BMI160 */
  bmi160Dev.read = (bmi160_com_fptr_t)BMI160BurstRead;
  bmi160Dev.write = (bmi160_com_fptr_t)BMI160BurstWrite;
  bmi160Dev.delay_ms = (bmi160_delay_fptr_t)vTaskDelay;
  
  bmi160Dev.id = BMI160_I2C_ADDR;  // I2C device address

  rslt = bmi160_init(&amp;bmi160Dev); // initialize the device
  if (rslt == 0)
    {
      printf("BMI160 I2C connection [OK].\n");
      bmi160Dev.gyro_cfg.odr = BMI160_GYRO_ODR_800HZ;
      bmi160Dev.gyro_cfg.range = BMI160_GYRO_RANGE_125_DPS;
      bmi160Dev.gyro_cfg.bw = BMI160_GYRO_BW_OSR4_MODE;

      /* Select the power mode of Gyroscope sensor */
      bmi160Dev.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE;

      bmi160Dev.accel_cfg.odr = BMI160_ACCEL_ODR_1600HZ;
      bmi160Dev.accel_cfg.range = BMI160_ACCEL_RANGE_4G;
      bmi160Dev.accel_cfg.bw = BMI160_ACCEL_BW_OSR4_AVG1;
      bmi160Dev.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;

      /* Set the sensor configuration */
      bmi160_set_sens_conf(&amp;bmi160Dev);
      bmi160Dev.delay_ms(50);
    }
  else
    {
      printf("BMI160 I2C connection [FAIL].\n");
    }
}</pre>
<h1>Create the main firmware and test</h1>
<p>Finally I test the firmware by running an infinite loop that prints out acceleration data.</p>
<pre class="lang:c decode:true">void motionTask(void *arg)
{
    (void)arg;
    I2C_1_Start();
    sensorsDeviceInit();
    struct bmi160_sensor_data acc;

    while(1)
    {
        
        bmi160_get_sensor_data(BMI160_ACCEL_ONLY, &amp;acc, NULL, &amp;bmi160Dev);      
        printf("x=%4d y=%4d z=%4d\r\n",acc.x,acc.y,acc.z,);       
        vTaskDelay(200);
    }
}
</pre>
<p>Now you should have this:</p>
<p><a href="https://iotexpert.com/?attachment_id=4964" rel="attachment wp-att-4964"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.47.49-PM.png" alt="" width="660" height="420" class="alignnone wp-image-4964 size-full" srcset="https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.47.49-PM.png 660w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.47.49-PM-600x382.png 600w, https://iotexpert.com/wp-content/uploads/2018/02/Screen-Shot-2018-02-03-at-2.47.49-PM-300x191.png 300w" sizes="(max-width: 660px) 100vw, 660px" /></a></p>
<p>And finally the whole program in one shot</p>
<pre class="lang:c decode:true ">#include "project.h"
#include "FreeRTOS.h"
#include "task.h"
#include &lt;stdio.h&gt;
#include "bmi160.h"

static struct bmi160_dev bmi160Dev;

static int8_t BMI160BurstWrite(uint8_t dev_addr, uint8_t reg_addr,uint8_t *data, uint16_t len)
{
    
    Cy_SCB_I2C_MasterSendStart(I2C_1_HW,dev_addr,CY_SCB_I2C_WRITE_XFER,0,&amp;I2C_1_context);
    Cy_SCB_I2C_MasterWriteByte(I2C_1_HW,reg_addr,0,&amp;I2C_1_context);
    for(int i = 0;i&lt;len; i++)
    { 
        Cy_SCB_I2C_MasterWriteByte(I2C_1_HW,data[i],0,&amp;I2C_1_context);
    }
    
    Cy_SCB_I2C_MasterSendStop(I2C_1_HW,0,&amp;I2C_1_context);
    
    return 0;
}

// This function supports the BMP180 library and read I2C Registers
static int8_t BMI160BurstRead(uint8_t dev_addr, uint8_t reg_addr,uint8_t *data, uint16_t len)
{
    
    Cy_SCB_I2C_MasterSendStart(I2C_1_HW,dev_addr,CY_SCB_I2C_WRITE_XFER,0,&amp;I2C_1_context);
    Cy_SCB_I2C_MasterWriteByte(I2C_1_HW,reg_addr,0,&amp;I2C_1_context);
    Cy_SCB_I2C_MasterSendReStart(I2C_1_HW,dev_addr,CY_SCB_I2C_READ_XFER,0,&amp;I2C_1_context);
    for(int i = 0;i&lt;len-1; i++)
    {
        Cy_SCB_I2C_MasterReadByte(I2C_1_HW,CY_SCB_I2C_ACK,&amp;data[i],0,&amp;I2C_1_context);
    }
    Cy_SCB_I2C_MasterReadByte(I2C_1_HW,CY_SCB_I2C_NAK,&amp;data[len-1],0,&amp;I2C_1_context);
    
    Cy_SCB_I2C_MasterSendStop(I2C_1_HW,0,&amp;I2C_1_context);
    
    
    return 0;
}


static void sensorsDeviceInit(void)
{

  int8_t rslt;
  vTaskDelay(500); // guess

  /* BMI160 */
  bmi160Dev.read = (bmi160_com_fptr_t)BMI160BurstRead;
  bmi160Dev.write = (bmi160_com_fptr_t)BMI160BurstWrite;
  bmi160Dev.delay_ms = (bmi160_delay_fptr_t)vTaskDelay;
  
  bmi160Dev.id = BMI160_I2C_ADDR;  // I2C device address

  rslt = bmi160_init(&amp;bmi160Dev); // initialize the device
  if (rslt == 0)
    {
      printf("BMI160 I2C connection [OK].\n");
      bmi160Dev.gyro_cfg.odr = BMI160_GYRO_ODR_800HZ;
      bmi160Dev.gyro_cfg.range = BMI160_GYRO_RANGE_125_DPS;
      bmi160Dev.gyro_cfg.bw = BMI160_GYRO_BW_OSR4_MODE;

      /* Select the power mode of Gyroscope sensor */
      bmi160Dev.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE;

      bmi160Dev.accel_cfg.odr = BMI160_ACCEL_ODR_1600HZ;
      bmi160Dev.accel_cfg.range = BMI160_ACCEL_RANGE_4G;
      bmi160Dev.accel_cfg.bw = BMI160_ACCEL_BW_OSR4_AVG1;
      bmi160Dev.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;

      /* Set the sensor configuration */
      bmi160_set_sens_conf(&amp;bmi160Dev);
      bmi160Dev.delay_ms(50);
    }
  else
    {
      printf("BMI160 I2C connection [FAIL].\n");
    }
}
#define MAXACCEL 8000
void motionTask(void *arg)
{
    (void)arg;
    I2C_1_Start();
    sensorsDeviceInit();
    struct bmi160_sensor_data acc;

    while(1)
    {
        bmi160_get_sensor_data(BMI160_ACCEL_ONLY, &amp;acc, NULL, &amp;bmi160Dev);
        printf("x=%4d y=%4d z=%4d\r\n",acc.x,acc.y,acc.z);
        
        vTaskDelay(200);
    }
}



int main(void)
{
    __enable_irq(); /* Enable global interrupts. */

    UART_1_Start();

    xTaskCreate( motionTask, "Motion Task",400,0,1,0);
    vTaskStartScheduler();

    while(1);
}

/* [] END OF FILE */
</pre>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/bosch-bmi160-psoc-6-cy8ckit-028-epd/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>FreeRTOS FAT SL FileSystem &#8211; Using the FM24V10 FRAM</title>
		<link>https://iotexpert.com/freertos-fat-sl-filesystem-part-1/</link>
					<comments>https://iotexpert.com/freertos-fat-sl-filesystem-part-1/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Wed, 11 Oct 2017 13:41:41 +0000</pubDate>
				<category><![CDATA[CY8CKIT-044]]></category>
		<category><![CDATA[FreeRTOS]]></category>
		<category><![CDATA[FreeRTOS FAT SL]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=4110</guid>

					<description><![CDATA[Summary Last week while working on a PSoC FreeRTOS Project, I looked at the CY8CKIT-044 Development kit that I was using and remembered that right under the Ambient Light Sensor there is a Cypress FM24V10 FRAM.  Way back, I started pushing our Development Kit team to put other Cypress parts onto the dev kits&#8230;. and [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>Last week while working on a PSoC FreeRTOS Project, I looked at the CY8CKIT-044 Development kit that I was using and remembered that right under the Ambient Light Sensor there is a <a href="http://www.cypress.com/file/41666/download" target="_blank" rel="noopener">Cypress FM24V10</a> FRAM.  Way back, I started pushing our Development Kit team to put other Cypress parts onto the dev kits&#8230;. and because they are awesome, they aggressively started doing that.  One of those chips is the FM24V10 FRAM.  As I looked at the chip, I realized again that I had never really written anything into the FM24V10 FRAM on any of our dev kits, which seems silly after I pushed the dev kit team for them.  I realized that the reason I had never used the FM24V10 FRAM was I didn&#8217;t have a nifty way to write files.  But, while working on the other FreeRTOS projects, I noticed the <a href="http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT_SL/FreeRTOS_Plus_FAT_SL.shtml" target="_blank" rel="noopener">FreeRTOS FAT SL</a> Filesystem is built into FreeRTOS.  The next couple (3?) articles I will talk about making the FreeRTOS FAT SL Filesystem work on a PSoC4200M with a FM24V10 I2C FRAM.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/07/IMG_4575.jpg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/07/IMG_4575-1024x768.jpg" alt="CY8CKIT-044 with FM24V10 FRAM" width="1024" height="768" class="alignnone wp-image-3789 size-large" srcset="https://iotexpert.com/wp-content/uploads/2017/07/IMG_4575-1024x768.jpg 1024w, https://iotexpert.com/wp-content/uploads/2017/07/IMG_4575-600x450.jpg 600w, https://iotexpert.com/wp-content/uploads/2017/07/IMG_4575-300x225.jpg 300w, https://iotexpert.com/wp-content/uploads/2017/07/IMG_4575-768x576.jpg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>The Cypress FM24V10 FRAM</h1>
<p>The &#8220;F&#8221; in FRAM stands for ferroelectric.  What that means is each of the memory cells is a little magnet.  So what you say?  Well the &#8220;what&#8221; is that FRAMs don&#8217;t wear out (unlike Flash), you can write individual cells (unlike Flash), and it is super low power, it is plenty fast (I2C = 3.4MBS), and it retains data for a long long time (151 years).</p>
<p>That list sounds great.  Actually really great.  But, what is the but?  There are two answers to that question.  The first answer is there is a density penalty, the biggest I2C FRAM is 1Mb where you can buy a 1Gb NOR Flash or even bigger NAND Flash.  The next issue is price.  The digikey pricing for a 128Kb FRAM is $12.76 or 9.9c/kb and a 1GB NOR Flash is $14.97 or <span>0.0014c/kb.  That means an FRAM is 6724 x as expensive per bit.</span></p>
<p>How do I use it?  The FRAM is attached to the I2C pins on the CY8CKIT-044.  That means that I can talk to it with either the <a href="https://iotexpert.com/?s=bridge+control+panel" target="_blank" rel="noopener">Bridge Control Panel</a>, or with the PSoC.  To start with I will show you the Bridge Control Panel.  First, I probe the I2C bus, and I see that there are three I2C devices.</p>
<ul>
<li>0x0F = The I2C Accelerometer (which I wrote about <a href="https://iotexpert.com/2017/06/29/psoc-freertos-kionix-kxtj2-accelerometer/" target="_blank" rel="noopener">here</a>)</li>
<li>0x50= The first 64K of FRAM</li>
<li>0x51 = The second 64K of FRAM</li>
</ul>
<p>The 128K FRAM is divided into two banks which are accessed on separate I2C addresses.  By splitting 128K into two blocks of 64K the chip designers optimized the addressing of the memory.  In order to access 64K you need 16-bits, which means to access 128K you need 17-bits.  This would have required sending a whole extra byte of address when you really only needed 1 of those 8 bits.  They avoid this problem by having two addresses.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-03-at-8.24.44-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-03-at-8.24.44-AM-1024x797.png" alt="" width="1024" height="797" class="alignnone size-large wp-image-4198" srcset="https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-03-at-8.24.44-AM-1024x797.png 1024w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-03-at-8.24.44-AM-600x467.png 600w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-03-at-8.24.44-AM-300x234.png 300w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-03-at-8.24.44-AM-768x598.png 768w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-03-at-8.24.44-AM.png 1736w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The FM24V10 FRAM is easy to use as it implements an EzI2C (like) protocol.  EZI2C keeps an internal address pointer.  The pointer is automatically incremented each time you do an I2C transaction.  When you do a write transaction, the first two bytes you write are placed into the address pointer.  I say &#8220;EZI2C like&#8221; because the pointer is not retained between transactions.  Some examples:</p>
<p>If I want to write 0x56 into location 0x0123 I would issue</p>
<ul>
<li>I2C Start</li>
<li>I2C Write to I2C address 0x50</li>
<li>Send 0x01, 0x02 (which write the address pointer)</li>
<li>Send 0x56</li>
<li>I2C Stop</li>
</ul>
<p>I can do that sequence with the Bridge Control Panel command &#8220;W 50 01 23 56 P;&#8221;  The &#8220;W&#8221; stands for &#8220;send a start and send the 7-bit address 0x50 (left shifted 1) and send a &#8216;0&#8217; for write&#8221;.  For some reason the engineers at Philips decided that the I2C protocol would have 7-bit addressing and then 1 bit to represent write or read.  When you talk about I2C there is always confusion about &#8220;8-bit address&#8221; versus &#8220;7-bit address&#8221;.  When they talk about 8-bit address they are talking about the 7-bit address shifted left 1 bit and then or-ed with the read or write bit.  Here is a picture from the bridge control panel:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.32.38-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.32.38-AM.png" alt="" width="839" height="680" class="alignnone size-full wp-image-4204" srcset="https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.32.38-AM.png 839w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.32.38-AM-600x486.png 600w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.32.38-AM-300x243.png 300w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.32.38-AM-768x622.png 768w" sizes="(max-width: 839px) 100vw, 839px" /></a></p>
<p>And the same thing from the logic analyzer.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.33.49-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.33.49-AM-1024x372.png" alt="" width="1024" height="372" class="alignnone size-large wp-image-4205" srcset="https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.33.49-AM-1024x372.png 1024w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.33.49-AM-600x218.png 600w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.33.49-AM-300x109.png 300w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.33.49-AM-768x279.png 768w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.33.49-AM.png 1108w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Once I have written 0x56 into address 0x0123, I can read it back by a &#8220;w 50 01 23 r 50 x p;&#8221; which sends:</p>
<ul>
<li>I2C Start</li>
<li>I2C Write to I2C address 0x50</li>
<li>Send 0x01, 0x02 (which write the address pointer)</li>
<li>I2C Restart</li>
<li>Sends 0x50 (shifted left) or-ed with &#8220;read&#8221;</li>
<li>Reads the byte</li>
<li>I2C Stop</li>
</ul>
<p>In the transaction output window below, you can see that the &#8220;x&#8221; is replaced with &#8220;56&#8221; meaning that it read the previously written value back.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.39.40-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.39.40-AM.png" alt="" width="836" height="672" class="alignnone size-full wp-image-4206" srcset="https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.39.40-AM.png 836w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.39.40-AM-600x482.png 600w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.39.40-AM-300x241.png 300w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.39.40-AM-768x617.png 768w" sizes="(max-width: 836px) 100vw, 836px" /></a></p>
<p>The only other interesting thing about the protocol is that once you have sent and address, you can keep reading, or writing without sending the address again.  For instance to write 01, 02, 03, 04 to address 23, 23,25 and 26 you can send &#8220;W 50 00 23 01 02 03 04 p&#8221;, then you can read it back with &#8220;W 50 00 23 r 50 x x x x p;&#8221;</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.43.24-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.43.24-AM.png" alt="" width="838" height="674" class="alignnone size-full wp-image-4207" srcset="https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.43.24-AM.png 838w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.43.24-AM-600x483.png 600w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.43.24-AM-300x241.png 300w, https://iotexpert.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-11-at-8.43.24-AM-768x618.png 768w" sizes="(max-width: 838px) 100vw, 838px" /></a></p>
<p>In the next Article I will start the process of using the Free RTOS File System to write and read from the I2C FRAM.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/freertos-fat-sl-filesystem-part-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>CY3280 MBR3 &#038; WICED CYW943907</title>
		<link>https://iotexpert.com/cy3280-mbr3-wiced-cyw943907/</link>
					<comments>https://iotexpert.com/cy3280-mbr3-wiced-cyw943907/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Thu, 14 Sep 2017 11:14:55 +0000</pubDate>
				<category><![CDATA[CY943907]]></category>
		<category><![CDATA[PSoC Creator]]></category>
		<category><![CDATA[WICED]]></category>
		<category><![CDATA[WIFI]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=4134</guid>

					<description><![CDATA[Summary In the last Article I talked about the GE Megahackathon.  One of the groups at the event got interested in using a CY3280 MBR3 to send signals via a WICED CYW943907 to the Particle IO server which was connected to a Particle Photon.  I helped them with the implementation and thought that it would [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>In the last Article I talked about the <a href="https://iotexpert.com/2017/09/11/cypress-development-kits-ge-mega-hackthon/" target="_blank" rel="noopener">GE Megahackathon</a>.  One of the groups at the event got interested in using a CY3280 MBR3 to send signals via a WICED CYW943907 to the Particle IO server which was connected to a <a href="https://iotexpert.com/category/devkits/particle-photon/" target="_blank" rel="noopener">Particle Photon</a>.  I helped them with the implementation and thought that it would be useful to show here.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/09/IMG_4892.jpg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/09/IMG_4892-e1505331571825-768x1024.jpg" alt="CYW3280 &amp; WICED CYW943907" width="768" height="1024" class="alignnone wp-image-4139 size-large" srcset="https://iotexpert.com/wp-content/uploads/2017/09/IMG_4892-e1505331571825-768x1024.jpg 768w, https://iotexpert.com/wp-content/uploads/2017/09/IMG_4892-e1505331571825-600x800.jpg 600w, https://iotexpert.com/wp-content/uploads/2017/09/IMG_4892-e1505331571825-225x300.jpg 225w, https://iotexpert.com/wp-content/uploads/2017/09/IMG_4892-e1505331571825-scaled.jpg 1920w" sizes="(max-width: 768px) 100vw, 768px" /></a></p>
<h1>Cypress CY3280 MBR3</h1>
<p>The CY3280 MBR development kit is a CapSense demonstration kit that shows the Mechanical Button Replacement 3 chip.  It features 4 CapSense buttons with LEDs, a proximity sensor, and a buzzer.  It is connected to another MCU via the Arduino pins. of the WICED CYW943907.  The device sits on the I2C bus and acts as an I2C Slave.  You configure it using EZ Click.</p>
<p>When you run EZ Click you can setup the configure the internal registers of the MBR3 to make the board act like a bunch of different things.  In this case I turned on</p>
<ul>
<li>The MBR buttons 1-4 (you can see them in the picture above)</li>
<li>The Flanking Sensor rejection which makes it so that you can only press one button at a time.</li>
<li>All of the automatic tuning features.</li>
</ul>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-2.16.41-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-2.16.41-PM.png" alt="EZ-Click CY3280" width="904" height="771" class="alignnone wp-image-4137 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-2.16.41-PM.png 904w, https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-2.16.41-PM-600x512.png 600w, https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-2.16.41-PM-300x256.png 300w, https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-2.16.41-PM-768x655.png 768w" sizes="(max-width: 904px) 100vw, 904px" /></a></p>
<p>Once the main CapSense is configured, I moved to the other part of the configuration where I setup</p>
<ul>
<li>The 4 LEDs to toggle and be full brightness when on</li>
<li>The buzzer to buzz for 100ms at 4kHz when something happens</li>
<li>The host interrupt pin as CS15/SH/HI.  This made the Arduino pin D2 be an interrupt when something happened so that WICED would poll the MBR3</li>
</ul>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-2.16.55-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-2.16.55-PM.png" alt="EZ-Click CY3280" width="905" height="768" class="alignnone wp-image-4136 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-2.16.55-PM.png 905w, https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-2.16.55-PM-600x509.png 600w, https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-2.16.55-PM-300x255.png 300w, https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-2.16.55-PM-768x652.png 768w" sizes="(max-width: 905px) 100vw, 905px" /></a></p>
<p>Once these settings were all done, I downloaded the firmware configuration via the KitProg USB connector.  Then I tested it using the <a href="https://iotexpert.com/?s=bridge+control+panel" target="_blank" rel="noopener">bridge control panel</a> which I have shown you a bunch of different times in the past.  The MBR3 acts as an I2C slave.  To find out what the state of the buttons are you need to read register 0xAA.  The only little trick is that the chip goes to sleep to save power.  In order to wake it up you need to send an I2C transaction, which ends up getting NAK&#8217;d.  But the next transaction you send will be ACKd.  In the screenshot below you can see that I tried two of the buttons (0x08 and 0x20)</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-4.06.59-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-4.06.59-PM.png" alt="Bridge Control Panel" width="850" height="672" class="alignnone wp-image-4144 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-4.06.59-PM.png 850w, https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-4.06.59-PM-600x474.png 600w, https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-4.06.59-PM-300x237.png 300w, https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-4.06.59-PM-768x607.png 768w" sizes="(max-width: 850px) 100vw, 850px" /></a></p>
<p>One problem that I had is that the power system of this board is setup to take 5V from the Arduino base board but the WICED development kit gives only 3.3v.  Here is a picture of the power system from the MBR3 schematic.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-3.36.57-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-3.36.57-PM-1024x522.png" alt="CY3280 Power Supply" width="1024" height="522" class="alignnone wp-image-4141 size-large" srcset="https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-3.36.57-PM-1024x522.png 1024w, https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-3.36.57-PM-600x306.png 600w, https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-3.36.57-PM-300x153.png 300w, https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-3.36.57-PM-768x391.png 768w, https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-3.36.57-PM.png 1125w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The MBR3 can run on 3.3Vs.  In fact it can run all the way down to 1.7v and up to 5.5v, but for some reason (which I can&#8217;t remember) we made the board only work with 5.0v.  To fix this problem I removed J12 and then wired a wire from the 3.3V Arduino pin.  The wire is soldered onto the 3.3v pin, but has a female connector on the other side so that it can be plugged into J12.  Here is a picture:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/09/IMG_4890.jpg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/09/IMG_4890-e1505327051755-1024x768.jpg" alt="CY3280" width="1024" height="768" class="alignnone wp-image-4138 size-large" srcset="https://iotexpert.com/wp-content/uploads/2017/09/IMG_4890-e1505327051755-1024x768.jpg 1024w, https://iotexpert.com/wp-content/uploads/2017/09/IMG_4890-e1505327051755-600x450.jpg 600w, https://iotexpert.com/wp-content/uploads/2017/09/IMG_4890-e1505327051755-300x225.jpg 300w, https://iotexpert.com/wp-content/uploads/2017/09/IMG_4890-e1505327051755-768x576.jpg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The last thing that I needed to do was move the jumpers to position &#8220;A&#8221; which made the host interrupt pin be connected to D2, and move the I2C jumpers so that the MBR3 was connected to the Arduino instead of the P5LP kitprog.  You can see that in the J3_scl and J3_sda in the picture above.</p>
<h1>WICED CYW943907</h1>
<p>The <a href="http://www.cypress.com/documentation/development-kitsboards/cyw943907aeval1f-evaluation-kit" target="_blank" rel="noopener">CYW934907AEVAL1F</a> is an development kit for the Cypress 43907 MCU+WiFi module.  The WICED CYW943907 board can do dual band (2.4 and 5Ghz), 802.11 a/b/g/n,  Ethernet and a whole bunch of other stuff.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/09/IMG_4893.jpg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/09/IMG_4893-e1505333784420-1024x768.jpg" alt="WICED CYW943907" width="1024" height="768" class="alignnone wp-image-4145 size-large" srcset="https://iotexpert.com/wp-content/uploads/2017/09/IMG_4893-e1505333784420-1024x768.jpg 1024w, https://iotexpert.com/wp-content/uploads/2017/09/IMG_4893-e1505333784420-600x450.jpg 600w, https://iotexpert.com/wp-content/uploads/2017/09/IMG_4893-e1505333784420-300x225.jpg 300w, https://iotexpert.com/wp-content/uploads/2017/09/IMG_4893-e1505333784420-768x576.jpg 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The first firmware that I wrote in WICED Studio:</p>
<ul>
<li>Sets up an ISR to unlock a semaphore when the interrupt occurs</li>
<li>Initialized WICED_GPIO_9 to be an input and connected to an ISR &#8230; this is also known as Arduino D2</li>
<li>Setup the I2C Master Hardware in the 43907</li>
<li>Wait for a semaphore (from the ISR)</li>
<li>Read the I2C register 0xAA from the MBR</li>
</ul>
<p>The only trick in the firmware is that I read the I2C with a &#8220;do&#8221; loop until I get a valid result, meaning that the MBR3 has woken up.</p>
<pre class="lang:c decode:true">#include "wiced.h"

#define I2C_ADDRESS (0x37)
#define BUTTON_REG (0xAA)

wiced_semaphore_t buttonPress;

/* Interrupt service routine for the button */
void button_isr(void* arg)
{
    wiced_rtos_set_semaphore(&amp;buttonPress);
}

/* Main application */
void application_start( )
{
    wiced_init();	/* Initialize the WICED device */
    WPRINT_APP_INFO(("Started\n"));

    wiced_result_t result;
    wiced_rtos_init_semaphore(&amp;buttonPress);

    // WICED_GPIO_9 is the MBR3 Interrupt Pin
    wiced_gpio_init(WICED_GPIO_9,INPUT_PULL_UP);
    wiced_gpio_input_irq_enable(WICED_GPIO_9, IRQ_TRIGGER_FALLING_EDGE, button_isr, NULL); /* Setup interrupt */

    /* Setup I2C master */
    const wiced_i2c_device_t i2cDevice = {
            .port = WICED_I2C_2,
            .address = I2C_ADDRESS,
            .address_width = I2C_ADDRESS_WIDTH_7BIT,
            .speed_mode = I2C_STANDARD_SPEED_MODE
    };

    wiced_i2c_init(&amp;i2cDevice);

    /* Tx buffer is used to set the offset */
    uint8_t tx_buffer[] = {BUTTON_REG};
    uint8_t buttonStatus;

    while ( 1 )
    {

        wiced_rtos_get_semaphore(&amp;buttonPress,WICED_WAIT_FOREVER);

        // Do this until the MBR3 is alive.  It goes into deep sleep and wakes when you
        // send the first command.
        do {
            result = wiced_i2c_write(&amp;i2cDevice, WICED_I2C_START_FLAG | WICED_I2C_STOP_FLAG, tx_buffer, sizeof(tx_buffer));
        }
        while(result != WICED_SUCCESS);

        result=wiced_i2c_read(&amp;i2cDevice, WICED_I2C_START_FLAG | WICED_I2C_STOP_FLAG, &amp;buttonStatus, sizeof(buttonStatus));
        WPRINT_APP_INFO(("Button State = %X\n", buttonStatus)); /* Print data to terminal */
    }
}
</pre>
<p>Once that is programmed I program and test the firmware.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-1.46.36-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-1.46.36-PM.png" alt="Testing WICED CYW943907" width="877" height="522" class="alignnone wp-image-4135 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-1.46.36-PM.png 877w, https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-1.46.36-PM-600x357.png 600w, https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-1.46.36-PM-300x179.png 300w, https://iotexpert.com/wp-content/uploads/2017/09/Screen-Shot-2017-09-13-at-1.46.36-PM-768x457.png 768w" sizes="(max-width: 877px) 100vw, 877px" /></a></p>
<p>In the next article I will modify all of this firmware and make the WICED CYW943907 send data via HTTP to the Cloud.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/cy3280-mbr3-wiced-cyw943907/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>PSoC FreeRTOS &#8211; Sharing the I2C Bus</title>
		<link>https://iotexpert.com/psoc-freertos-sharing-the-i2c-bus/</link>
					<comments>https://iotexpert.com/psoc-freertos-sharing-the-i2c-bus/#comments</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Thu, 22 Jun 2017 12:55:42 +0000</pubDate>
				<category><![CDATA[CY8CKIT-044]]></category>
		<category><![CDATA[FreeRTOS]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=3713</guid>

					<description><![CDATA[Summary I have gotten quite a few questions about my PSoC FreeRTOS series of Articles.  One question was: &#8220;I have a bunch of different I2C sensors, what is a good PSoC FreeRTOS scheme to share the I2C bus?&#8221;  When I thought about this question there were a number of possible firmware architectures that could be [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>I have gotten quite a few questions about my PSoC FreeRTOS series of Articles.  One question was: &#8220;I have a bunch of different I2C sensors, what is a good PSoC FreeRTOS scheme to share the I2C bus?&#8221;  When I thought about this question there were a number of possible firmware architectures that could be used:</p>
<ol>
<li>Each sensor has a thread, and there is a global Mutex to lock/unlock the I2C bus</li>
<li>There is single thread that reads and writes to all of the sensors (oh&#8230;wait&#8230; that looks like the old bare metal while(1); )</li>
<li>There is a single I2C thread that can take requests execute them, and then feed data back to the calling thread</li>
</ol>
<p>After thinking about it a bit, I decided to use the 3rd scheme as it allows me to</p>
<ul>
<li>Reuse the I2C interface code (all the sensors have a register map that you read/write)</li>
<li>Handle all of the timing issues in one place (instead of duplicated)</li>
<li>Isolate the I2C interface from all of the threads (could be replaced with SPI or something else later)</li>
</ul>
<p>In this article I will show you:</p>
<ul>
<li>The register based I2C interface that is in common use with sensors</li>
<li>The design of the PSoC FreeRTOS firmware with a single I2C interface thread</li>
<li>The PSoC FreeRTOS firmware implementation</li>
<li>A test case using the CY8CKIT-044</li>
</ul>
<h1>Interfacing with I2C Sensor Registers using PSoC FreeRTOS</h1>
<p>The CY8CKIT-044 (on of my favorite Cypress kits) has two devices attached to the I2C bus, so it made a perfect test platform.  On the front there is a Cypress <a href="http://www.cypress.com/file/41666/download" target="_blank" rel="noopener">FM24V10</a> FRAM and a <a href="http://kionixfs.kionix.com/en/datasheet/KXTJ2-1009%20Specifications%20Rev%209.pdf" target="_blank" rel="noopener">Kionix KXTJ2-1009</a> I2C Accelerometer.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/06/IMG_4515.jpg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/06/IMG_4515-e1499117018159.jpg" alt="CY8CKIT-044 Development Kit Front" width="4032" height="3024" class="alignnone wp-image-3716 size-full" /></a></p>
<p>And on the back there is a nice little picture on the silkscreen that gives the FRAM I2C Address as 0x50, the I2C Address of the Accelerometer as 0X0F and the I2C pins as P4.0/P4.1 <a href="https://iotexpert.com/wp-content/uploads/2017/06/IMG_4514.jpg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/06/IMG_4514.jpg" alt="CY8CKIT-044 Development Kit Back" width="4032" height="3024" class="alignnone wp-image-3717 size-full" /></a></p>
<p>When I probe the I2C Bus using the bridge control panel I see that three I2C devices respond, 0x0F (the <a href="http://kionixfs.kionix.com/en/datasheet/KXTJ2-1009%20Specifications%20Rev%209.pdf" target="_blank" rel="noopener">KXTJ2-1009</a>), 0x50/0x51 (the FRAM.)</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.31.07-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.31.07-AM.png" alt="Bridge control panel probing I2C bus on CY8CKIT-044" width="930" height="680" class="alignnone wp-image-3719 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.31.07-AM.png 930w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.31.07-AM-600x439.png 600w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.31.07-AM-300x219.png 300w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.31.07-AM-768x562.png 768w" sizes="(max-width: 930px) 100vw, 930px" /></a></p>
<p>So, how do you talk to the devices?  It turns out that both of these devices respond to the very common I2C device scheme which is called &#8220;EZI2C&#8221; inside of Cypress.  The scheme goes like this:</p>
<ul>
<li>The chip is organized into registers</li>
<li>Each register has an address</li>
<li>Addresses are either 8-bits or 16-bits</li>
<li>To write an address you can send a string of bytes like:  I2C Start, I2C Address + W, Register Address,  Value to write, Stop</li>
<li>To read an address you can send a string of bytes like:  I2C Start, I2C Address + W, Register Address, Restart, Read, Stop</li>
</ul>
<p>A simplification is that you can keep writing (or reading) and it will automatically goes to the next address without you having to send the next address. The easiest thing to do is show an example with the FRAM.</p>
<p>The FRAM has 128K addresses so it uses 16-bit addresses.  For example to save the values 5,6,7,8 into the register 0x0123 you would send:</p>
<ul>
<li>0x50, W, 0x01, 0x02, 0x05, 0x06, 0x07, 0x08, Stop  (in the bridge control panel the command is W 50 1 2 5 6 7 8 p)</li>
</ul>
<p>To read back those addresses you would send</p>
<ul>
<li>0x50, W, 0x01, 0x02, restart, read read read read Stop  (in the bridge control panel the command is W 50 1 2 R 50 x x x x p)</li>
</ul>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.49.40-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.49.40-AM.png" alt="Writing to Cypress FRAM using Bridge Control Panel" width="935" height="677" class="alignnone wp-image-3720 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.49.40-AM.png 935w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.49.40-AM-600x434.png 600w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.49.40-AM-300x217.png 300w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.49.40-AM-768x556.png 768w" sizes="(max-width: 935px) 100vw, 935px" /></a></p>
<p>The interface is similar for the <a href="http://kionixfs.kionix.com/en/datasheet/KXTJ2-1009%20Specifications%20Rev%209.pdf" target="_blank" rel="noopener">Kionix KXTJ2-1009</a>.  When you look at the datasheet you will see on page 17 their description of the EZI2C protocol:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.52.21-AM.png"></a><a href="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.52.21-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.52.21-AM.png" alt="Kionix KXTJ2-1009 Datasheet" width="1118" height="921" class="alignnone wp-image-3721 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.52.21-AM.png 1118w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.52.21-AM-600x494.png 600w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.52.21-AM-300x247.png 300w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.52.21-AM-768x633.png 768w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.52.21-AM-1024x844.png 1024w" sizes="(max-width: 1118px) 100vw, 1118px" /></a></p>
<p>Then on page 20 they start describing the registers, and on page 21 they describe two registers (called DCST_RESP and WHO_AM_I) that will always respond with known values.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.54.07-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.54.07-AM.png" alt="Kionix KXTJ2-1009 Datasheet" width="1106" height="568" class="alignnone wp-image-3722 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.54.07-AM.png 1106w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.54.07-AM-600x308.png 600w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.54.07-AM-300x154.png 300w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.54.07-AM-768x394.png 768w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.54.07-AM-1024x526.png 1024w" sizes="(max-width: 1106px) 100vw, 1106px" /></a></p>
<p>To verify the operation I send read commands using the Bridge Control panel to those registers, which respond with 55 and 9 just like the datasheet says that they should.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.58.08-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.58.08-AM.png" alt="Reading from Kionix KXTJ2-1009 Using Bridge Control Panel" width="933" height="679" class="alignnone wp-image-3723 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.58.08-AM.png 933w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.58.08-AM-600x437.png 600w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.58.08-AM-300x218.png 300w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-5.58.08-AM-768x559.png 768w" sizes="(max-width: 933px) 100vw, 933px" /></a></p>
<h1>Designing PSoC FreeRTOS FW for I2C Register Based Sensors</h1>
<p>From the previous section(s) we know that</p>
<ol>
<li>Two totally different devices, a memory and an accelerometer, can be accessed using exactly the same protocol</li>
<li>It may take a while to complete I2C transactions (4 bytes @ 400kb/s = 87.5uS).</li>
<li>The I2C master is a &#8220;shared&#8221; interface on the board, but multiple threads may want to perform transactions</li>
</ol>
<p>These facts lead up to the conclusion that it would be nice to:</p>
<ul>
<li>Have a standard software interface to I2C devices that use the EZI2C protocol</li>
<li>Have a non-blocking thread to run the interface</li>
<li>Share the I2C</li>
<li>Use PSoC FreeRTOS (the whole point)</li>
</ul>
<p>With all of that in mind I created &#8220;i2cmaster.h&#8221;, the public interface to a PSoC FreeRTOS thread that will run the EZI2C protocol.  It defines two public functions</p>
<ul>
<li>i2cm_Task &#8211; The thread that will need to be started to run all of the transactions</li>
<li>i2cm_runTransaction &#8211; The thread safe public interface which will send the transaction to the i2cm_Task</li>
</ul>
<p>To run a transaction you need to have a transaction.  I defined a new type called &#8220;i2cm_transaction&#8221;.  This type is a structure that contains all of the information that is required to perform a transaction.  The input is split into three sections:</p>
<ul>
<li>The I2C Address, the Register Address (and type 8-bit or 16-bit), and if the transaction is a Read or a Write</li>
<li>The number of bytes you want to read/write and a pointer to the data</li>
<li>The number of bytes that were processed (an output of the task)&#8230; plus an optional semaphore that will be given if you want a blocking transaction</li>
</ul>
<pre class="lang:c decode:true">#include &lt;project.h&gt;
#include "FreeRTOS.h"
#include "semphr.h"

#ifndef I2C_MASTER_H
#define I2C_MASTER_H

    
typedef enum i2cm_transactionMethod {
    I2CM_READ,
    I2CM_WRITE
} i2cm_transactionMethod_t;

typedef enum i2cm_registerAddresType {
    I2CM_BIT8,
    I2CM_BIT16
 
} i2cm_registerAddressType_t;


typedef struct i2cm_transaction {
    i2cm_transactionMethod_t i2cm_method;        // I2CM_READ or I2CM_WRITE
    uint8_t i2cm_address;                        // The I2C Address of the slave
    i2cm_registerAddressType_t i2cm_regType;     // I2CM_8BIT or I2CM_16BIT
    uint16_t i2cm_register;                      // The register in the slave
    
    uint8_t *i2cm_bytes;                         // A pointer to the data to be written (or a place to save the data)
    int i2cm_byteNum;                            // How many bytes are in the request

    int *i2cm_bytesProcessed;                    // A return value with the number of bytes written 
    SemaphoreHandle_t i2cm_doneSemaphore;        // If you want a semaphore flaging that the transaction is done
 
} i2cm_transaction_t;

void i2m_Task(void *arg);                  // The main thread function... you should start it in the RTOS

void i2cm_runTransaction(i2cm_transaction_t *i2cm_Transaction); // The public interface

#endif</pre>
<p>With the public interface setup you will be able to run code that does exactly the same thing as you did in the bridge control panel.  For instance you can query the accelerometer &#8220;WHO_AM_I&#8221; register:</p>
<pre class="start-line:232 lang:c decode:true ">                    mytransaction.i2cm_method = I2CM_READ;
                    mytransaction.i2cm_address = 0x0F;            // Acelleromter I2C Address
                    mytransaction.i2cm_regType = I2CM_BIT8;       // 8-bit addressing
                    mytransaction.i2cm_register = 0x0F;           // WHO_AM_I Register
               
                    mytransaction.i2cm_byteNum = 1;               // One byte
                    mytransaction.i2cm_bytes = data;
               
                    mytransaction.i2cm_bytesProcessed = &amp;byteCount;
                    mytransaction.i2cm_doneSemaphore = mySemaphore;
                    i2cm_runTransaction(&amp;mytransaction);
                    
                    sprintf(buff,"Bytes=%d WHO_AM_I=0x%02X\n",byteCount,data[0]);
                    UART_UartPutString(buff);          
</pre>
<p>Which will yield exactly the same result as the bridge control panel did:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-7.03.19-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-7.03.19-AM.png" alt="PSoC FreeRTOS: I2C Thread output from Kionix KXTJ2-1009" width="660" height="414" class="alignnone wp-image-3726 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-7.03.19-AM.png 660w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-7.03.19-AM-600x376.png 600w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-7.03.19-AM-300x188.png 300w" sizes="(max-width: 660px) 100vw, 660px" /></a></p>
<h1>Implementing a PSoC FreeRTOS I2C Master Library</h1>
<p>From the previous section we know the public interface.  But how does it work?  When the PSoC FreeRTOS i2cm_Task starts it:</p>
<ul>
<li>Starts up the hardware I2C block</li>
<li>It makes a queue.  The queue will hold transactions which are waiting to be processed.  This is how multiple processes will put requested transactions into the queue, and the I2C master will deal with them one at a time in the order they were placed in the queue.</li>
<li>It starts up the infinite loop and waits for a transaction to be placed in the queue.</li>
</ul>
<pre class="start-line:42 lang:c decode:true">void i2cm_Task(void *arg)
{
    
    // The argument is the size of the queue
    uint32_t queueSize = (uint32_t)arg; // cast the arg
    
    I2C_Start(); // turn on the I2C Master
     
    i2cm_transaction_t i2cm_transaction; // A scratch transaction
    i2cm_transactionQueue = xQueueCreate(queueSize, sizeof(i2cm_transaction_t));
    
    uint32_t rval; // all of the I2C functions return a uint32_t
    
    while(1)
    {
        int i;
 
        // Wait until something gets put in the queue
        if(xQueueReceive(i2cm_transactionQueue,&amp;i2cm_transaction,portMAX_DELAY) == pdTRUE)</pre>
<p>The public interface to the whole system is i2cm_runTransaction.  It takes the transaction structure and pushes it onto the queue for the main thread to process.  If the user has asked to wait for completion then it also holds until the semaphore is given by the main loop.</p>
<pre class="start-line:123 lang:c decode:true">// the i2cm_runTransaction function is the public interace to the system
// This function is thread safe (it can be called from any thread)
// It will queue up an I2C tranaction and then wait (if there is a semaphore handle)
void i2cm_runTransaction(i2cm_transaction_t *i2cm_transaction)
{
    if(xQueueSend(i2cm_transactionQueue,i2cm_transaction,portMAX_DELAY) != pdTRUE)
    {
        // Highly bad
        CYASSERT(0); // 
    }
    if(i2cm_transaction-&gt;i2cm_doneSemaphore)
        xSemaphoreTake(i2cm_transaction-&gt;i2cm_doneSemaphore,portMAX_DELAY);
}</pre>
<p>The last part of the system is the main transaction processing loop which:</p>
<ul>
<li>Waits for a transaction</li>
<li>Sends a start, then write the I2C address and register address (lines 65-75)</li>
<li>If it is a write, then write the bytes (lines 80-85)</li>
<li>If it is a read, then read then read bytes (lines 89-102)</li>
<li>Send a stop (lines 105-106)</li>
<li>If the user asked for a semaphore, give it. (lines 112-113)</li>
</ul>
<pre class="start-line:60 lang:c decode:true">        // Wait until something gets put in the queue
        if(xQueueReceive(i2cm_transactionQueue,&amp;i2cm_transaction,portMAX_DELAY) == pdTRUE)
        {
            // Begining of an I2C transaction
            *i2cm_transaction.i2cm_bytesProcessed = 0;
            // First write the register address
            rval = I2C_I2CMasterSendStart(i2cm_transaction.i2cm_address,I2C_I2C_WRITE_XFER_MODE);
            if(rval != I2C_I2C_MSTR_NO_ERROR) goto cleanup;
            
            if(i2cm_transaction.i2cm_regType == I2CM_BIT16) // if a 16 bit register then send the high
            {
                rval = I2C_I2CMasterWriteByte((i2cm_transaction.i2cm_register &gt;&gt; 8) &amp; 0xFF);
                if(rval != I2C_I2C_MSTR_NO_ERROR) goto cleanup;
            }
            rval = I2C_I2CMasterWriteByte((i2cm_transaction.i2cm_register ) &amp; 0xFF); // send the low byte
            if(rval != I2C_I2C_MSTR_NO_ERROR) goto cleanup;
            
            // if w send ...
            switch(i2cm_transaction.i2cm_method) // Look at the type of transaction they want to do...
            {
                case I2CM_WRITE:  // If it is a write... then just send out the bytes
                for(i=0; i &lt; i2cm_transaction.i2cm_byteNum;i++)
                {
                    rval = I2C_I2CMasterWriteByte(i2cm_transaction.i2cm_bytes[i]);
                    if(rval != I2C_I2C_MSTR_NO_ERROR) goto cleanup;
                    *i2cm_transaction.i2cm_bytesProcessed += 1;
                }
                break;
            
                case I2CM_READ: // If it is a read.. then do a restart with READ... then read n-1 bytes
                rval = I2C_I2CMasterSendRestart(i2cm_transaction.i2cm_address,I2C_I2C_READ_XFER_MODE);
                if(rval != I2C_I2C_MSTR_NO_ERROR) goto cleanup;
                for(i=0; i &lt; i2cm_transaction.i2cm_byteNum-1;i++)
                {
                    i2cm_transaction.i2cm_bytes[i] = I2C_I2CMasterReadByte(I2C_I2C_ACK_DATA);
                    if(i2cm_transaction.i2cm_bytes[i] &amp; 0x10000000) goto cleanup;
                    *i2cm_transaction.i2cm_bytesProcessed += 1;
                }
                // Then read the last byte and NAK (saying you are done)
                i2cm_transaction.i2cm_bytes[i2cm_transaction.i2cm_byteNum-1] = I2C_I2CMasterReadByte(I2C_I2C_NAK_DATA);
                if(i2cm_transaction.i2cm_bytes[i2cm_transaction.i2cm_byteNum-1] &amp; 0x10000000) goto cleanup;
                *i2cm_transaction.i2cm_bytesProcessed += 1;
                break;
            }

            rval = I2C_I2CMasterSendStop();
            if(rval != I2C_I2C_MSTR_NO_ERROR) goto cleanup;

            cleanup:
            CYASSERT(rval == 0); // something really bad happend
          
           // If they ask for a semphore when done... then give it
            if(i2cm_transaction.i2cm_doneSemaphore)
                xSemaphoreGive(i2cm_transaction.i2cm_doneSemaphore);     
        }</pre>
<h1>I2C Sensor Library on the CY8CKIT-044 (FRAM)</h1>
<p>In order to test the FRAM  I define a buffer in the RAM of the PSoC called &#8220;data&#8221;.  Then I setup three commands that can be executed from the UART Thread which will:</p>
<ul>
<li>q &#8211; read 4 bytes from register 0x0102 into the data[] array</li>
<li>w -write 4 bytes from the data[] array into the FRAM register 0x0102</li>
<li>i &#8211; increment the values in the data[] array.</li>
</ul>
<p>The code is simple:</p>
<pre class="start-line:187 lang:c decode:true">           case 'q':
                    mytransaction.i2cm_address = 0x50;
                    mytransaction.i2cm_regType = I2CM_BIT16;
                    mytransaction.i2cm_byteNum = 4;
                    mytransaction.i2cm_register = 0x0102;
                    mytransaction.i2cm_method = I2CM_READ;
                    mytransaction.i2cm_bytesProcessed = &amp;byteCount;
                    mytransaction.i2cm_bytes = data;
                    mytransaction.i2cm_doneSemaphore = mySemaphore;
                    i2cm_runTransaction(&amp;mytransaction);
                    sprintf(buff,"Bytes=%d 0=%d 1=%d 2=%d 3=%d\n",byteCount,data[0],data[1],data[2],data[3]);
                    UART_UartPutString(buff);                  
            break;
            case 'i': // This will increment the values (that you read presumably from the FRAM
                    data[0] += 1;
                    data[1] += 1;
                    data[2] += 1;
                    data[3] += 1;
                    sprintf(buff,"0=%d 1=%d 2=%d 3=%d\n",data[0],data[1],data[2],data[3]);
                    UART_UartPutString(buff);
            break;
           
            case 'w': //This will write 4 values to register 0 in the FRAM
                    mytransaction.i2cm_address = 0x50;
                    mytransaction.i2cm_regType = I2CM_BIT16;
                    mytransaction.i2cm_byteNum = 4;
                    mytransaction.i2cm_register = 0x0102;
                    mytransaction.i2cm_method = I2CM_WRITE;
                    mytransaction.i2cm_bytesProcessed = &amp;byteCount;
                    mytransaction.i2cm_bytes = data;
                    mytransaction.i2cm_doneSemaphore = mySemaphore;
                    i2cm_runTransaction(&amp;mytransaction);
                    sprintf(buff,"Wrote %d bytes\n",byteCount);
                    UART_UartPutString(buff);
            break;</pre>
<p>To test:</p>
<ul>
<li>Press &#8216;q&#8217; to read from the FRAM into data[]</li>
<li>Press &#8216;i&#8217; to increment the values in data[]</li>
<li>Press &#8216;w&#8217; to write the data[] back into the FRAM</li>
<li>Press &#8216;q&#8217; to make sure that the values were written</li>
<li>Use the bridge control panel to read the data to make sure that it is right.</li>
</ul>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.07.25-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.07.25-AM.png" alt="PSoC FreeRTOS: I2C Thread output from Cypress FRAM" width="665" height="417" class="alignnone wp-image-3730 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.07.25-AM.png 665w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.07.25-AM-600x376.png 600w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.07.25-AM-300x188.png 300w" sizes="(max-width: 665px) 100vw, 665px" /></a></p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.08.24-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.08.24-AM.png" alt="Read/Write from Bridge Control Panel to Cypress FRAM" width="932" height="677" class="alignnone wp-image-3729 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.08.24-AM.png 932w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.08.24-AM-600x436.png 600w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.08.24-AM-300x218.png 300w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.08.24-AM-768x558.png 768w" sizes="(max-width: 932px) 100vw, 932px" /></a></p>
<h1>I2C Sensor Library on the CY8CKIT-044 (Accelerometer)</h1>
<p>Finally, to test the Accelerometer I create a PSoC FreeRTOS thread which starts up and turns on the Accelerometer.  To turn on the accelerometer you need to write a 0b1000000 to register 0x1b (called the CTRL_REG_1)</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.20.11-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.20.11-AM.png" alt="" width="1119" height="1032" class="alignnone size-full wp-image-3732" srcset="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.20.11-AM.png 1119w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.20.11-AM-600x553.png 600w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.20.11-AM-300x277.png 300w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.20.11-AM-768x708.png 768w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.20.11-AM-1024x944.png 1024w" sizes="(max-width: 1119px) 100vw, 1119px" /></a></p>
<pre class="start-line:67 lang:c decode:true">// This task manages the accelerometer
// 
void accel_Task(void *arg)
{
    (void)arg;
    SemaphoreHandle_t mySemaphore;
    i2cm_transaction_t mytransaction;
    char buff[128];
    int x,y,z;
    int xs,ys,zs;
    
    int byteCount;
    accel_t myData;
    
    mySemaphore = xSemaphoreCreateBinary();
     
    // True of all read/writes
    mytransaction.i2cm_address = 0x0F;
    mytransaction.i2cm_regType = I2CM_BIT8;
    mytransaction.i2cm_bytesProcessed = &amp;byteCount;
    
    // Initalize the acceleromter
    uint8_t setupData[] = {0b10000000};
    mytransaction.i2cm_method = I2CM_WRITE;
    mytransaction.i2cm_register = 0x1b; // CTRL_REG_1
    mytransaction.i2cm_byteNum = sizeof(setupData);
    mytransaction.i2cm_doneSemaphore = mySemaphore;
    mytransaction.i2cm_bytes = setupData;
    i2cm_runTransaction(&amp;mytransaction);</pre>
<p>Once the accelerometer is turned on, it will update 6 registers called XOUT_L/XOUT_H, YOUT_L/YOUT_Z, XOUT_L/ZOUT_H with the current X,Y and Z acceleration.  The data will be in the form of a 12-bit signed integer, left aligned (in other words the 4 least significant bits will be nothing).  I create a structure that I will use to hold the acceleration data.  Notice that I used &#8220;CY_PACKED&#8221; so that it will be not padded by the compiler.</p>
<pre class="start-line:67 lang:c decode:true ">CY_PACKED typedef struct accel {
    int16_t x;
    int16_t y;
    int16_t z;
} CY_PACKED_ATTR accel_t;
</pre>
<p>Then I set up a read transaction of those registers, which are conveniently all right next to each other so you can read 6 consecutive bytes.</p>
<pre class="start-line:105 lang:c decode:true">   // Setup for repeated reads
    mytransaction.i2cm_method = I2CM_READ;
    mytransaction.i2cm_register = 0x06;
    mytransaction.i2cm_byteNum = sizeof(myData);
    mytransaction.i2cm_doneSemaphore = mySemaphore;
    mytransaction.i2cm_bytes = (uint8_t *)&amp;myData;</pre>
<p>Finally I repeatedly read the registers and print out the results.  The only trick is that I didn&#8217;t enable the floating point output libraries (they are huge), so I manually convert the floats to ints to be printed out.</p>
<pre class="start-line:112 lang:c decode:true">    while(1)  // Run the same transaction over and over
    {
        i2cm_runTransaction(&amp;mytransaction);
        myData.x /= 16;  // The KXTJ2 Datasheet say lower 4 bits are X
        myData.y /= 16;  // The KXTJ2 Datasheet say lower 4 bits are X
        myData.z /= 16;  // The KXTJ2 Datasheet say lower 4 bits are X
        xs = (myData.x &lt; 0? -1:1);  // Find the XSign
        ys = (myData.y &lt; 0? -1:1);  // Find the YSign
        zs = (myData.z &lt; 0? -1:1);  // Find the ZSign
            
        // The 1024 is a hardcode based on the range of the acceleromter
        x = (int)((float)myData.x / 1024.0 * 10.0) * xs; // Turn it into integer G * 10
        y = (int)((float)myData.y / 1024.0 * 10.0) * ys; // Turn it into integer G * 10
        z = (int)((float)myData.z / 1024.0 * 10.0) * zs; // Turn it into integer G * 10
       
        // Format data in x.x  
        sprintf(buff,"x=%s%d.%dg\ty=%s%d.%dg\tz=%s%d.%dg\n",(xs&lt;0?"-":""),x/10,x%10,(ys&lt;0?"-":""),y/10,y%10,(zs&lt;0?"-":""),z/10,z%10);
        UART_UartPutString(buff);
        vTaskDelay(1000); // delay for 1 second
    }</pre>
<p>And here is the screen shot of the output of the PSoC FreeRTOS with the kit sitting on my desk&#8230;. the output is about 1G down (which make sense)</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.28.02-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.28.02-AM.png" alt="PSoC FreeRTOS: Output of Kionix KXTJ2-1009 Accelerometer" width="658" height="412" class="alignnone wp-image-3733 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.28.02-AM.png 658w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.28.02-AM-600x376.png 600w, https://iotexpert.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-22-at-8.28.02-AM-300x188.png 300w" sizes="(max-width: 658px) 100vw, 658px" /></a></p>
<p>As always you can git this PSoC FreeRTOS project at the <a href="https://github.com/iotexpert/PSoC-FreeRTOS-Examples" target="_blank" rel="noopener">IoT Expert GitHub </a>site or git@github.com:iotexpert/PSoC-FreeRTOS-Examples.git</p>
<p><span><p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Topic</th>
<th >Description</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://iotexpert.com/2017/02/23/psoc4-freertos-port/" target="_blank" rel="noopener noreferrer">FreeRTOS: A PSoC4 FreeRTOS Port</a></td>
<td >An introduction to making FreeRTOS work on PSoC 4</td>
</tr>

<tr><td ><a href="https://iotexpert.com/2017/05/23/freertos-psoc-examples/" target="_blank" rel="noopener noreferrer">FreeRTOS PSoC Examples</a></td>
<td >Using multiple tasks in FreeRTOS</td>
</tr>

<tr><td ><a href="https://iotexpert.com/2017/05/25/psoc-freertos-queue-example/" target="_blank" rel="noopener noreferrer">FreeRTOS Queue Example</a></td>
<td >Using a queue to communicate between tasks</td>
</tr>

<tr><td ><a href="https://iotexpert.com/2017/05/30/psoc-6-freertos-first-example/" target="_blank" rel="noopener noreferrer">PSoC 6 FreeRTOS - The First Example</a></td>
<td >Booting FreeRTOS on PSoC 6</td>
</tr>

<tr><td ><a href="https://iotexpert.com/2017/06/01/psoc-freertos-binary-semaphore/" target="_blank" rel="noopener noreferrer">FreeRTOS Binary Semaphore</a></td>
<td >An first example of a binary semaphore</td>
</tr>

<tr><td ><a href="https://iotexpert.com/2017/06/08/psoc-freertos-binary-semaphore-part-2/">FreeRTOS Binary Semaphore (Part 2)</td>
<td >Removing polling in the UART Task</a></td>
</tr>

<tr><td ><a href="https://iotexpert.com/2017/06/20/psoc-freertos-counting-semaphore/" target="_blank" rel="noopener">FreeRTOS Counting Semaphore</a></td>
<td >An example using a counting semaphore</td>
</tr>

<tr><td ><a href="https://iotexpert.com/2017/06/22/psoc-freertos-sharing-the-i2c-bus/" target="_blank" rel="noopener">PSoC FreeRTOS</a></td>
<td >Reading I2C Sensors with a shared I2C Bus</td>
</tr>

<tr><td ><a href="https://iotexpert.com/2017/08/22/psoc-freertos-task-notify/" target="_blank" rel="noopener">PSoC FreeRTOS Task Notify</a></td>
<td >A light weight scheme to replace Semaphores</td>
</tr>

<tr><td ><a href="https://iotexpert.com/2017/08/24/psoc-freertos-task-notification-value/" target="_blank" rel="noopener">PSoC FreeRTOS Task Notification Values</a></td>
<td >A very light weight method to transfer one word of information into a task</td>
</tr>
</tbody></table></div></p></span></p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/psoc-freertos-sharing-the-i2c-bus/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Embedded World 2017: The Top Secret New Chip as a Servo Motor Driver</title>
		<link>https://iotexpert.com/embedded-world-2017-the-top-secret-new-chip-as-servo-motor-driver/</link>
					<comments>https://iotexpert.com/embedded-world-2017-the-top-secret-new-chip-as-servo-motor-driver/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Sat, 11 Mar 2017 13:59:34 +0000</pubDate>
				<category><![CDATA[Embedded World 2017]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=3187</guid>

					<description><![CDATA[Summary In this article I will take you through the firmware that I will be using to control the Robot Arm Servo Motors.  The Business Unit Manager is being a total pain the neck about letting me tell too much about his new product before the announcement at Embedded World next week.  He is from Indiana, [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>Summary</h2>
<p>In this article I will take you through the firmware that I will be using to control the Robot Arm Servo Motors.  The Business Unit Manager is being a total pain the neck about letting me tell too much about his new product before the announcement at Embedded World next week.  He is from Indiana, so that probably explains his dogged recalcitrance (just joking&#8230; Im from KY and there is a big rivalry).  Anyway.  You will be able to see some things about the new chip if you look closely what I am doing.  My design will have:</p>
<ul>
<li>An EZI2C to support communication with the WICED I2C Master</li>
<li>Two PWMs to control two servo motors</li>
<li>A connection to the onboard switch and LED to turn the servo PWMs on/off</li>
</ul>
<h2>Building the Servo Firmware</h2>
<p>To make the design I first create a new project and the edit the schematic.  In this new chip there is clearly some logic gates as you can see that I control the PWMs with a Toggle Flip Flop.  Basically every time I press the switch it toggles the flip flop and then either starts or kills the PWMs.  This is very handy when you are trying to figure out what is going on with the PWMs and the servos.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-8.00.17-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-8.00.17-PM.png" alt="" width="657" height="418" class="alignnone size-full wp-image-3198" srcset="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-8.00.17-PM.png 657w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-8.00.17-PM-600x382.png 600w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-8.00.17-PM-300x191.png 300w" sizes="(max-width: 657px) 100vw, 657px" /></a></p>
<p>As in earlier Cypress chips you double click the component to configure it.  Ill start with the PWMs and observe that we have another new GUI for configuring PWMs.  The servo motors want a pulse that is between 1 and 2 ms wide at a frequency of 50hz.  My PWM has a 12 Mhz clock input, which is then divided by 4 with the prescaler, and finally by 60000 by the PWM itself.  That equation yields a period o.052 kHz which (also known as 52hz) as PSoC Creator helpfully tell us.  By setting the compare to 3000 I will end up with a pulse of 1MS (about).</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.00.33-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.00.33-PM.png" alt="Configure the TCPWM" width="690" height="668" class="alignnone wp-image-3195 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.00.33-PM.png 690w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.00.33-PM-600x581.png 600w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.00.33-PM-300x290.png 300w" sizes="(max-width: 690px) 100vw, 690px" /></a></p>
<p>In order to configure the PWM to have the start/kill inputs, I select the Advanced tab and setup the PWM to start when the toggle flip flop goes low.  And I get it to kill (stop) when the toggle flip flop goes high.  I choose active low because the LED that is attached to the circuit to indicate the state to the user is active low.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-8.00.05-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-8.00.05-PM.png" alt="Advanced PWM Configuration" width="658" height="473" class="alignnone wp-image-3200 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-8.00.05-PM.png 658w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-8.00.05-PM-600x431.png 600w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-8.00.05-PM-300x216.png 300w" sizes="(max-width: 658px) 100vw, 658px" /></a></p>
<p>Next I configure the EZI2C by double clicking it.  It looks like there is a new interface for EZI2C as well&#8230; but under inspection there is nothing too tricky.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.03.17-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.03.17-PM.png" alt="Configuring the EZI2C" width="627" height="473" class="alignnone wp-image-3196 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.03.17-PM.png 627w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.03.17-PM-600x453.png 600w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.03.17-PM-300x226.png 300w" sizes="(max-width: 627px) 100vw, 627px" /></a></p>
<p>Once I have the schematic built, I need to assign the Pins which is done using the DWR Pins Menu (as you did with earlier Cypress chips)</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.15.25-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.15.25-PM.png" alt="Pin Assignment" width="1069" height="218" class="alignnone wp-image-3197 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.15.25-PM.png 1069w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.15.25-PM-600x122.png 600w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.15.25-PM-300x61.png 300w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.15.25-PM-768x157.png 768w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-10-at-7.15.25-PM-1024x209.png 1024w" sizes="(max-width: 1069px) 100vw, 1069px" /></a></p>
<p>Hmmm it looks like the new chip comes in a BGA, and seems to have a bunch of pins.  For the purposes of this demo, I assign the two motor pins too two of the pins on the Arduino Adafruit Servo Shield that I am using to make the connectivity easier.  This was a neat way for me to be able to plug in servo motors and provide them with power from something other than the chip, but still drive them with the chip.  Here is a picture of my shield.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/03/IMG_3957.jpg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/03/IMG_3957.jpg" alt="Adafruit Servo Motor Shield" width="4032" height="3024" class="alignnone wp-image-3202 size-full" /></a></p>
<h2>Build the Firmware</h2>
<p>The firmware is very simple.</p>
<ul>
<li>Declare a structure to hold the data from the I2C master (lines 8-11)</li>
<li>Start &amp; Configure the EZI2C (lines 21-23)</li>
<li>Start &amp; the PWMs (lines 24-28)</li>
<li>In the main loop, when there is a complete write from the I2C Master, Update the PWM compare values</li>
<li>The function convertPercentToCompare calculates the compare value required based on a number 0-100 (aka percent)</li>
</ul>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-11-at-8.42.44-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-11-at-8.42.44-AM.png" alt="Servo Motor Firmware" width="718" height="635" class="alignnone wp-image-3209 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-11-at-8.42.44-AM.png 718w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-11-at-8.42.44-AM-600x531.png 600w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-11-at-8.42.44-AM-300x265.png 300w" sizes="(max-width: 718px) 100vw, 718px" /></a></p>
<h2>Testing the Firmware</h2>
<p>To test the firmware I use the Bridge Control Panel to issue I2C Commands (as I did in the earlier post).  You can see that I did a list devices.  Then sent several different percents (they are in hex).</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-11-at-8.48.58-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-11-at-8.48.58-AM.png" alt="Using the Bridge Control Panel to control the Servo Motors" width="934" height="676" class="alignnone wp-image-3210 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-11-at-8.48.58-AM.png 934w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-11-at-8.48.58-AM-600x434.png 600w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-11-at-8.48.58-AM-300x217.png 300w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-11-at-8.48.58-AM-768x556.png 768w" sizes="(max-width: 934px) 100vw, 934px" /></a></p>
<p>Here screenshot from my oscilloscope where you can see that I entered 0x32 (aka 50%) so the width of the pulse is 1.5ms @ 50Hz.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/03/TEK00000.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/03/TEK00000.png" alt="Servo Motor Pulses on Oscilliscope" width="480" height="234" class="alignnone wp-image-3189 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/03/TEK00000.png 480w, https://iotexpert.com/wp-content/uploads/2017/03/TEK00000-300x146.png 300w" sizes="(max-width: 480px) 100vw, 480px" /></a></p>
<p>And it seems to work pretty well at controlling my Servo Motor Robot ARM.  Nicholas looks a little bit crazy, probably the result of too much Solder smoke?</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/03/IMG_3955-e1489195580612.jpg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/03/IMG_3955-e1489195580612.jpg" alt="Nicholas and the Servo Motor Controller" width="3024" height="4032" class="alignnone wp-image-3205 size-full" /></a></p>
<p>In the next article I will make the final connection to the WICED WiFi kit which will give me end to end connectivity through the Amazon IoT Cloud.</p>
<p>Alan</p>
<p>p.s. I love this new chip, you guys are going to be blown away.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/embedded-world-2017-the-top-secret-new-chip-as-servo-motor-driver/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Embedded World 2017: PSoC Analog CoProcessor CapSense GUI</title>
		<link>https://iotexpert.com/embedded-world-2017-psoc-analog-coprocessor-capsense-gui/</link>
					<comments>https://iotexpert.com/embedded-world-2017-psoc-analog-coprocessor-capsense-gui/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Thu, 09 Mar 2017 22:18:22 +0000</pubDate>
				<category><![CDATA[Embedded World 2017]]></category>
		<category><![CDATA[PSoC Creator]]></category>
		<category><![CDATA[WIFI]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=3156</guid>

					<description><![CDATA[Summary I have been building up pieces of code that are going to allow me to show the PSoC Analog CoProcessor &#8211;&#62; WICED WiFi &#8211;&#62; Amazon IoT &#8211;&#62; WICED WiFi &#8211;&#62; Secret New Chip &#8211;&#62; Robot Arm.   In the previous two articles (part1, part2) I have shown you how to build most of the WICED firmware. [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>Summary</h2>
<p>I have been building up pieces of code that are going to allow me to show the <a href="http://www.cypress.com/products/psoc-analog-coprocessor" target="_blank">PSoC Analog CoProcessor</a> &#8211;&gt; <a href="http://www.cypress.com/products/ieee-80211-abgn-wlan-sdio-usb-and-mimo" target="_blank">WICED WiFi</a> &#8211;&gt; <a href="https://aws.amazon.com/iot/" target="_blank">Amazon IoT</a> &#8211;&gt; <a href="http://www.cypress.com/products/ieee-80211-abgn-wlan-sdio-usb-and-mimo" target="_blank">WICED WiFi</a> &#8211;&gt; Secret New Chip &#8211;&gt; Robot Arm.   In the previous two articles (<a href="https://iotexpert.com/2017/03/08/embedded-world-2017-wiced-wifi-mqtt-and-the-amazon-iot-cloud/">part1</a>, <a href="https://iotexpert.com/2017/03/09/embedded-world-2017-wiced-wifi-mqtt-and-the-amazon-iot-cloud-part-2/">part2</a>) I have shown you how to build most of the WICED firmware.  In this article I am going to focus on the PSoC Analog CoProcessor firmware (but if you look real close you can see the secret new chip&#8217;s development kit).</p>
<p>In the picture below you can see the red shield board.  This is a shield with the PSoC Analog CoProcessor plus a bunch of sensors that show the power of that chip.  The shield also includes 4x CapSense Buttons which I am going to use to set the position of the Robot Arm.  The PSoC will serve as a front end companion to the WICED WiFi Development Kit.  They will communicate via I2C with the PSoC acting as an I2C Slave and the WICED WiFi as a master.  Here is a picture of the all of parts minus Amazon.com&#8217;s cloud.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/03/IMG_3844.jpg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/03/IMG_3844.jpg" alt="Embedded World 2017 Components" width="4032" height="3024" class="alignnone wp-image-3162 size-full" /></a></p>
<h2>PSoC Analog CoProcessor</h2>
<p>The PSoC Analog CoProcessor has the new Cypress CapSense block that gives you a bunch of new features, including enough measurement range to measure a capacitative humidity sensor (which you can see in the upper left hand part of the board).  For this demonstration I am just going to use the 4 CapSense buttons.  They will serve as the user interface for the Robot Arm.  The 4 buttons will set 4 different positions, 20%,40%,60%,80%.  I will be talking in much more detail about this shield in coming posts (later next month)</p>
<h2>PSoC Analog CoProcessor Schematic</h2>
<p>The PSoC Creator schematic is pretty straight forward.  I use the EZI2C slave to provide communication for the WICED board.  There are 4x LEDs that sit right next to the CapSense buttons,  and there are the 4x CapSense buttons.  The only slightly odd duck is the Bootloadable component which I use because when I designed the shield I did not put a programmer on it.  The BootLoadable allows me to me to load new firmware into the PSoC via the I2C interface.  Here is the PSoC Creator Schematic:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.12.36-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.12.36-PM.png" alt="PSoC Creator Schematic" width="1024" height="730" class="alignnone wp-image-3169 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.12.36-PM.png 1024w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.12.36-PM-600x428.png 600w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.12.36-PM-300x214.png 300w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.12.36-PM-768x548.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The CapSense configuration just specifies the use of 4x CapSense buttons that are automatically tuned by the Cypress magic.</p>
<p><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.12.58-PM.png" alt="CapSense Configuration" width="1570" height="784" class="alignnone wp-image-3168 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.12.58-PM.png 1570w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.12.58-PM-600x300.png 600w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.12.58-PM-300x150.png 300w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.12.58-PM-768x384.png 768w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.12.58-PM-1024x511.png 1024w" sizes="(max-width: 1570px) 100vw, 1570px" /></p>
<p>The last step in configuring the schematic is to assign all of the pins to the correct locations.</p>
<p><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.13.36-PM.png" alt="Pin Assignment" width="1492" height="560" class="alignnone wp-image-3167 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.13.36-PM.png 1492w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.13.36-PM-600x225.png 600w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.13.36-PM-300x113.png 300w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.13.36-PM-768x288.png 768w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.13.36-PM-1024x384.png 1024w" sizes="(max-width: 1492px) 100vw, 1492px" /></p>
<h2>PSoC Analog CoProcessor Firmware</h2>
<p>One of the great things about all of this process is how easy the firmware is to write.</p>
<ul>
<li>Line 3 declares a buffer that will be used to relay the position information to the WICED board.  I start the position at 50%</li>
<li>Lines 8-9 start the EZI2C which starts up the EZI2C protocol and tells it to read from the &#8220;position&#8221; variable</li>
<li>Lines 10-11 gets the CapSense going</li>
</ul>
<p>Inside of the infinite while(1) loop, I read from the CapSense and do the right thing</p>
<ul>
<li>Lines 17-22 reads the CapSense status</li>
<li>Lines 24-27 set the correct position based on which buttons are pressed (notice that if no button is pressed then the position stays the same)</li>
<li>Line 29 turns on the Bootloader if B0 &amp; B3 are pressed</li>
</ul>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.59.13-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.59.13-PM.png" alt="PSoC Analog CoProcessor Main.c" width="1546" height="1160" class="alignnone wp-image-3174 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.59.13-PM.png 1546w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.59.13-PM-600x450.png 600w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.59.13-PM-300x225.png 300w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.59.13-PM-768x576.png 768w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-4.59.13-PM-1024x768.png 1024w" sizes="(max-width: 1546px) 100vw, 1546px" /></a></p>
<h2>Testing the PSoC Analog CoProcessor System</h2>
<p>The easiest way to test the system is to use the Bridge Control Panel which comes as part of the PSoC Creator installation.  It lets me read the value from the EZ2IC buffer to make sure that the CapSense buttons are doing the right thing.  The command language is pretty simple.  You can see in the editor window that I typed &#8220;W42 0 R 42 X p;&#8221;  Everytime I press &#8220;enter&#8221; it sends the I2C commands:</p>
<ul>
<li>Send an I2C start</li>
<li>write the 7-bit I2C address 0x42</li>
<li>write a 0</li>
<li>send a restart</li>
<li>read from address 0x42</li>
<li>read one byte</li>
<li>send a stop</li>
</ul>
<p>You can see that I pressed each button and indeed got 20,40,60,80 (assuming you can convert hex to decimal&#8230; but trust me)</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-5.01.29-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-5.01.29-PM.png" alt="Bridge Control Panel" width="1866" height="1354" class="alignnone wp-image-3175 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-5.01.29-PM.png 1866w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-5.01.29-PM-600x435.png 600w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-5.01.29-PM-300x218.png 300w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-5.01.29-PM-768x557.png 768w, https://iotexpert.com/wp-content/uploads/2017/03/Screen-Shot-2017-03-09-at-5.01.29-PM-1024x743.png 1024w" sizes="(max-width: 1866px) 100vw, 1866px" /></a></p>
<p>In the next article I will modify the WICED Publisher to poll the PSoC Analog CoProcessor and then publish the current state.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/embedded-world-2017-psoc-analog-coprocessor-capsense-gui/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>ThingSoC: The TSoC GROVEY I2CHUB : I2C Hub/Switch</title>
		<link>https://iotexpert.com/thingsoc-tsoc-grovey-i2chub-i2c-hubswitch/</link>
					<comments>https://iotexpert.com/thingsoc-tsoc-grovey-i2chub-i2c-hubswitch/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Thu, 02 Feb 2017 10:28:39 +0000</pubDate>
				<category><![CDATA[PSoC 4200]]></category>
		<category><![CDATA[ThingSoC]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=2782</guid>

					<description><![CDATA[Pattern Agents are running a crowd funding effort for ThingSoC TSoC4L &#8230; help them here Summary One of the boards that the Pattern Agents guys sent me was a TSOC GROVEY I2CHUB : I2C Hub/Switch.  In this post I will take you through the process that I went through to evaluate the board and build an interface to the ThingSoc TSoC [&#8230;]]]></description>
										<content:encoded><![CDATA[<h4><span style="color: #ff0000;"><span style="color: #008000;">Pattern Agents are running a crowd funding effort for ThingSoC TSoC4L &#8230; help them</span> <a href="https://www.crowdsupply.com/patternagents-llc/thingsoc-grovey?utm_source=thingSOC+Supporters&amp;utm_campaign=f1c4185485-launch_thingsoc_2017_01_23&amp;utm_medium=email&amp;utm_term=0_4aec98a7fc-f1c4185485-112421013" target="_blank" style="color: #ff0000;">here</a></span></h4>
<h2>Summary</h2>
<p>One of the boards that the <a href="http://www.patternagents.com" target="_blank">Pattern Agents</a> guys sent me was a <a href="http://patternagents.com/projects/TSOC_GROVEY_I2CHUB.html" target="_blank">TSOC GROVEY I2CHUB : I2C Hub/Switch</a>.  In this post I will take you through the process that I went through to evaluate the board and build an interface to the ThingSoc TSoC 4L base board.</p>
<ol>
<li>Introduction to the TSoC Grovey I2CHUB</li>
<li>Discussion of PCA9546A I2C</li>
<li>Using the MiniProg-3 to interact with the PCA9546A</li>
<li>Building a Command Line Interface (CLI) using the USB/UART</li>
<li>Adding firmware to mimic the MiniProg-3 I2C list to the CLI</li>
<li>Adding a &#8220;port change&#8221; feature to the CLI firmware</li>
</ol>
<h2>Introduction to the TSoC Grovey I2CHUB</h2>
<p>The ThingSoC I2C Hub is a ThingSoC Compatible (not Compliant) board that serves as a bridge from the base board to 4 separate programmable I2C busses using an NXP/TI 9546A bridge chip.  Each of the I2C busses is attached via a <a href="https://www.seeedstudio.com" target="_blank">SeeedStudio</a> <a href="https://www.seeedstudio.com/category/Grove-c-45.html" target="_blank">Grove connector</a>.  Grove is an ecosystem of sensors (Humidity, Temperature etc.) that are all? mostly? I2C connected.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/01/TSOC_GROVEY_I2CHUB_pop_top.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/TSOC_GROVEY_I2CHUB_pop_top.png" alt="ThingSoC I2CHub" width="640" height="442" class="alignnone wp-image-2793 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/01/TSOC_GROVEY_I2CHUB_pop_top.png 640w, https://iotexpert.com/wp-content/uploads/2017/01/TSOC_GROVEY_I2CHUB_pop_top-600x414.png 600w, https://iotexpert.com/wp-content/uploads/2017/01/TSOC_GROVEY_I2CHUB_pop_top-300x207.png 300w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>
<h2>Discussion of PCA9546A I2C</h2>
<p>The PCA9546A is made by <a href="http://www.ti.com/product/PCA9546A" target="_blank">TI</a> and <a href="http://www.nxp.com/documents/data_sheet/PCA9546A.pdf" target="_blank">NXP</a> (or whatever they are calling themselves these days) and can be purchased for about $0.70 from <a href="http://www.digikey.com/products/en?keywords=pca9546a" target="_blank">Digikey</a>, <a href="http://www.mouser.com/Search/Refine.aspx?Keyword=pca9546A" target="_blank">Mouser</a>, or <a href="https://www.arrow.com/en/products/search?q=pca9546a" target="_blank">Arrow</a>.  The chip is pretty cool.  It will let you connect your I2C master to 1 of 4 I2C busses.  It will actually let you connect more than one bus at a time.  This chip enables you to connect multiple slaves with the same address to your I2C master.</p>
<p>Here is a simplified picture from TIs datasheet.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-12.07.02-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-12.07.02-PM.png" alt="PCA9546A Block Diagram" width="674" height="504" class="alignnone wp-image-2791 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-12.07.02-PM.png 674w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-12.07.02-PM-600x449.png 600w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-12.07.02-PM-300x224.png 300w" sizes="(max-width: 674px) 100vw, 674px" /></a></p>
<p>To control the system you just need to write into the control register with a bit mask.  The bit masks contains which slaves busses you want switched on.  Here is a screen shot from NXPs datasheet:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-12.11.51-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-12.11.51-PM.png" alt="PCA9546A Control Register" width="1019" height="796" class="alignnone wp-image-2792 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-12.11.51-PM.png 1019w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-12.11.51-PM-600x469.png 600w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-12.11.51-PM-300x234.png 300w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-12.11.51-PM-768x600.png 768w" sizes="(max-width: 1019px) 100vw, 1019px" /></a></p>
<h2>Using the MiniProg-3 to interact with the PCA9546A</h2>
<p>I start the whole firmware journey by using a MiniProg-3 as an I2C&lt;&#8211;&gt;USB bridge.  This allows me to type I2C commands in the Bridge Control Panel which go directly to the chip (without writing firmware).  In the picture below you can see that I have the MiniProg-3 attached to the ThingSoC board using jumper wires.  I also use the MiniProg-3 to power the board.</p>
<h2><a href="https://iotexpert.com/wp-content/uploads/2017/01/IMG_3644.jpg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/IMG_3644.jpg" alt="Using a MiniProg-3 to Probe the ThingSoC I2C Hub" width="4032" height="3024" class="alignnone wp-image-2789 size-full" /></a></h2>
<p>When I press &#8220;List&#8221;, the Bridge Control Panel probes all of the I2C addresses.  If a device ACKs, it prints out that fact in the output window.  In the picture below you can see that PCA9546A is attached at address 0x73.  I then read and write the control register, which also works as expected.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-11.35.13-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-11.35.13-AM.png" alt="Bridge Control Panel" width="1123" height="681" class="alignnone wp-image-2790 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-11.35.13-AM.png 1123w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-11.35.13-AM-600x364.png 600w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-11.35.13-AM-300x182.png 300w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-11.35.13-AM-768x466.png 768w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-11.35.13-AM-1024x621.png 1024w" sizes="(max-width: 1123px) 100vw, 1123px" /></a></p>
<p>The address 0x73 makes sense as you can see that (in the picture above) there is a blob of solder on &#8220;A2&#8221; which pulls it low (instead of the default high).  Here is that part of the schematic:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.25.46-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.25.46-PM.png" alt="ThingSoC Schematic for PCA9546A Address Selection" width="1006" height="438" class="alignnone wp-image-2812 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.25.46-PM.png 1006w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.25.46-PM-600x261.png 600w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.25.46-PM-300x131.png 300w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.25.46-PM-768x334.png 768w" sizes="(max-width: 1006px) 100vw, 1006px" /></a></p>
<h2>Building a Command Line Interface (CLI) over the USB/UART</h2>
<p>Now I am  ready to build a command line interface using the USB &lt;&#8211;&gt; UART Bridge.  First, I make a schematic with the USB-FS (Full Speed), LED and I2C components.  Notice that the USBFS is setup as a USBUART.  The I2C is configured as a Master.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.55.41-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.55.41-PM.png" alt="PSoC Creator Schematic for ThingSoC I2C Hub Firmware" width="387" height="424" class="alignnone wp-image-2818 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.55.41-PM.png 387w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.55.41-PM-274x300.png 274w" sizes="(max-width: 387px) 100vw, 387px" /></a></p>
<p>The Pins are selected as:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.57.54-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.57.54-PM.png" alt="PSoC Creator Pin Selection" width="499" height="150" class="alignnone wp-image-2819 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.57.54-PM.png 499w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.57.54-PM-300x90.png 300w" sizes="(max-width: 499px) 100vw, 499px" /></a></p>
<p>Next is a helper function to printout text via the CDC UART:</p>
<p><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.56.12-PM.png" alt="PSoC Creator Firmware PrintBuff Helper Function" width="851" height="216" class="alignnone wp-image-2817 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.56.12-PM.png 851w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.56.12-PM-600x152.png 600w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.56.12-PM-300x76.png 300w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.56.12-PM-768x195.png 768w" sizes="(max-width: 851px) 100vw, 851px" /></p>
<p>Then I write a little bit of firmware for the CLI.  The function just reads from the UART and, if the user has pressed a button, then it issues that command.</p>
<p>Lines 99-103 get the USBUART going, and deal with changes (e.g. unplug events).</p>
<p>The only thing that you might not have seen is the &#8220;Clear Screen&#8221;.  I just send out the escape sequence (old school) for clear screen and move home from the <a href="http://www.climagic.org/mirrors/VT100_Escape_Codes.html" target="_blank">VT100 Escape Codes</a>.</p>
<h2><a href="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-1.37.51-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-1.37.51-PM.png" alt="PSoC Creator Main Command Line Interface" width="905" height="871" class="alignnone wp-image-2802 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-1.37.51-PM.png 905w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-1.37.51-PM-600x577.png 600w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-1.37.51-PM-300x289.png 300w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-1.37.51-PM-768x739.png 768w" sizes="(max-width: 905px) 100vw, 905px" /></a></h2>
<h2>Adding firmware to mimic the MiniProg-3 I2C list to the CLI</h2>
<p>When you press &#8220;List&#8221; in the Bridge Control Panel, what happens?  Although I have been using the Bridge Control Panel for years I wasn&#8217;t exactly sure.  To find the answer, I plugged in my <a href="https://www.saleae.com/originallogic16" target="_blank">Saleae Logic 16</a> and watched the output.</p>
<p><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/IMG_0461.jpg" alt="Probing using MiniProg-3 and Saleae Logic-16" width="4032" height="3024" class="alignnone wp-image-2787 size-full" /></p>
<p>In this screenshot from the Saleae Logic output screen,  you can see that the Bridge Control Panel sends out a &#8220;Read 0x15&#8221; which was NAKed.</p>
<p><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-10.38.09-AM.png" alt="Saleae Logic 16 address 0x15 NAK" width="516" height="160" class="alignnone wp-image-2785 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-10.38.09-AM.png 516w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-10.38.09-AM-300x93.png 300w" sizes="(max-width: 516px) 100vw, 516px" /></p>
<p>In this screen shot you can see that when the &#8220;Read 0x73&#8221; occurs, that the PCA9456A ACKs which tells the Bridge Control Panel that the device is there.</p>
<p><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-10.37.03-AM.png" alt="Saleae Logic 16 0x73 ACK" width="699" height="152" class="alignnone wp-image-2786 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-10.37.03-AM.png 699w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-10.37.03-AM-600x130.png 600w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-10.37.03-AM-300x65.png 300w" sizes="(max-width: 699px) 100vw, 699px" /></p>
<p>While I was writing the entry, I looked around at several implementations.  It appears that sometimes people send &#8220;Write Address&#8221; instead of &#8220;Read Address&#8221;.  I wasn&#8217;t sure exactly what was right, so I consulted <a href="https://iotexpert.com/2017/01/06/drzwave-bio-iot-expert-psoc5-and-z-wave-engineer/" target="_blank">Dr. Zwave</a>.  He really should go by Dr. I2C since that is what he did at Cypress.  Anyway, he pointed out that you will hang the I2C bus if you try a Read and then don&#8217;t read the next byte.  With a write you don&#8217;t actually need to keep writing.  I decided to follow his instructions.</p>
<p>I have always liked the output of the Raspberry Pi I2CDetect command.  Here is a screen shot from one of my Raspberry Pi&#8217;s where a PSoC4 is attached on I2C Address 0x8.  I am not totally sure why the command does not probe addresses 0x00-0x02 (comment with the answer and Ill send you a devkit)</p>
<h2><a href="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-12.27.39-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-12.27.39-PM.png" alt="Raspberry Pi I2CDetect" width="511" height="187" class="alignnone wp-image-2799 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-12.27.39-PM.png 511w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-12.27.39-PM-300x110.png 300w" sizes="(max-width: 511px) 100vw, 511px" /></a></h2>
<p>The implementation of i2c_detect on the PSoC4L is pretty simple.  All I need to do is iterate through all of the addresses from 0-&gt;0x7F.  Then attempt to write.  If a device ACKs then printout the address, otherwise move on.  Instead of  one big loop, I split it up into two loops to make the printing a little bit simpler.  Here is the code:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-1.39.13-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-1.39.13-PM.png" alt="PSoC Creator I2C Detect Firmware" width="866" height="514" class="alignnone wp-image-2803 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-1.39.13-PM.png 866w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-1.39.13-PM-600x356.png 600w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-1.39.13-PM-300x178.png 300w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-1.39.13-PM-768x456.png 768w" sizes="(max-width: 866px) 100vw, 866px" /></a></p>
<p>Now, when I press &#8220;l&#8221; on the CLI, it probes all of the legal addresses on the I2C bus from the PSoC4L.  You can see that only the PCA9546A at address 0x73 is active.  How cool is that?</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-1.39.57-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-1.39.57-PM.png" alt="PSoC Creator Firmware I2CDetect" width="392" height="153" class="alignnone wp-image-2804 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-1.39.57-PM.png 392w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-1.39.57-PM-300x117.png 300w" sizes="(max-width: 392px) 100vw, 392px" /></a></p>
<h2>Adding a &#8220;port change&#8221; feature to the CLI firmware</h2>
<p>The last block of code adds three functions which let me control the PCA9546A control register.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.12.06-PM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.12.06-PM.png" alt="PSoC Creator PCA9546A Control Firmware" width="845" height="715" class="alignnone wp-image-2811 size-full" srcset="https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.12.06-PM.png 845w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.12.06-PM-600x508.png 600w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.12.06-PM-300x254.png 300w, https://iotexpert.com/wp-content/uploads/2017/01/Screen-Shot-2017-01-29-at-2.12.06-PM-768x650.png 768w" sizes="(max-width: 845px) 100vw, 845px" /></a></p>
<p>To test the whole thing, I attach the Saleae Logic Analzer to I2C Port1.  Then I probe to make sure that I can attach and unattached the bus.</p>
<p><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2017/01/IMG_3643-2.jpg" alt="Test Jig for PSoC Creator Firmware" width="4032" height="3024" class="alignnone wp-image-2805 size-full" /></p>
<p><span><p>You can find all of the projects in the TSoC Series at my GitHub ThingSoC repository git@github.com:iotexpert/ThingSoC.git</p>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Index</th>
<th >Description</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://iotexpert.com/2017/01/25/thingsoc-psoc4l/">ThingSoc: TSoC PSoC4L Development Kit from PatternAgents</a></td>
<td >Introduction to ThingSoC</td>
</tr>

<tr><td ><a href="https://iotexpert.com/2017/01/30/thingsoc4l-using-debugging-the-psoc4-clock/" target="_blank">ThingSoC PSoC4L: Using &amp; Debugging the PSoC4 Clock</a></td>
<td >Debugging a beta firmware problem</td>
</tr>

<tr><td ><a href="https://iotexpert.com/2017/02/02/thingsoc-tsoc-grovey-i2chub-i2c-hubswitch/" target="_blank">ThingSoC: The TSoC GROVEY I2CHUB : I2C Hub/Switch</td>
<td >Evaluating the ThingSoC I2C Hub</a></td>
</tr>

<tr><td ><a href="https://iotexpert.com/2017/02/06/thingsoc-psoc4l-i2c-oled-displays/" target="_blank">ThingSoC: Multiple I2C Displays</td>
<td >Using the I2CHUB and U8X8 Library</a></td>
<td >A project using ThingSoC I2C Hub &amp; 4 OLED Displays</td>
</tr>
</tbody></table></div></p></span></p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/thingsoc-tsoc-grovey-i2chub-i2c-hubswitch/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Qinsi-QS5100 Sn63Pb37 Solder Profile</title>
		<link>https://iotexpert.com/qinsi-qs5100-sn63pb37-solder-profile/</link>
					<comments>https://iotexpert.com/qinsi-qs5100-sn63pb37-solder-profile/#comments</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 28 Nov 2016 12:03:07 +0000</pubDate>
				<category><![CDATA[Misc]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=2296</guid>

					<description><![CDATA[About 2 years ago, I bought a Qinsi QS5100 reflow oven from China via Amazon.com.  My decision was based almost completely on the nice youtube video that Ian Lesnet from Dangerous Prototypes posted about his results.  After I got the oven, I successfully built a series of Physics Lab boards with it.  Then one day [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>About 2 years ago, I bought a Qinsi QS5100 reflow oven from China via <a href="https://www.amazon.com/QS-5100-Drawer-Type-Lead-Reflow/dp/B00KDGN9S6/ref=sr_1_fkmr0_1?s=hi&amp;ie=UTF8&amp;qid=1480253579&amp;sr=1-1-fkmr0&amp;keywords=qinsi+qs5100" target="_blank">Amazon.com</a>.  My decision was based almost completely on the nice <a href="https://www.youtube.com/watch?v=GIRLY3VNNVw" target="_blank">youtube video</a> that Ian Lesnet from <a href="http://dangerousprototypes.com/blog/" target="_blank">Dangerous Prototypes</a> posted about his results.  After I got the oven, I successfully built a series of <a href="https://iotexpert.com/category/solutions/physics-lab/" target="_blank">Physics Lab</a> boards with it.  Then one day about a year ago, I got two boards in a row with horrible results which I attributed to the temperature profile.  A few weeks later, I dug around on the internet and decided to change to the Lesnet profile and things seemed to be working again.</p>
<p>I have always had this bouncing around in the back of my head as a potential problem because I wasn&#8217;t SURE about the source of my original problem.  And, I don&#8217;t really believe in magic, but I didn&#8217;t have time to pursue a root cause.  As I have had a little bit of time the last few days, I decided to dig in.  First, I found the data sheet for the Kester solder paste that I have been using.  Here is scan of the printout of a blown up section from the datasheet with my handwritten notes from the Lesnet video (which I incorrectly denote as Sparkfun)</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-8.41.17-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-8.41.17-AM.png" alt="screen-shot-2016-11-27-at-8-41-17-am" width="1153" height="862" class="alignnone size-full wp-image-2299" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-8.41.17-AM.png 1153w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-8.41.17-AM-600x449.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-8.41.17-AM-300x224.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-8.41.17-AM-768x574.png 768w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-8.41.17-AM-1024x766.png 1024w" sizes="(max-width: 1153px) 100vw, 1153px" /></a></p>
<p>In fact in the video Mr. Lesnet shows a screenshot of a solder profile which is similar to the Kester data sheet.  I wondered why he didnt use that profile?</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-8.57.22-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-8.57.22-AM.png" alt="screen-shot-2016-11-27-at-8-57-22-am" width="1285" height="727" class="alignnone size-full wp-image-2302" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-8.57.22-AM.png 1285w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-8.57.22-AM-600x339.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-8.57.22-AM-300x170.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-8.57.22-AM-768x435.png 768w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-8.57.22-AM-1024x579.png 1024w" sizes="(max-width: 1285px) 100vw, 1285px" /></a></p>
<p>I had switched to using the Lesnet profile and was having consistently good results.  However, yesterday I decided that I wanted to compare that program with reality.  I found at least a couple of places on the internet where a comparison of the actual temperature and the programmed temperature were made with a Fluke &amp; Thermocouple.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-9.00.03-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-9.00.03-AM.png" alt="screen-shot-2016-11-27-at-9-00-03-am" width="1292" height="797" class="alignnone size-full wp-image-2300" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-9.00.03-AM.png 1292w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-9.00.03-AM-600x370.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-9.00.03-AM-300x185.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-9.00.03-AM-768x474.png 768w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-9.00.03-AM-1024x632.png 1024w" sizes="(max-width: 1292px) 100vw, 1292px" /></a><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-9.01.36-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-9.01.36-AM.png" alt="screen-shot-2016-11-27-at-9-01-36-am" width="1282" height="800" class="alignnone size-full wp-image-2301" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-9.01.36-AM.png 1282w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-9.01.36-AM-600x374.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-9.01.36-AM-300x187.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-9.01.36-AM-768x479.png 768w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-9.01.36-AM-1024x639.png 1024w" sizes="(max-width: 1282px) 100vw, 1282px" /></a></p>
<p>In the past I used the Fluke/Thermocouple method as well, but I found it difficult to compare a time based profile with instantaneous readings from the Fluke.  Moreover the numbers that you can read from the Kester data sheet don&#8217;t seem to match what you can enter into the QS-5100.  So, what in the world is the oven doing?</p>
<p>What I really wanted was to capture the data in realtime so that I could plot and analyze what the oven was doing.  To do this I used <a href="http://www.cypress.com/documentation/development-kitsboards/cy8ckit-025-psoc-precision-analog-temperature-sensor-expansion" target="_blank">CY8CKIT-025</a> Precision Temperature Sensor Expansion Board attached to a <a href="http://www.cypress.com/documentation/development-kitsboards/cy8ckit-050-psoc-5lp-development-kit" target="_blank">PSoC5LP CY8CKIT-050</a> connected to the Bridge Control Panel to capture the actual PCB temperature into an excel file.  The CY8CKIT-025 has a K-Type thermocouple, a DS600 for cold junction compensation, a thermistor, an RTD and a temperature diode.  When paired with the 20-bit ADC in the PSoC5LP you are able to demonstrate a bunch of different methods for measuring temperature.  I used the example project that came with the kit with one modification, the addition of an &#8220;EZI2C&#8221;.   By putting in an EZI2C I was able to use the Bridge Control Panel to measure the temperature every 100ms and record that data to a file for analysis.  Here are several pictures of the setup:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/IMG_3386.jpg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/IMG_3386-e1480259472617.jpg" alt="img_3386" width="3024" height="4032" class="alignnone wp-image-2312 size-full" /></a></p>
<p>The board on the right side of the CY8CKIT-050 has a little header where you can plug in a miniprog-3 to use as an USB-&gt;I2C bridge</p>
<p><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/IMG_3390.jpg" alt="img_3390" width="4032" height="3024" class="alignnone size-full wp-image-2307" /></p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/IMG_3388.jpg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/IMG_3388.jpg" alt="img_3388" width="4032" height="3024" class="alignnone size-full wp-image-2308" /></a></p>
<p>In the picture below, the PCB has been through about 15 reflows (which is why it looks so crappy).  The yellow wires are holding the board and the thermocouple wire in place.</p>
<p><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/IMG_3392.jpg" alt="img_3392" width="4032" height="3024" class="alignnone size-full wp-image-2306" /></p>
<p>The modification that I made to the Cy8CKIT-025 kit example project were</p>
<ul>
<li>Add the EZI2C Component</li>
</ul>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.26.23-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.26.23-AM.png" alt="screen-shot-2016-11-27-at-10-26-23-am" width="974" height="745" class="alignnone size-full wp-image-2314" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.26.23-AM.png 974w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.26.23-AM-600x459.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.26.23-AM-300x229.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.26.23-AM-768x587.png 768w" sizes="(max-width: 974px) 100vw, 974px" /></a></p>
<ul>
<li>Make a floating point buffer and attach it to the I2C</li>
</ul>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.27.20-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.27.20-AM.png" alt="screen-shot-2016-11-27-at-10-27-20-am" width="621" height="77" class="alignnone size-full wp-image-2315" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.27.20-AM.png 621w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.27.20-AM-600x74.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.27.20-AM-300x37.png 300w" sizes="(max-width: 621px) 100vw, 621px" /></a></p>
<ul>
<li>Save the thermocouple data into the floating point buffer</li>
</ul>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.27.34-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.27.34-AM.png" alt="screen-shot-2016-11-27-at-10-27-34-am" width="562" height="43" class="alignnone size-full wp-image-2316" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.27.34-AM.png 562w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.27.34-AM-300x23.png 300w" sizes="(max-width: 562px) 100vw, 562px" /></a></p>
<p>Once that was done, I can start the Bridge Control Panel and set it up to automatically read from the I2C by first setting up the variable tempC, setting up the read and then setting up the 100ms repeat.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.50.45-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.50.45-AM.png" alt="screen-shot-2016-11-27-at-10-50-45-am" width="519" height="413" class="alignnone size-full wp-image-2319" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.50.45-AM.png 519w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-27-at-10.50.45-AM-300x239.png 300w" sizes="(max-width: 519px) 100vw, 519px" /></a></p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/bcp.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/bcp.png" alt="bcp" width="1500" height="844" class="alignnone size-full wp-image-2318" srcset="https://iotexpert.com/wp-content/uploads/2016/11/bcp.png 1500w, https://iotexpert.com/wp-content/uploads/2016/11/bcp-600x338.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/bcp-300x169.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/bcp-768x432.png 768w, https://iotexpert.com/wp-content/uploads/2016/11/bcp-1024x576.png 1024w" sizes="(max-width: 1500px) 100vw, 1500px" /></a></p>
<p>Now, I can run the whole thing and view the chart.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/bcpgraph.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/bcpgraph.png" alt="bcpgraph" width="1500" height="579" class="alignnone size-full wp-image-2320" srcset="https://iotexpert.com/wp-content/uploads/2016/11/bcpgraph.png 1500w, https://iotexpert.com/wp-content/uploads/2016/11/bcpgraph-600x232.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/bcpgraph-300x116.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/bcpgraph-768x296.png 768w, https://iotexpert.com/wp-content/uploads/2016/11/bcpgraph-1024x395.png 1024w" sizes="(max-width: 1500px) 100vw, 1500px" /></a></p>
<p>All of the temperature measurement is setup, so I can take some real data.  First I look for repeatability by running a couple of heat cycles.  The oven seems to act the same way every time here is an overlay of the 12th and 13th run.  (bad Alan&#8230; label your axis)</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/data-overlay.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/data-overlay.png" alt="data-overlay" width="1424" height="1035" class="alignnone size-full wp-image-2321" srcset="https://iotexpert.com/wp-content/uploads/2016/11/data-overlay.png 1424w, https://iotexpert.com/wp-content/uploads/2016/11/data-overlay-600x436.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/data-overlay-300x218.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/data-overlay-768x558.png 768w, https://iotexpert.com/wp-content/uploads/2016/11/data-overlay-1024x744.png 1024w" sizes="(max-width: 1424px) 100vw, 1424px" /></a></p>
<p>And finally we are ready to do a little bit of analysis.  Here is an annotated plot of Run12 which was done with the Lesnet profile:</p>
<ul>
<li>Preheat 150 degrees 60 seconds</li>
<li>Heat 180 degrees 58 seconds</li>
<li>Solder 210 30 seconds</li>
<li>Keep 180 degrees</li>
<li>Cool 150 degrees</li>
</ul>
<p>Based on the graph you can see that the oven seems to have 4 modes:</p>
<ol>
<li>Heat</li>
<li>Hold</li>
<li>Cool</li>
<li>Cool with fan</li>
</ol>
<p>In the graph below:</p>
<ul>
<li> The heater turns on to drive the temperature to the preheat phase (mode 1).  The oven heater appears to be able to raise the temperature linearly at about 1.6 degrees C per second.  Once it gets to the preheat temperature, it try&#8217;s to hold the temperature at about 145 degrees for 58 seconds (151-93) in mode 2.  Looking at the graph this section isn&#8217;t very flat, so I wonder if there is really a 5th mode?</li>
<li>The oven turns on the heater and the temperature ramps up to about 186 degrees (mode 1), which it then attempts to hold for about 60 seconds (mode 2)</li>
<li>Then the oven turns on the heater and raises the temperature to about 219 degree (mode 1), which it then holds for about 30 seconds (mode 2)</li>
<li>Then the oven lets the temperature drop naturally until it reaches about 180 degrees (mode 3)</li>
<li>Then the oven turns on the fans and drives the temperature in a steeper line down to 150 degrees (mode 4)</li>
<li>Then the oven turns off the fans and lets the oven cool down (mode 3)</li>
</ul>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/analysis.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/analysis.png" alt="analysis" width="1437" height="1068" class="alignnone size-full wp-image-2322" srcset="https://iotexpert.com/wp-content/uploads/2016/11/analysis.png 1437w, https://iotexpert.com/wp-content/uploads/2016/11/analysis-600x446.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/analysis-300x223.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/analysis-768x571.png 768w, https://iotexpert.com/wp-content/uploads/2016/11/analysis-1024x761.png 1024w" sizes="(max-width: 1437px) 100vw, 1437px" /></a></p>
<p>As far as accuracy goes, the time measurement seems pretty good (one website bitched about this).  With regards to temperature it appears that the oven is a bit low during the preheat phase (which is also not very flat) and is a bit high during the heat and solder phases.  I think that I might lower the heat/solder temperatures a little bit.. 5 degrees?</p>
<p>As far as matching the Kester profile goes, or the the profile on the screenshot that Mr. Lesnet showed in his video, the heat/soak phase the temperature is just a little bit high.  However, he never says that his profile is intended for Sn63Pb37 solder so maybe he was trying to achieve something else (that is what I get for making an assumption).  The profile does however, work very well for me for that solder.  So where does that leave me?</p>
<p>The book that came with the oven (which is obviously translated from Chinese into very funny English) says about the same numbers for the preheat and heat and a bit hotter for the solder.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/IMG_3393.jpg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/IMG_3393-e1480265906913.jpg" alt="img_3393" width="3024" height="4032" class="alignnone wp-image-2325 size-full" /></a></p>
<p>But interestingly, the oven does not come pre-programmed that way for any of the default profiles:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/IMG_3394.jpg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/IMG_3394.jpg" alt="img_3394" width="4032" height="3024" class="alignnone size-full wp-image-2326" /></a></p>
<p>The book that came with the oven also has a nice chart with some properties of different alloys of solder.  On that chart it says that the melting point of Sn63Pb37 is 183 degrees. That means that the soak/preheat phase is just below the melting point of the solder.  My best guess it that the spot where the thermocouple measures the temperature-just off of the surface of the board-is actually just touch higher than the actual junction temperature which is why I think that it works.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/IMG_3396.jpg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/IMG_3396-e1480266499912.jpg" alt="img_3396" width="3024" height="4032" class="alignnone wp-image-2328 size-full" /></a></p>
<p>The next real boards that I do I think that I will run an experiment and lower the preheat temperature by 5 degrees.  Unfortunately that still leaves me with the question&#8230; why did I have bad solder joints originally?  I think that the answer is old solder paste, but I am not sure that I will ever know.</p>
<p>That is it. While I was looking for information I found a number of resources on the internet to be useful</p>
<div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Link</th>
<th >Comment</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://www.youtube.com/watch?v=GIRLY3VNNVw" target="_blank">Ian Lesnet youtube video</td>
<td ></a></td>
</tr>

<tr><td ><a href="https://www.youtube.com/watch?v=PzhkTR0K8-w&amp;t=428s" target="_blank">Marks Tech Channel teardown of QS-5100</a></td>
<td >He warns you that a wire isn't connected properly</td>
</tr>

<tr><td ><a href="http://www.kester.com/DesktopModules/Bring2mind/DMX/Download.aspx?Command=Core_Download&amp;EntryId=1523&amp;language=en-US&amp;PortalId=0&amp;TabId=96" target="_blank">Kester Datasheet</a></td>
<td >Graph profile on 2nd page of document</td>
</tr>

<tr><td ><a href="https://www.youtube.com/watch?v=FEe6QbErEQw" target="_blank">Reflow 7 youtube video</a></td>
<td >A sweep of the temperature measured with a multi-meter</td>
</tr>

<tr><td ><a href="http://dangerousprototypes.com/forum/viewtopic.php?f=68&amp;t=5118&amp;p=61671" target="_blank">Dangerous Prototype Forum discussion</a></td>
<td >a few solder profiles + some proposed modifications</td>
</tr>

<tr><td ><a href="http://makeict.org/wiki/Qinsi_QS-5100_IR_reflow_oven" target="_blank">MakeICT scan of QS-5100 manual</a></td>
<td >Just a scan of the manual</td>
</tr>

<tr><td ><a href="http://www.eevblog.com/forum/reviews/qs-5100-reflow-oven-any-tips-warings-etc/" target="_blank">An EEVBlog Forum discussion of the QS-5100</a></td>
<td >A bit of chatter</td>
</tr>

<tr><td ><a href="http://www.despectus.co.uk/index.php/blog/chronicles-1-rapid-prototyping-with-the-qinsi-qs-5100-part-1" target="_blank">Despectus blog teardown of QS-5100</a></td>
<td >A modification of the placement of the thermocouple</td>
</tr>

<tr><td ><a href="https://labitat.dk/wiki/Reflow_Oven_QS" target="_blank">Labitat wiki</a></td>
<td >A few different reflow profiles &amp; instructions</td>
</tr>
</tbody></table></div>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/qinsi-qs5100-sn63pb37-solder-profile/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Electronica 2016 &#8211; CY8CKIT-145 User Interface</title>
		<link>https://iotexpert.com/electronica-2016-cy8ckit-145-user-interface/</link>
					<comments>https://iotexpert.com/electronica-2016-cy8ckit-145-user-interface/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 07 Nov 2016 10:07:08 +0000</pubDate>
				<category><![CDATA[Cy8CKIT-145]]></category>
		<category><![CDATA[Electronica 2016]]></category>
		<category><![CDATA[PSoC Creator]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=2225</guid>

					<description><![CDATA[I finally made it to Munich late yesterday afternoon&#8230; then I proceeded to turn my hotel room into an electronics lab as I frantically worked to finish everything for tomorrow.  Earlier this year I wrote a whole series of posts about the PSoC4000S &#38; CY8CKIT-145 after the Embedded World show.  We finally have volume production [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>I finally made it to Munich late yesterday afternoon&#8230; then I proceeded to turn my hotel room into an electronics lab as I frantically worked to finish everything for tomorrow.  Earlier this year I wrote a whole series of posts about the <a href="https://iotexpert.com/2016/02/29/psoc4000s-and-the-cy8ckit145-stamp-board-part-1/" target="_blank">PSoC4000S &amp; CY8CKIT-145</a> after the Embedded World show.  We finally have volume production on the development kit and will be giving them out at the show this week.  So, I decided to use the -145 as part of the user interface for my Electronica project.  The devkit functions as the block labeled &#8220;PSoC Capsense&#8221;.  The wire between the &#8220;PSoC Capsense&#8221; and the &#8220;WICED WiFi&#8221; will be I2C (the green and red wire from the picture below)</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/electronica-wiced.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/electronica-wiced.png" alt="electronica-wiced" width="1197" height="868" class="alignnone wp-image-2177 size-full" srcset="https://iotexpert.com/wp-content/uploads/2016/11/electronica-wiced.png 1197w, https://iotexpert.com/wp-content/uploads/2016/11/electronica-wiced-600x435.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/electronica-wiced-300x218.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/electronica-wiced-768x557.png 768w, https://iotexpert.com/wp-content/uploads/2016/11/electronica-wiced-1024x743.png 1024w" sizes="(max-width: 1197px) 100vw, 1197px" /></a></p>
<p>The -145 devkit has the PSoC4000S silicon on it which has the new mutual capacitance capsense block.  On the devkit, there are three mutual cap buttons and one slider.  Here is a picture of the devkit connected to the WICED WiFi board that I am going to use:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/IMG_3318.jpg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/IMG_3318.jpg" alt="img_3318" width="4032" height="3024" class="alignnone wp-image-2226 size-full" /></a></p>
<p>I want to make as simple of a PSoC Creator project as I can possibly do as I want to be able to easily do it live.  Here it is:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.12.23-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.12.23-AM.png" alt="screen-shot-2016-11-07-at-10-12-23-am" width="888" height="720" class="alignnone wp-image-2228 size-full" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.12.23-AM.png 888w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.12.23-AM-600x486.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.12.23-AM-300x243.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.12.23-AM-768x623.png 768w" sizes="(max-width: 888px) 100vw, 888px" /></a></p>
<p>The CapSense block is configured with three mutual cap buttons and 1 self-cap slider:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.13.54-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.13.54-AM.png" alt="screen-shot-2016-11-07-at-10-13-54-am" width="1726" height="1142" class="alignnone size-full wp-image-2229" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.13.54-AM.png 1726w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.13.54-AM-600x397.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.13.54-AM-300x198.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.13.54-AM-768x508.png 768w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.13.54-AM-1024x678.png 1024w" sizes="(max-width: 1726px) 100vw, 1726px" /></a></p>
<p>On this development board, the three mutual cap buttons share the same transmit line, so you need to configure the component that way. The screen shot below shows the configuration of the &#8220;Button1_Tx&#8221; which is set to share the &#8220;Button0_Tx&#8221;.  You need to make the same setting for &#8220;Button2_Tx&#8221;.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.15.34-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.15.34-AM.png" alt="screen-shot-2016-11-07-at-10-15-34-am" width="1728" height="1144" class="alignnone size-full wp-image-2230" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.15.34-AM.png 1728w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.15.34-AM-600x397.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.15.34-AM-300x199.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.15.34-AM-768x508.png 768w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.15.34-AM-1024x678.png 1024w" sizes="(max-width: 1728px) 100vw, 1728px" /></a></p>
<p>The next step is to assign all of the pins to the proper locations:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.18.10-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.18.10-AM.png" alt="screen-shot-2016-11-07-at-10-18-10-am" width="1294" height="880" class="alignnone size-full wp-image-2232" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.18.10-AM.png 1294w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.18.10-AM-600x408.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.18.10-AM-300x204.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.18.10-AM-768x522.png 768w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.18.10-AM-1024x696.png 1024w" sizes="(max-width: 1294px) 100vw, 1294px" /></a></p>
<p>Finally the smallest amount of firmware that I could think up to hold it all together.</p>
<p>Line 3-6: define a structure that the WICED board will be able to read.  It will represent the position of two of the Servo motors.  The CY_PACKED provides the compiler appropriate key words to make the bytes be right next to each other in the RAM, i.e. not word aligned..</p>
<p>Line 8: initializes both positions to 50%.</p>
<p>Lines 12-17 get the components going</p>
<p>Line 22: Checks to make sure that the CapSense block is not scanning before it reads the results</p>
<p>Line 24: Tells the CapSense block to process the results from the previous scan</p>
<p>Lines 25-31: Looks at the three buttons, sets the LEDs and sets pos1 to be either 25%, 50% or 75%</p>
<p>Line 33: Reads the position of the slider and assigns it to &#8220;pos0&#8221;</p>
<p>Lines 34-35: Gets the scanning going again</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.21.02-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.21.02-AM.png" alt="screen-shot-2016-11-07-at-10-21-02-am" width="1548" height="1254" class="alignnone size-full wp-image-2233" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.21.02-AM.png 1548w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.21.02-AM-600x486.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.21.02-AM-300x243.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.21.02-AM-768x622.png 768w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.21.02-AM-1024x830.png 1024w" sizes="(max-width: 1548px) 100vw, 1548px" /></a></p>
<p>To test the system I first used the bridge control panel.  First, connect to the kitprog2.  Then I setup a read from the I2C address (0x08) which is the address of my board.  I then click repeat which runs the read command over and over again.  In the picture below you can see that I tested the three position of the button (25,50 and 75 which are also known as 0x19, 0x32 and 0x4B).  Then I tested the slider by touching it about in the middle (0x3A)</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.31.52-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.31.52-AM.png" alt="screen-shot-2016-11-07-at-10-31-52-am" width="1722" height="1358" class="alignnone size-full wp-image-2235" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.31.52-AM.png 1722w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.31.52-AM-600x473.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.31.52-AM-300x237.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.31.52-AM-768x606.png 768w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.31.52-AM-1024x808.png 1024w" sizes="(max-width: 1722px) 100vw, 1722px" /></a></p>
<p>The next thing to do was make sure that the WICED devkit could read my I2C slave, so I wrote some WICED firmware to read the I2C registers every 500ms:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.55.08-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.55.08-AM.png" alt="screen-shot-2016-11-07-at-10-55-08-am" width="1578" height="1176" class="alignnone size-full wp-image-2237" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.55.08-AM.png 1578w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.55.08-AM-600x447.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.55.08-AM-300x224.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.55.08-AM-768x572.png 768w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.55.08-AM-1024x763.png 1024w" sizes="(max-width: 1578px) 100vw, 1578px" /></a></p>
<p>But, occasionally I  was getting a &#8220;read failed&#8221;:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.58.48-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.58.48-AM.png" alt="screen-shot-2016-11-07-at-10-58-48-am" width="1490" height="1476" class="alignnone size-full wp-image-2238" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.58.48-AM.png 1490w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.58.48-AM-100x100.png 100w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.58.48-AM-600x594.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.58.48-AM-150x150.png 150w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.58.48-AM-300x297.png 300w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.58.48-AM-768x761.png 768w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.58.48-AM-1024x1014.png 1024w" sizes="(max-width: 1490px) 100vw, 1490px" /></a></p>
<p>Last night in my sleep deprived state I was struggling like crazy to figure it out.  This morning after some sleep I realized that the WICED board that I have must not like getting its I2C clock stretched.  So, I changed the priority of the I2C interrupt on the PSoC and that fixed the problem:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.28.03-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.28.03-AM.png" alt="screen-shot-2016-11-07-at-10-28-03-am" width="716" height="198" class="alignnone size-full wp-image-2234" srcset="https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.28.03-AM.png 716w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.28.03-AM-600x166.png 600w, https://iotexpert.com/wp-content/uploads/2016/11/Screen-Shot-2016-11-07-at-10.28.03-AM-300x83.png 300w" sizes="(max-width: 716px) 100vw, 716px" /></a></p>
<p>Keep watching here for more updates on the project.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/electronica-2016-cy8ckit-145-user-interface/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
