/************************************************/
/* Demo Program For ET-BASE PIC40/46K80(ICSP)   */
/* MCU Control : PIC18F46K80                    */
/*             : Run 64MHz(Internal 16MHz+4PLL) */
/* Compiler    : C18 Version 3.41               */
/* Function    : USART1,2 Receive & Echo        */
/*             : Baudrate 9600                  */
/************************************************/
// UART2 = Hardware USART
//  ->Jump RD6 = TX2 RS232
//  ->Jump RD7 = RX2 RS232

/** C O N F I G U R A T I O N   B I T S ******************************/
//ETT:ET-BASE PIC40/46K80(PIC18F46K80) 
#pragma config RETEN    = ON            // Ultra low-power regulator is Enabled (Controlled by SRETEN bit)
#pragma config INTOSCSEL = LOW          // LF-INTOSC in Low-power mode during Sleep
#pragma config SOSCSEL  = LOW           // Low Power SOSC circuit selected
#pragma config XINST    = OFF           // Disabled Extended Instruction Set
 
#pragma config FOSC     = INTIO1        // Internal RC oscillator, CLKOUT function on OSC2
#pragma config PLLCFG   = ON            // Oscillator multiplied by 4
#pragma config FCMEN    = ON            // Fail-Safe Clock Monitor enabled
#pragma config IESO     = ON            // Oscillator Switchover mode enabled
#pragma config PWRTEN   = ON          	// Power up timer enabled 
#pragma config BOREN    = SBORDIS       // Brown-out Reset enabled in hardware only (SBOREN is disabled)
#pragma config BORV     = 0             // VBOR set to 3.0V V nominal
#pragma config BORPWR   = LOW           // BORMV set to low power level
#pragma config WDTEN    = OFF           // Watch dog timer is always disabled. SWDTEN has no effect.
#pragma config WDTPS    = 1048576       // 1:1048576
#pragma config CANMX    = PORTB         // ECAN TX and RX pins are located on RB2 and RB3, respectively
#pragma config MSSPMSK  = MSK7          // 7 Bit address masking mode
#pragma config MCLRE    = ON            // MCLR Enabled, RG5 Disabled
#pragma config STVREN   = ON            // Enabled Stack Overflow Reset
#pragma config BBSIZ    = BB2K          // 2K word Boot Block size

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

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

/** POT(RA0)*******************************************************/
#define InitPOT()         {ANCON0bits.ANSEL0=1;TRISAbits.TRISA0=1;}

/** SWITCH(RA1)****************************************************/
#define InitSwitch1()     {ANCON0bits.ANSEL1=0;TRISAbits.TRISA1=1;}
#define sw1                PORTAbits.RA1
 
/** LED(RA2)*******************************************************/
#define InitLED1()        {ANCON0bits.ANSEL2=0;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(Hardware UART1)*******************************************/
#define UART1_TRISTx   	   TRISCbits.TRISC6
#define UART1_Tx       	   PORTCbits.RC6 
#define UART1_TRISRx   	   TRISCbits.TRISC7
#define UART1_Rx       	   PORTCbits.RC7    

/** RS232(Hardware UART2)*******************************************/
#define UART2_TRISTx   	   TRISDbits.TRISD6
#define UART2_Tx       	   PORTDbits.RD6 
#define UART2_TRISRx   	   TRISDbits.TRISD7
#define UART2_Rx       	   PORTDbits.RD7    

#define INPUT_PIN          1
#define OUTPUT_PIN         0

/** Run 64.00 MHz **************************************************/
#define CLOCK_FREQ 		   64000000   
#define GetSystemClock()   64000000

