/****************************************************************************/
/* Copyright 2016 MBARI.                                                    */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/

#include <xc.h>
#include <string.h>
#include <stdio.h>
#include "HardwareProfile.h"
#include "uart1.h"
#include "timer.h"


extern unsigned short AlarmCnt;//Global incremented in AlarmISR


/*---------------------------------------------------------------------
  Function name: vInitU1/U2
  Description: Initialization of UART1/2 module
  Input parameters: -
  Output parameters: -
-----------------------------------------------------------------------*/
void vInitU1 ( void )
{
	U1MODE = 0; // Clear UART1 mode register
	U1STA = 0;	// Clear UART1 status register

	U1BRG = (FCY/(16*BAUD_RATE_UART1))-1; // Calculate value of baud rate register
    
	U1MODEbits.UARTEN = 1;   // Enable UART1 module
	U1STAbits.UTXEN = 1;     // Enable UART1 transmit 
    
    ANSB = 0xFFF8; //make RB2/U1RX digital input buffer (not analog)
}

void vInitU2 ( void )
{
	U2MODE = 0; // Clear UART2 mode register
	U2STA = 0;	// Clear UART2 status register

	U2BRG = (FCY/(16*BAUD_RATE_UART2))-1; // Calculate value of baud rate register
    
	U2MODEbits.UARTEN = 1;   // Enable UART2 module
	U2STAbits.UTXEN = 1;     // Enable UART2 transmit 
    
    ANSB = 0xFFF8; //make RB2/U1RX digital input buffer (not analog)
}

/*---------------------------------------------------------------------
  Function name: vPutCharU
  Description: Sends one character to UART (use of blocking wait)
  Input parameters: Character to send, UART to send to
  Output parameters: -
-----------------------------------------------------------------------*/
void vPutCharU ( unsigned short cChar, int chan )
{
	if (chan ==1)
    {
        while (U1STAbits.UTXBF); // Waits when the output buffer is full
        U1TXREG = cChar;         // Puts the character to the buffer
    }
    
    if (chan ==2)
     {
        while (U2STAbits.UTXBF); // Waits when the output buffer is full
        U2TXREG = cChar;         // Puts the character to the buffer
    }       
}

/*---------------------------------------------------------------------
  Function name: vPutStrU
  Description: Sends string to UART
  Input parameters: String to send, UART to send to
  Output parameters: -
-----------------------------------------------------------------------*/
void vPutStrU ( char* pcStr, int chan )
{
    unsigned short i=0;
	while( *pcStr != 0 )
	{
        i=0;
		vPutCharU(*pcStr++,chan);
        //while(i<0x1000){i++;};
	}
}

/*---------------------------------------------------------------------
  Function name: cGetCharU
  Description: Receives character from UART1 (non-blocking)
  Input parameters: UART to read from
  Output parameters: Received character
-----------------------------------------------------------------------*/
CHAR cGetCharU( int chan )
{
    if(chan==1)
    {
        if ( U1STAbits.URXDA )    
        {return U1RXREG;}
        else
        {return(0);
        }
    }
    if(chan==2)
    {
        if ( U2STAbits.URXDA )    
        {return U2RXREG;}
        else
        {return(0);
        }
    }
    return(0);
}

int RxStr(int maxchar,char *buf,int ms_to1,int ms_bet) //read RxD1 to LF
 {
  //Read up to maxchars or until LF is read from Rx port into 
  //buf or until ms_bet millisecs elapse
  //between characters. ms_to1 = timeout to reception of 1st char. 
  //Returns number of chars read
  //A NULL is appended but not included in the character count so adjust
  //maxchar accordingly to avoid buffer overrun.
  
  char *ptr;

  AlarmCnt = 0; //reset alarm
    
  while( AlarmCnt<ms_to1  && !U1STAbits.URXDA){}; //wait for first char
  
  if(!U1STAbits.URXDA)return(0); //bail if didnt get anything
  
  for (ptr=buf;ptr<buf+maxchar;ptr++)
   {
      AlarmCnt=0; //reset
      while ( !U1STAbits.URXDA) //Wait for a char
      {
        if ( AlarmCnt >=ms_bet )  //count times the 1 ms alarm has gone off
         {*ptr='\0';//append a NULL but don't count it
           return (ptr-buf) ; //quit if a timeout
         }
       }
     
    if ( (*ptr=(char)cGetCharU(1)) == 0x0d )  //store the waiting character
      {//read an LF
       ptr++;//count the LF 
       break; //quit when LF is read
      }
   }
  *ptr='\0';//append a NULL but don't count it
  return (ptr-buf);
 } // end RxStr
//*******************************************************************************
int RxStr2(int maxchar,char *buf,int ms_to1,int ms_bet) //read RxD2 to LF or ;
 {
  //Read up to maxchars, until LF, or ; is read from Rx port into 
  //buf or until ms_bet millisecs elapse
  //between characters. ms_to1 = timeout to reception of 1st char. 
  //Returns number of chars read
  //A NULL is appended but not included in the character count so adjust
  //maxchar accordingly to avoid buffer overrun.
  
  char *ptr;

  AlarmCnt = 0; //reset alarm  

  while( AlarmCnt<ms_to1  && !U2STAbits.URXDA){}; //wait for first char
  
  if(!U2STAbits.URXDA)return(0); //bail if didnt get anything
  
  for (ptr=buf;ptr<buf+maxchar;ptr++)
   {
      AlarmCnt=0; //reset
      while ( !U2STAbits.URXDA) //Wait for a char
      {
        if ( AlarmCnt >=ms_bet )  //count times the 1 ms alarm has gone off
         {*ptr='\0';//append a NULL but don't count it
           return (ptr-buf) ; //quit if a timeout
         }
       }
    *ptr=(char)cGetCharU(2);  //store the waiting character
    //LATAbits.LATA0 ^= 1;
    
    if (  (*ptr == 0x0a) || (*ptr == 0x3b) ) 
      {//read an LF or semicolon
       ptr++;//count the LF 
       break; //quit when LF is read
      }
   }
  *ptr='\0';//append a NULL but don't count it
  return (ptr-buf);
 } // end RxStr
//*******************************************************************************