/************************************************/
/* Demo Program For ET-BASE PIC40/4550(ICSP)    */
/* MCU Control : PIC18F4550                     */
/*             : Run 48MHz(X-TAL 8.00MHz + PLL) */
/* Compiler    : C18 Version 3.41               */
/* Function    : USART1 Receive & Echo          */
/************************************************/

/** C O N F I G U R A T I O N   B I T S ******************************/
//ETT:ET-BASE PIC40/4550(PIC18F4550) 
#pragma config PLLDIV   = 2         	// (8 MHz crystal on ET-BASE PIC18 board)
#pragma config CPUDIV   = OSC1_PLL2    	// [Primary Oscillator Src: /1][96 MHz PLL Src: /2] 
#pragma config USBDIV   = 2             // Clock source from 96MHz PLL/2
#pragma config FOSC     = HSPLL_HS		// Clock Source = HS+PLL
#pragma config FCMEN    = OFF			// Fail-Safe Clock Monitor disabled
#pragma config IESO     = OFF			// Oscillator Switchover mode disabled
#pragma config PWRT     = ON			// Power-up Timer Enable
#pragma config BOR      = ON			// Brown-out Reset enabled in hardware only (SBOREN is disabled) 
#pragma config BORV     = 0				// Brown-out Reset Voltage = Maximum setting
#pragma config VREGEN   = ON      		// USB Voltage Regulator
#pragma config WDT      = OFF			// WDT disabled (control is placed on the SWDTEN bit) 
#pragma config WDTPS    = 32768			// Watchdog Timer Postscale = 1:32768	
#pragma config CCP2MX   = OFF  			// CCP2 input/output is multiplexed with RB3 
#pragma config PBADEN   = OFF			// PORTB<4:0> pins are configured as digital I/O on Reset
#pragma config LPT1OSC  = OFF			// Timer1 configured for higher power operation 
#pragma config MCLRE    = ON			// MCLR pin enabled; RE3 input pin disabled
#pragma config STVREN   = ON			// Stack full/underflow will cause Reset
#pragma config LVP      = OFF			// Single-Supply ICSP disabled
#pragma config ICPRT    = ON            // ***Enable In-Circuit Debug/Programming***
#pragma config XINST    = OFF       	// Extended Instruction Set
#pragma config DEBUG    = ON            // Background debugger enabled, RB6 and RB7 are dedicated to In-Circuit Debug 

//Disable All Protect
#pragma config CP0      = OFF			// Block 0 (000800-001FFFh) is not code-protected
#pragma config CP1      = OFF			// Block 1 (002000-003FFFh) is not code-protected
#pragma config CP2      = OFF			// Block 2 (004000-005FFFh) is not code-protected
#pragma config CP3      = OFF			// Block 3 (006000-007FFFh) is not code-protected
#pragma config CPB      = OFF			// Boot block (000000-0007FFh) is not code-protected
#pragma config CPD      = OFF			// Data EEPROM is not code-protected 
#pragma config WRT0     = OFF			// Block 0 (000800-001FFFh) is not write-protected
#pragma config WRT1     = OFF			// Block 1 (002000-003FFFh) is not write-protected
#pragma config WRT2     = OFF			// Block 2 (004000-005FFFh) is not write-protected
#pragma config WRT3     = OFF			// Block 3 (006000-007FFFh) is not write-protected
#pragma config WRTC     = OFF			// Configuration registers (300000-3000FFh) are not write-protected
#pragma config WRTB     = OFF       	// Boot block (000000-0007FFh) is not write-protected 
#pragma config WRTD     = OFF			// Data EEPROM is not write-protected
#pragma config EBTR0    = OFF			// Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks
#pragma config EBTR1    = OFF			// Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks
#pragma config EBTR2    = OFF			// Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks 
#pragma config EBTR3    = OFF			// Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks
#pragma config EBTRB    = OFF			// Boot block (000000-0007FFh) is not protected from table reads executed in other blocks
//ETT:ET-BASE PIC40/4550(PIC18F4550)

/** I N C L U D E S **************************************************/
#include "p18f4550.h"
#include "delays.h"
#include "GenericTypeDefs.h"

/** POT(RA0)*******************************************************/
#define InitPOT()          {TRISAbits.TRISA0=1;ADCON1bits.PCFG = 14;}

/** SWITCH(RA1)****************************************************/
#define InitSwitch1()      {TRISAbits.TRISA1=1;}
#define sw1                PORTAbits.RA1
 
/** LED(RA2)*******************************************************/
#define InitLED1()         {LATAbits.LATA2=0; TRISAbits.TRISA2=0;}	
#define LED1               LATAbits.LATA2    
#define LED1_On()          LED1 = 1;    
#define LED1_Off()         LED1 = 0;
#define LED1_Toggle()      LED1 = !LED1;

/** RS232(UART1)****************************************************/
#define UART_TRISTx   	   TRISCbits.TRISC6
#define UART_Tx       	   PORTCbits.RC6 
#define UART_TRISRx   	   TRISCbits.TRISC7
#define UART_Rx       	   PORTCbits.RC7    

#define INPUT_PIN          1
#define OUTPUT_PIN         0

/** Run 48.00 MHz **************************************************/
#define CLOCK_FREQ 		   48000000   
#define GetSystemClock()   48000000

