<?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>blog &#124; edwards research &#187; debugging</title>
	<atom:link href="http://blog.edwards-research.com/tag/debugging/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.edwards-research.com</link>
	<description>some notes from our staff...</description>
	<lastBuildDate>Wed, 04 May 2011 02:11:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>PIC32 UART&#160;Console</title>
		<link>http://blog.edwards-research.com/2009/03/pic32-uart-console/</link>
		<comments>http://blog.edwards-research.com/2009/03/pic32-uart-console/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 23:17:38 +0000</pubDate>
		<dc:creator>Jim</dc:creator>
				<category><![CDATA[firmware]]></category>
		<category><![CDATA[tips and tricks]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[microcontroller]]></category>
		<category><![CDATA[pic]]></category>

		<guid isPermaLink="false">http://blog.edwards-research.com/?p=33</guid>
		<description><![CDATA[I hate debugging code without a UART console. Don&#8217;t get me wrong, using the ICD3 is extremely easy, and allows you to quickly debug things that would take a while to debug through the UART console (like structures, large arrays) and allows for setting breakpoints which come in extremely useful to find out why certain [...]]]></description>
			<content:encoded><![CDATA[<p>I hate debugging code without a UART console.  Don&#8217;t get me wrong, using the ICD3 is extremely easy, and allows you to quickly debug things that would take a while to debug through the UART console (like structures, large arrays) and allows for setting breakpoints which come in extremely useful to find out why certain events happened or the program took certain paths, but in developing programs from the ground up, especially with peripherals that you don&#8217;t have libraries for, a UART console is often much easier.</p>
<p>Basically, the UART console allows you to control the flow of your program, dispay diagnostic messages, etc.   A sample of my most recent UART console output is below:</p>
<div id="attachment_34" class="wp-caption alignnone" style="width: 678px"><img class="size-full wp-image-34" title="UART_Console_01" src="http://blog.edwards-research.com/wp-content/uploads/2009/03/croppercapture8.png" alt="UART_Console_01" width="668" height="688" /><p class="wp-caption-text">A sample of my most recent UART console, debugging the ENC28J60 SPI - Ethernet Controller.</p></div>
<p>Implementation is simple.  I enable the UART interrupt, and just pass each character to the Console_HandleChar function.  The Console_HandleChar just adds the character to a buffer (array) and parses the character received.  It handles backspaces correctly (not arrow keys or the delete, home, or end keys, though) and checks for the enter key.</p>
<p>On enter, the buffer is bytewise copied into another buffer (to avoid overwriting / stomping) and a flag (console_entry_flag) is set.  The main loop checks this flag, and if it is set, parses the command.  Most of my debug consoles use a two character comand (0-255) specified as 00-FF in hex.  Anyway, here is the code:</p>
<pre class="brush: cpp; title: ;">
// console.h
#ifndef H_CONSOLE
#define H_CONSOLE

#include &lt;p32xxxx.h&gt;
#include &quot;globals.h&quot;
#include &quot;static.h&quot;
#include &quot;controlboard.h&quot;

#define CONSOLE_BUFFER_WIDTH 32 // Because of iteration variables, this must be &lt; 256

void Console_Init(void);

void Console_HandleChar(unsigned char);

unsigned char Console_getchar(void);

unsigned char Console_getline(void);

#endif
</pre>
<pre class="brush: cpp; title: ;">
// console.c

#include &quot;console.h&quot;

unsigned char console_buffer[CONSOLE_BUFFER_WIDTH];
unsigned char console_buffer_index;

unsigned char console_entry[CONSOLE_BUFFER_WIDTH];
unsigned char console_entry_index;
unsigned char console_entry_flag;

void Console_Init(void)
{
	unsigned char i;

	for(i=0; i&lt;CONSOLE_BUFFER_WIDTH; i++)
	{
		console_buffer[i] = 0x00;
	}

	console_buffer_index = 0x00;

	return;
}

void Console_HandleChar(unsigned char byte)
{
	unsigned char i;

	console_buffer[console_buffer_index++] = byte;

	switch(byte)
	{
		case 0x7F:									//Escape
		case 0x08:
			console_buffer_index -= 2;				//Rem Escape and Last Char
			_mon_putc(byte);
			_mon_putc(' ');
			_mon_putc(byte);
			break;
		case 0x0d:
			printf(&quot;\r\n&quot;);
			for(i=0; i&lt;console_buffer_index; i++)
			{
				console_entry[i] = console_buffer[i];
			}
			console_entry_index = console_buffer_index;
			console_entry_flag = 1;

			// Reset Buffer Index
			console_buffer_index = 0;
			break;
		default:
			_mon_putc(byte);
			break;
	}

	if(console_buffer_index &gt;= CONSOLE_BUFFER_WIDTH)
	{
		printf(&quot;\r\n&quot;);
		console_buffer_index = 0;
	}

	return;
}
</pre>
<p>The main function is simple and I&#8217;ll only show parts that I think are relevant.</p>
<p>Interrupt Handler (PIC32):</p>
<pre class="brush: cpp; title: ;">
void __ISR(_UART_1_VECTOR, ipl4) U1_ISR(void)
{
	if(mU1RXGetIntFlag())
	{
		// Clear the RX interrupt Flag
		mU1RXClearIntFlag();

		// Handle Character
		Console_HandleChar(ReadUART1());
	}

	if ( mU1TXGetIntFlag() )
	{
		mU1TXClearIntFlag();
	}
}
</pre>
<p>Main Loop:</p>
<pre class="brush: cpp; title: ;">
while(1)
{
	if(console_entry_flag)
	{
		if(console_entry_index &lt; 2)
		{
			printf(&quot;1x: ENC Communication                \r\n&quot;);
			printf(&quot;  10: Read Control Register (10xx)   \r\n&quot;);
			printf(&quot;  11: Read Buffer Memory             \r\n&quot;);
			printf(&quot;  12: Write Control Memory (12xxyy)  \r\n&quot;);
			printf(&quot;  13: Write Buffer Memory (13xx)     \r\n&quot;);
			printf(&quot;  14: Bit Field Set (14xxyy)         \r\n&quot;);
			printf(&quot;  15: Bit Field Clear (15xxyy)       \r\n&quot;);
			printf(&quot;  16: Issue Soft Reset               \r\n&quot;);
			printf(&quot;  17: Set ENC Register Bank          \r\n&quot;);
			printf(&quot;  18: Dump ETH Registers in Bank     \r\n&quot;);
			printf(&quot;  19: Dump Entire ETH Controller     \r\n&quot;);
			console_entry_flag = 0;
			continue;
		}
		cmd = form8(ctob(console_entry[0]), ctob(console_entry[1]));
		len = console_entry_index - 1;

		switch(cmd)
		{
			case 0x10:
				if(len &lt; 4){ printf(&quot;Check Syntax.\r\n&quot;); break; }
				address = form8(ctob(console_entry[2]), ctob(console_entry[3]));
				data = ENC_ReadControlRegister(address);
				printf(&quot;ENC[0x%02x] =&gt; 0x%02x\r\n&quot;, address, data);
				break;
			case 0x11:
				data = ENC_ReadBufferMemory();
				printf(&quot;ENC[BM] = 0x%02x\r\n&quot;, data);
				break;
			case 0x12:
				if(len &lt; 6){ printf(&quot;Check Syntax.\r\n&quot;); break; }
				address = form8(ctob(console_entry[2]), ctob(console_entry[3]));
				data = form8(ctob(console_entry[4]), ctob(console_entry[5]));
				ENC_WriteControlRegister(address, data);
				printf(&quot;ENC[0x%02x] &lt;= 0x%02x\r\n&quot;, address, data);
				break;
			case 0x13:
				if(len &lt; 4){ printf(&quot;Check Syntax.\r\n&quot;); break; }
				data = form8(ctob(console_entry[2]), ctob(console_entry[3]));
				ENC_WriteBufferMemory(data);
				printf(&quot;ENC[BM] =&gt; 0x%02x\r\n&quot;, data);
				break;
				break;
			case 0x14:
				if(len &lt; 6){ printf(&quot;Check Syntax.\r\n&quot;); break; }
				address = form8(ctob(console_entry[2]), ctob(console_entry[3]));
				data = form8(ctob(console_entry[4]), ctob(console_entry[5]));
				ENC_BFS(address, data);
				printf(&quot;ENC[0x%02x] &lt;| 0x%02x\r\n&quot;, address, data);
				break;
			case 0x15:
				if(len &lt; 6){ printf(&quot;Check Syntax.\r\n&quot;); break; }
				address = form8(ctob(console_entry[2]), ctob(console_entry[3]));
				data = form8(ctob(console_entry[4]), ctob(console_entry[5]));
				ENC_BFC(address, data);
				printf(&quot;ENC[0x%02x] &lt;: 0x%02x\r\n&quot;, address, data);
				break;
			case 0x16:
				ENC_SoftReset();
				printf(&quot;Soft Reset Issued to ENC\r\n&quot;);
				break;
			case 0x17:
				if(len &lt; 4){ printf(&quot;Check Syntax.\r\n&quot;); break; }
				data = form8(ctob(console_entry[2]), ctob(console_entry[3]));
				ENC_SetBank(data);
				printf(&quot;ENC Bank Set (%1d)\r\n&quot;, data);
				break;
			case 0x18:
				for(i=0; i&lt;0x20; i++)
				{
					data = ENC_ReadControlRegister(i);
					printf(&quot;ENC[0x%02x] = 0x%02x&quot;, i, data);
					if(i % 2 == 1){ printf(&quot;\r\n&quot;); }
					else{ printf(&quot;    &quot;); }
				}
				break;
			case 0x19:
				for(j=0; j&lt;4; j++)
				{
					ENC_SetBank(j);
					printf(&quot;ENC BANK %1d\r\n&quot;, j);
					for(i=0; i&lt;0x20; i++)
					{
						data = ENC_ReadControlRegister(i);
						printf(&quot;[0x%02x] = 0x%02x&quot;, i, data);
						if(i % 4 == 3){ printf(&quot;\r\n&quot;); }
						else{ printf(&quot;    &quot;); }
					}
					printf(&quot;\r\n&quot;);
				}
				break;
			default:
				printf(&quot;Command not found. (%02x)\r\n&quot;, cmd);
				break;
		}
		console_entry_flag = 0;
	}
}
</pre>
<p>Anyway, this should give you a good start to creating your own debugging UART console.</p>
<p>But wait!  I just assumed you knew what to do with a UART console.  Even if your microcontroller had a fully functional UART console, how do you access it.  There are many ways, but I&#8217;ll touch on the few I use:</p>
<ol>
<li>Use a UART &#8211; USB Bridge.  FTDI sells a great IC (somewhat pricey, though, so see #2 for a better solution) that you just slap on the board, connect to the D+ and D- lines of a USB connector (or cut up a USB cable and use that) and connect TX and RX to the microcontroller (remember to switch them, so that the micro&#8217;s RX is connected to the FT chip&#8217;s TX, etc. &#8212; I&#8217;ve screwed that up before) &#8212; and voila.  The FT232RL (my favorite) comes in a small SOIC package, has outputs for LEDs to show transmit/ receive status as well as programmable GPIOs and an internal 3.3V regulator you can run some small draw devices off of.  Highly recommeneded, but again, the parts are around $5/ ea.  Open up minicom (linux), HypterTerminal or Putty (Windows), connect to the right port, set the baud and you&#8217;re good to go.</li>
<li>Use a UART &#8211; USB Bridge breakout board.  SparkFun sells <a href="http://www.sparkfun.com/commerce/product_info.php?products_id=718" target="_blank">these</a>.  They are just the chip I described in #1 on a breakout board.  Solder a 4 pin header on the back of the connector and you have 3.3V, ground, RX and TX.  Connect these with clip leads or stick this pin header into a 4-pin socket you&#8217;ve added on your dev board.  Done and done.</li>
<li>Use the <a href="http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;nodeId=1406&amp;dDocName=en023805" target="_blank">PICKit 2</a>&#8216;s UART Interface &#8212; not as full featured as using a real UART interface, but useful if you don&#8217;t have access to the SparkFun breakout board or a serial cable to hack up (4).  For more info on the PICKit 2&#8242;s UART interface, see <a href="http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;nodeId=1406&amp;dDocName=en023805" target="_blank">here</a> and <a href="http://www.microchip.com/Microchip.WWW.SecureSoftwareList/secsoftwaredownload.aspx?device=en023805&amp;lang=en&amp;ReturnURL=http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;nodeId=1406&amp;dDocName=en023805#" target="_blank">here</a>.</li>
<li>Hack up a serial cable &#8212; google the pin out (like <a href="http://www.lammertbies.nl/comm/cable/RS-232.html" target="_blank">here</a>) &#8212; connect the RX and TX to the right pins on a buffer IC, connect the buffer IC to the micro and connect this to your computer&#8217;s serial port (if you have one).</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.edwards-research.com/2009/03/pic32-uart-console/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

