/***********************************************/
/* Demo Program For ET-BASE PIC40/1939(ICSP)   */
/* MCU Control : PIC16F1939                    */
/*             : Run 32MHz(Internal 8MHz+4PLL) */
/* Compiler    : Hitech C Version 9.83         */
/* Function    : USART1 Receive & Echo         */
/***********************************************/
#include <htc.h>						// Required to interface with delay routines
#include <stdio.h>

//Config Run Internal Oscillator 32MHz (Internal 8MHz + 4xPLL)
__CONFIG(FOSC_INTOSC & 					// FOSC = Internal Oscillator
         WDTE_OFF &						// WDT disabled
         PWRTE_ON &     				// Power-up Timer Enable
         MCLRE_ON &						// MCLR pin function is MCLR
         CP_OFF &						// Code Protection Disable
         CPD_OFF &						// Data Protection Disable
         BOREN_OFF &					// Brown-out Reset Disable
         CLKOUTEN_OFF &					// CLKOUT Function Disabled
         IESO_ON &						// Internal/External Switchover mode is enabled
         FCMEN_ON &						// Fail-Safe Clock Monitor is enabled

         //Config2
         WRT_OFF &      				// Write protection off
         VCAPEN_OFF &   				// No capacitor on VCAP pin
         PLLEN_ON &						// 4x PLL enabled
         STVREN_ON &					// Stack Overflow or Underflow will cause a Reset
         BORV_HI &    					// Brown-out Reset Voltage (VBOR) set to 2.5 V       
         LVP_OFF);						// Low-voltage programming Disable        
#define  _XTAL_FREQ 		32000000	// Run 32.00 MHz

#define OUTPUT_PIN      	0
#define INPUT_PIN       	1

/** VR1(RA0): Analog Input ****************************************/
#define InitVR1()         	{ANSELAbits.ANSA0=1;TRISAbits.TRISA0=1;}

/** SW1(RA1): Digital Input ***************************************/
#define InitSW1()     		{ANSELAbits.ANSA1=0;TRISAbits.TRISA1=1;}
#define sw1                	PORTAbits.RA1

/** LED(RA2): Digital Output **************************************/
#define InitLED1()        	{ANSELAbits.ANSA2=0;LATAbits.LATA2=0; TRISAbits.TRISA2=0;}	
#define LED1               	LATAbits.LATA2    
#define LED1_TRIS			TRISA2
#define LED1_On()         	LED1 = 1;    
#define LED1_Off()         	LED1 = 0;
#define LED1_Toggle()      	LED1 = !LED1;

/** RS232(Hardware UART1)*******************************************/
#define UART1_TRISTx   	  	TRISCbits.TRISC6
#define UART1_Tx       	   	PORTCbits.RC6 
#define UART1_TRISRx   	   	TRISCbits.TRISC7
#define UART1_Rx       	   	PORTCbits.RC7    

/** PRIVATE PROTOTYPES *********************************************/
void InitializeUSART(void);
void putch(unsigned char);
unsigned char getch(void);

/** demonstration of various built-in delay mechanisms */
void main(void)
{
  unsigned char Rxdata;

  //Config PIC16F1939 Oscillator : Run 32MHz from Internal 8MHz + PLL(4)
  OSCCONbits.SPLLEN = 1;			// 4x PLL is always enabled
  OSCCONbits.IRCF = 14;				// Internal Oscillator Frequency = 8MHz HF
  OSCCONbits.SCS = 0;				// HF-INTOSC with PLL. Defined by the FOSC<3:0> Configuration bits, CONFIG1H<3:0>.)
  OSCTUNEbits.TUN = 0;  			// Factory-calibrated frequency 

  InitVR1(); 						// VR1 = Analog Input
  InitSW1(); 						// SW1 = Digital Input
  InitLED1();						// LED = Digital Output  
  InitializeUSART();				// Initial USART1

  __delay_ms(500);					// Power-On delay for 500 millisecond 
  printf("\n\rET-BASE PIC40/1939(ICSP)\n\r"); 		    				
  printf("USART1>"); 		
  
  //Loop Receive & Echo RS232
  while(1)
  {
    if((PIR1bits.RCIF))  			// Wait USART1 Receive
    {
      Rxdata = getch();

      if(Rxdata==0x0D)
      {
        printf("\n\rUSART1>"); 		
      }
      else
      {
        putch(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;
        
  UART1_TRISRx = 1;				// RX1 = Input
  UART1_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
  //             = ((32000000/9600)/4) – 1
  //             = 832.3
  //             = 0x0342
  SPBRGH = 0x03;      			// 0x0342 for 32MHz -> 9600 baud
  SPBRG = 0x42;

  BAUDCONbits.ABDOVF = 0;		// No BRG rollover has occurred
  BAUDCONbits.RCIDL = 0;		// Receive operation is active
  BAUDCONbits.SCKP = 0;			// Idle state for transmit (TXx) is high
  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 putch(unsigned char c)
 *
 * PreCondition:    None
 *
 * Input:           unsigned char c - character to print to the UART
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Print the input character to the UART
 *
 * Note:            
 *
 *****************************************************************************/
void putch(unsigned char c)
{  
  TXREG = c;   
  while(!TXSTAbits.TRMT);		// Wait TX Complete
}

/******************************************************************************
 * Function:        unsigned char getch()
 *
 * 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 getch(void)
{
  unsigned char  c;

  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;	
}