/** PRIVATE PROTOTYPES *********************************************/
void InitializeUSART(void);
void myPutcUSART(char c); 
unsigned char myGetcUSART(void);

/** DECLARATIONS ***************************************************/
#pragma code
void main(void)
{
  unsigned char Rxdata;

  ADCON1bits.PCFG = 14;			// RA0 = ADC Only
  Delay10KTCYx(250);			// Delay multiples of 10,000 Tcy
  InitializeUSART();
  myPutcUSART(0x0D);
  myPutcUSART(0x0A);
  myPutcUSART('P');
  myPutcUSART('I'); 
  myPutcUSART('C');
  myPutcUSART('1');
  myPutcUSART('8');
  myPutcUSART('F'); 
  myPutcUSART('4');
  myPutcUSART('5'); 
  myPutcUSART('5');
  myPutcUSART('0');  
  myPutcUSART(0x0D);
  myPutcUSART(0x0A);
  myPutcUSART('U');
  myPutcUSART('A'); 
  myPutcUSART('R');
  myPutcUSART('T');
  myPutcUSART('1');  
  myPutcUSART('>'); 
 
  //Loop Receive & Echo RS232
  while(1)
  {
    Rxdata = myGetcUSART();

    if(Rxdata==0x0D)
    {
      myPutcUSART(0x0D);
      myPutcUSART(0x0A); 
      myPutcUSART('U');
      myPutcUSART('A'); 
      myPutcUSART('R');
      myPutcUSART('T');
      myPutcUSART('1');  
      myPutcUSART('>'); 
    }
    else
    {
      myPutcUSART(Rxdata);
    }
  }
}

/******************************************************************************
 * Function:        void InitializeUSART(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This routine initializes the UART to 9600
 *
 * Note:            
 *
 *****************************************************************************/
void InitializeUSART(void)
{
  unsigned char c;
        
  UART_TRISRx = 1;				// RX1 = Input
  UART_TRISTx = 0;				// TX1 = Output

  TXSTAbits.CSRC = 0; 			// Asynchronous mode: Don’t care. This Bit
  TXSTAbits.TX9 = 0; 			// Selects 8-bit transmission 
  TXSTAbits.TXEN = 1;			// Transmit enabled
  TXSTAbits.SYNC = 0;			// Asynchronous mode
  TXSTAbits.SENDB = 0;			// Sync Break transmission completed
  TXSTAbits.BRGH = 1;			// High speed 
  TXSTAbits.TRMT = 0; 			// Reset Flag Status
  TXSTAbits.TX9D = 0;			// Don't Care 9th Bit TX 
  
  RCSTAbits.SPEN = 1;			// Serial port enabled	
  RCSTAbits.RX9 = 0;			// Selects 8-bit reception
  RCSTAbits.SREN = 0;			// Asynchronous mode: Don’t care. This Bit
  RCSTAbits.CREN = 1;			// Enables receiver 
  RCSTAbits.ADDEN = 0;			// Disables address detection, 
  RCSTAbits.FERR = 0; 			// No framing erro 
  RCSTAbits.OERR = 0; 			// No overrun error
  RCSTAbits.RX9D = 0; 			// Don't Care 9th Bit RX

  //BRG16(1):BRGH(1) Baudrate = FOSC/[4([SPBRGH:SPBRG]+1)]
  //SPBRGH:SPBRG = ((FOSC/Desired Baud Rate)/4) – 1
  //             = ((48000000/9600)/4) – 1
  //             = 1249
  //             = 0x04E1
  SPBRGH = 0x04;      			// 0x04E1 for 48MHz -> 9600 baud
  SPBRG = 0xE1;

  BAUDCONbits.ABDOVF = 0;		// No BRG rollover has occurred
  BAUDCONbits.RCIDL = 0;		// Receive operation is active
  BAUDCONbits.RXDTP = 0;		// RX data received is not inverted
  BAUDCONbits.TXCKP = 0;		// TX data is not inverted
  BAUDCONbits.BRG16 = 1;		// 16-bit Baud Rate Generator – SPBRGH and SPBRG
  BAUDCONbits.WUE = 0;			// RX pin not monitored or rising edge detected 
  BAUDCONbits.ABDEN = 0;		// Baud rate measurement disabled or completed

  c = RCREG;					// Read For Clear Last Receive
}//end InitializeUSART

/******************************************************************************
 * Function:        void myPutcUSART(char c)
 *
 * PreCondition:    None
 *
 * Input:           char c - character to print to the UART
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Print the input character to the UART
 *
 * Note:            
 *
 *****************************************************************************/
void myPutcUSART(char c)  
{  
  TXREG = c;   
  while(!TXSTAbits.TRMT);		// Wait TX Complete
}

/******************************************************************************
 * Function:        unsigned char myGetcUSART()
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          unsigned char c - character to received on the UART
 *
 * Side Effects:    None
 *
 * Overview:        Print the input character to the UART
 *
 * Note:            
 *
 *****************************************************************************/
unsigned char myGetcUSART()
{
  char  c;

  while(!PIR1bits.RCIF);		// Wait for data to be received

  if (RCSTAbits.OERR)  			// in case of overrun error
  {                    			// we should never see an overrun error, but if we do, 
    RCSTAbits.CREN = 0;  		// reset the port
	c = RCREG;
	RCSTAbits.CREN = 1;  		// and keep going.
  }
  else
  {
    c = RCREG;
  }
  
  return c;
}


	