Simple IO to debug Terminal for C programs on Atom Pro

This code is nowhere near production quality yet, but at least now I can output text at 9600 baud to the terminal window of the Atom Pro IDE, which does make it a lot easier to debug stuff then to continue blinking LEDs. I will probably expand on this code later, probably converting most of the output code to assembly language as to get the bit periods more exact. Likewise abstract it away from just the debug terminal (H8 IO pin P14) as I may have other serial devices I may want to communicate with.

As I said this is a work in progress. I should check on the Oscilloscope to see how close I am to hardware driver, but for now it worked close enough to display a few lines of text…

Just in case anyone else wants to play:

#include "SerIO.h"
extern "C" {
#include "3694s.h"
};


/* writes a character at the current location, updates
   current location to next space (to right) */
#ifndef F_CPU
#define F_CPU	16000000L
#endif

// Roughly calculate the number of times to go in our loop.  The main loop in the delay takes maybe 8 clocks per cycle...
#define DELAY_LOOP_COUNT ((((unsigned short)(F_CPU/9600))-75)/8)


void _Delay(unsigned int us)
{

   while ( us ) { us--; }  /* 6 cpu cycles per loop */
 
}




void WriteSOutCh(char ch)
{
	#define ASYNC_HIGH		1
	#define ASYNC_LOW		0
	// first initialize the P14 to be output and standard IO.
	IO.PMR1.BIT.IRQ0 = 0;		// Standard IO pin
	IO.PCR1 |=0x10;				// make sure the pin is set to Output.

	
	// Here is the workhorse.
	int i;
	
	
	// Need to first output the Start Bit
	IO.PDR1.BIT.B4 = ASYNC_LOW;
	_Delay(DELAY_LOOP_COUNT);	// try to convert to number of loops to wait. 35 approx cycles used elsewhere...
	
	for (i=0;i<8;i++)
	{
		// Output each bit
		if (ch & 1)
			IO.PDR1.BIT.B4 = ASYNC_HIGH;
		else
			IO.PDR1.BIT.B4 = ASYNC_LOW;

		ch = ch >> 1;
		_Delay(DELAY_LOOP_COUNT);	// try to convert to number of loops to wait. 35 approx cycles used elsewhere...
	}
	
	// Now output Stop Bit
	IO.PDR1.BIT.B4 = ASYNC_HIGH;
	_Delay(DELAY_LOOP_COUNT);	// try to convert to number of loops to wait. 35 approx cycles used elsewhere...
}


void WriteSOutString(char *psz)
{
	// bugbug should validate address
	while (*psz)
	{
		WriteSOutCh(*psz++);
	}
}

I also wrote a quick and dirty “itoa” function to use with this, as I found using sprintf bloated the code to download. Went back down from 30248 to 2314 bytes.

[code]/==============================================================================================
// Quick and dirty itoa function
//
void itoa(int n, char *psz)
{
char *pszT;
char cT;

if (n < 0)
{
	*psz++ = '-';
	n = -n;
}

pszT = psz;

while (n >= 10)
{
	*pszT++ = '0' + n%10;
	n = n/10;
}

*pszT++ = '0' + n%10;		// output last character of number
*pszT-- = '\0';				// output a trailing null character
 	

// now we need to swap the characters to make the correct number
while (psz < pszT)
{
	cT = *pszT;
	*pszT-- = *psz;
	*psz++ = cT;
}

}[/code]

This will allow me to debug my next generation I2C Ping code a little easier, like:

[code] iError = I2C_ReadMultiplRegisters(0xe0, 2, 2, abRegs);
if (iError == 0)
{
char szLine[20];

			iVal = (((unsigned short)abRegs[0])<< 8) + abRegs[1];
			
			// try to output this to the debug terminal
			WriteSOutString((char*)"Ping: ");
			itoa(iVal, szLine);
			WriteSOutString((char *)szLine);
			WriteSOutString((char*)"\n\r");
			
		}

[/code]
versus blinking the LEDS…

[code] iError = I2C_ReadMultiplRegisters(0xe0, 2, 2, abRegs);
if (iError == 0)
{
while (iVal >= 10)
{
IO.PDR8.BIT.B6 = 0x0; /* toggle LED /
ms_sleep(150);
IO.PDR8.BIT.B6 = 0x1; /
toggle LED */
ms_sleep(150);
iVal -= 10;
}

			while (iVal-- > 0)
			{
				IO.PDR8.BIT.B5 = 0x0;    /* toggle LED */
				ms_sleep(150);
				IO.PDR8.BIT.B5 = 0x1;    /* toggle LED */
				ms_sleep(150);
			}
		}

[/code]