/*******************************************************************
* FileName:        Morse Code LED Solution.c
* Processor:       PIC18F4520
* Compiler:        MPLAB C18 v.3.06 
*
* This file processes hardcoded string and transmits them using Morse Code
*                                                                     
*
* Creation and Revisions:
*      Author               Date			Comments
*   (your name here)       9/22/09
********************************************************************/

/** Header Files ***************************************************/     
#include <p18f4520.h> 

/** Configuration Bits *********************************************/     
#pragma config OSC = INTIO67
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config BOREN = OFF

/** Define Constants Here ******************************************/
#define MSG1_LENGTH 7
#define MSG2_LENGTH 15
#define TICK_DELAY 125

/** Local Function Prototypes **************************************/
void sendMorseCode(char ary[], int numChars);
void transmitChar(char charToTransmit);
void dot(void);
void dash(void);
void spaceBetweenMarksWithinLetter(void);
void spaceBetweenLetters(void);
void spaceBetweenWords(void);
void spaceAfterMessage(void);
void delayTicks(char numDelays);

/** Global Variables ***********************************************/
	
/*******************************************************************
* Function:        void main(void)
********************************************************************/
#pragma code
void main (void)
{
	char msg1[] = "sos sos";
	char msg2[] = "noon is so soon";
	
	OSCCONbits.IRCF2 = 1;
	OSCCONbits.IRCF1 = 0;
	OSCCONbits.IRCF0 = 1;
	
	ADCON1 = 0x0F;
	TRISB = 0xFE;
	PORTB = 0x00;
	
	sendMorseCode(msg1,MSG1_LENGTH);
	sendMorseCode(msg2,MSG2_LENGTH);
	
	while (1)
    {
		// This area loops forever
    }
}

/*******************************************************************
* Additional Helper Functions
********************************************************************/

void sendMorseCode(char ary[], int numCharsInArray)
{
	int i;
	for (i=0 ; i < numCharsInArray ; i++)
	{
		transmitChar(ary[i]);
		if ( (i+1) < numCharsInArray && ary[i+1] != ' ' && ary[i] != ' ')
			spaceBetweenLetters();
	}	
	spaceAfterMessage();
}

void transmitChar(char charToTransmit)
{
	switch( charToTransmit )
	{
		case ' ':
			spaceBetweenWords();
			break;
		case 's':
			dot();
			spaceBetweenMarksWithinLetter();
			dot();
			spaceBetweenMarksWithinLetter();
			dot();
			break;
		case 'o':
			dash();
			spaceBetweenMarksWithinLetter();
			dash();
			spaceBetweenMarksWithinLetter();
			dash();
			break;
		case 'i':
			dot();
			spaceBetweenMarksWithinLetter();
			dot();
			break;
		case 'n':
			dash();
			spaceBetweenMarksWithinLetter();
			dot();
			break;		
		default:
			break;
	}	
}	
void dot(void)
{
	PORTBbits.RB0 = 1;
	delayTicks(1);
	PORTBbits.RB0 = 0;
}	
void dash(void)
{
	PORTBbits.RB0 = 1;
	delayTicks(3);
	PORTBbits.RB0 = 0;
}	
void spaceBetweenMarksWithinLetter(void)
{
	delayTicks(1);
}	
void spaceBetweenLetters(void)
{
	delayTicks(3);
}	
void spaceBetweenWords(void)
{
	delayTicks(7);
}	
void spaceAfterMessage(void)
{
	delayTicks(14);
}	
void delayTicks(char numDelays)
{
	char i;
	for(i=0 ; i < numDelays ; i++)
	{
		Delay1KTCYx(TICK_DELAY);	
	}	
}