/** PRIVATE PROTOTYPES *********************************************/
void InitializeUSART1(void);
void InitializeUSART2(void);
void myPutcUSART1(char c); 
void myPutcUSART2(char c); 
unsigned char myGetcUSART1(void);
unsigned char myGetcUSART2(void);

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

  //Config PIC18F46K80 Oscillator : Run 64MHz from Internal 16MHz + PLL(4)
  OSCCONbits.IRCF = 7;					// HF-INTOSC output frequency is used (16 MHz)	
  OSCCONbits.OSTS = 0;					// Oscillator Start-up Timer (OST) time-out is running
  OSCCONbits.HFIOFS = 1;				// HF-INTOSC oscillator frequency is stable
  OSCCONbits.SCS = 0;					// HF-INTOSC with PLL. Defined by the FOSC<3:0> Configuration bits, CONFIG1H<3:0>.)
  OSCTUNEbits.PLLEN = 1;  				// x4 PLL enabled = 64MHz

  ANCON0bits.ANSEL2 = 0;                // RA2 = Digital 
  ANCON0bits.ANSEL1 = 0;                // RA1 = Digital 
  ANCON0bits.ANSEL0 = 1;				// RA0 = ADC
  
  Delay10KTCYx(250);					// Delay multiples of 10,000 Tcy
  InitializeUSART1();
  InitializeUSART2();

  myPutcUSART1(0x0D);
  myPutcUSART1(0x0A);
  myPutcUSART1('P');
  myPutcUSART1('I'); 
  myPutcUSART1('C');
  myPutcUSART1('1');
  myPutcUSART1('8');
  myPutcUSART1('F'); 
  myPutcUSART1('4');
  myPutcUSART1('6'); 
  myPutcUSART1('K'); 
  myPutcUSART1('8');
  myPutcUSART1('0');  
  myPutcUSART1(0x0D);
  myPutcUSART1(0x0A);
  myPutcUSART1('U');
  myPutcUSART1('A'); 
  myPutcUSART1('R');
  myPutcUSART1('T');
  myPutcUSART1('1');  
  myPutcUSART1('>'); 

  myPutcUSART2(0x0D);
  myPutcUSART2(0x0A);
  myPutcUSART2('P');
  myPutcUSART2('I'); 
  myPutcUSART2('C');
  myPutcUSART2('1');
  myPutcUSART2('8');
  myPutcUSART2('F'); 
  myPutcUSART2('4');
  myPutcUSART2('6'); 
  myPutcUSART2('K'); 
  myPutcUSART2('8');
  myPutcUSART2('0');  
  myPutcUSART2(0x0D);
  myPutcUSART2(0x0A);
  myPutcUSART2('U');
  myPutcUSART2('A'); 
  myPutcUSART2('R');
  myPutcUSART2('T');
  myPutcUSART2('2');  
  myPutcUSART2('>');  
 
  //Loop Receive & Echo RS232
  while(1)
  {
    if(PIR1bits.RC1IF==1)		// Wait for data to be received
    {
      Rxdata = myGetcUSART1();

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

    if(PIR3bits.RC2IF==1)		// Wait for data to be received
    {
      Rxdata = myGetcUSART2();

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

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

  TXSTA1bits.CSRC = 0; 			// Asynchronous mode: Don’t care. This Bit
  TXSTA1bits.TX9 = 0; 			// Selects 8-bit transmission 
  TXSTA1bits.TXEN = 1;			// Transmit enabled
  TXSTA1bits.SYNC = 0;			// Asynchronous mode
  TXSTA1bits.SENDB = 0;			// Sync Break transmission completed
  TXSTA1bits.BRGH = 1;			// High speed 
  TXSTA1bits.TRMT = 0; 			// Reset Flag Status
  TXSTA1bits.TX9D = 0;			// Don't Care 9th Bit TX 
  
  RCSTA1bits.SPEN = 1;			// Serial port enabled	
  RCSTA1bits.RX9 = 0;			// Selects 8-bit reception
  RCSTA1bits.SREN = 0;			// Asynchronous mode: Don’t care. This Bit
  RCSTA1bits.CREN = 1;			// Enables receiver 
  RCSTA1bits.ADDEN = 0;			// Disables address detection, 
  RCSTA1bits.FERR = 0; 			// No framing erro 
  RCSTA1bits.OERR = 0; 			// No overrun error
  RCSTA1bits.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
  //             = ((64000000/9600)/4) – 1
  //             = 1666
  //             = 0x0682
  SPBRGH1 = 0x06;      			// 0x0682 for 64MHz -> 9600 baud
  SPBRG1 = 0x82;

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

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

/******************************************************************************
 * Function:        void InitializeUSART(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This routine initializes the UART to 9600
 *
 * Note:            
 *
 *****************************************************************************/
void InitializeUSART2(void)
{
  unsigned char c;
        
  UART2_TRISRx = 1;				// RX2 = Input
  UART2_TRISTx = 0;				// TX2 = Output

  TXSTA2bits.CSRC = 0; 			// Asynchronous mode: Don’t care. This Bit
  TXSTA2bits.TX9 = 0; 			// Selects 8-bit transmission 
  TXSTA2bits.TXEN = 1;			// Transmit enabled
  TXSTA2bits.SYNC = 0;			// Asynchronous mode
  TXSTA2bits.SENDB = 0;			// Sync Break transmission completed
  TXSTA2bits.BRGH = 1;			// High speed 
  TXSTA2bits.TRMT = 0; 			// Reset Flag Status
  TXSTA2bits.TX9D = 0;			// Don't Care 9th Bit TX 
  
  RCSTA2bits.SPEN = 1;			// Serial port enabled	
  RCSTA2bits.RX9 = 0;			// Selects 8-bit reception
  RCSTA2bits.SREN = 0;			// Asynchronous mode: Don’t care. This Bit
  RCSTA2bits.CREN = 1;			// Enables receiver 
  RCSTA2bits.ADDEN = 0;			// Disables address detection, 
  RCSTA2bits.FERR = 0; 			// No framing erro 
  RCSTA2bits.OERR = 0; 			// No overrun error
  RCSTA2bits.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
  //             = ((64000000/9600)/4) – 1
  //             = 1666
  //             = 0x0682
  SPBRGH2 = 0x06;      			// 0x0682 for 64MHz -> 9600 baud
  SPBRG2 = 0x82;

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

  c = RCREG2;					// 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 myPutcUSART1(char c)  
{  
  TXREG1 = c;   
  while(!TXSTA1bits.TRMT);		// Wait TX Complete
}

/******************************************************************************
 * 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 myPutcUSART2(char c)  
{  
  TXREG2 = c;   
  while(!TXSTA2bits.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 myGetcUSART1()
{
  char  c;

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

/******************************************************************************
 * 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 myGetcUSART2()
{
  char  c;

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

