#include "serial_communications.h"
#include "rs232.h"

/** @name eye_serial.c 

    This file contains functions pertaining to the handling of the eyebot serial port.

    @author Daniel Storey, UWA, 1998
    @version 1.0   */

/*@{*/

/*************************************************************************/
/** Initialise the serial port.
    Initiate the eyebot port, clear the input and output buffers.

    @param channel Channel, the variable holding the channel data.
    @return void. */
/*************************************************************************/
void initalise_serial_port(Channel channel)
{
  if(OSInitRS232(channel.baudrate, NONE, EYEBOT_SERIAL_PORT)!=0) {
    LCDPrintf("Er: Serial Port\nPress Key 1.");
    KEYWait(KEY1);
  }
#if PC_SERIAL_CHECK
  if(OSInitRS232(SER9600, NONE, SERIAL1)!=0) {
    LCDPrintf("Er: Serial Port 1\n");
    KEYWait(KEY1);
  }
#endif
  OSFlushInBuff();
  OSFlushOutBuff();

  return;
}

/*************************************************************************/
/** Send a string.
    Send a string through the serial port.

    @param str string, the string to be sent.
    @param length int, length of the string to be sent.
    @param channel Channel, the variable holding the channel data.
    @return void. */
/*************************************************************************/
int send_string(char *str, int length, Channel *channel)
{
  int i;

  /* Send Data string */
  for(i=0; i<length; i++)
  {
    OSSendBuff(&str[i]);
    #if VIEW_SERIAL_DATA
      putchar(str[i]);
    #endif
  }

  return 0;
}

/*************************************************************************/
/** Send a check string.
    Send a string to serial port 1 for monitoring.

    @param str string, the string to be sent.
    @param length int, length of the string to be sent.
    @return void. */
/*************************************************************************/
#if PC_SERIAL_CHECK
void send_check_str(char* str, int length)
{
  int i;

  length = strlen(str);
  for(i=0; i<length; i++)
  {
    OSSendRS232(&str[i], SERIAL1);
  }
}
#endif

/*************************************************************************/
/** Read a packet from the serial port.
    Read from the serial port from when a Packet Start Marker is received to when a Packet End Marker is received.

    @param string string, the string to which data is to be written.
    @param channel Channel, the variable holding the channel data.
    @return int, -1 if there has been excess delay when reading from the port, 0 for ok. */
/*************************************************************************/
int read_until_packet_end(Channel *channel)
{
  int i = 0, bytes = 0, flag = 0;
  char c = 0;

  /* check the number of characters that have arrived in the serial port */
  bytes = OSCheckInBuff();
  
  if(bytes==0) /* if there are no bytes, return error, change nothing */
    return -1;

  /* Check if we are continuing a previous frame */
  if(channel->raw_valid==FALSE) { /* Not continuing */    
    /* read until the packet start */
    while(bytes!=0) {
      OSRecvBuff(&c);
      bytes--;
#if DEBUG
      putchar(c);
#endif
      if(c==PACKET_START) {
	flag = 1;
	break;
      }
    }
    
    if(flag==0) /* no frame start found */
      return -1;
    else { /* frame start found */
      channel->raw[0] = c;
      channel->raw_length = 1;
    }
  }

  /* Read in the frame data */
  while(OSCheckInBuff()!=0) {
    OSRecvBuff(&c);
    channel->raw[channel->raw_length] = c;
    channel->raw_length++;
#if DEBUG
    putchar(c);
#endif
    /* Check for frame end */
    if(c==PACKET_END) {
      channel->raw_valid = FALSE;
      channel->raw[channel->raw_length] = '\0';
      channel->raw_length = 0;
#if DEBUG
      LCDPrintf("Str:'%s'\n",channel->raw);
#endif
      return 0;
    }
    /* Check for new frame start */
    if(c==PACKET_START) {
      channel->raw[0] = c;
      channel->raw_length = 1;
    }
  }
  
  channel->raw[channel->raw_length] = '\0';
  channel->raw_valid = TRUE;
  return -1;
}

/*************************************************************************/
/** Set the transceiver to send mode.
    Call the assembly level send routine to change the transceiver status to send.

    @param void.
    @return void. */
/*************************************************************************/
void tx_send(void)
{
  WL_SEND(); /* Assembly language routine */
}

/*************************************************************************/
/** Set the transceiver to receive mode.
    Call the assembly level send routine to change the transceiver status to receive.  

    @param void.
    @return void. */
/*************************************************************************/
void tx_receive(void)
{
  WL_RECV(); /* Assembly language routine */
}


/*************************************************************************/
/** Check for receive switch ok.
    Returns true (clear to send) when there are no bytes to be transmitted from the serial port.

    @param void.
    @return void. */
/*************************************************************************/
bool tx_clear_receive(void)
{
  /* Wait for the serial port to clear */
  return (OSCheckOutRS232(EYEBOT_SERIAL_PORT)==0);
}









