#include "serial_communications.h"

/** @name buffer.c 

    This file contains functions to handle the input and output serial port buffers.

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

/*@{*/


#if PC_SERIAL_CHECK
int mid_packet;
#endif

/** Buffer to store information received from the port */
Buffer input_buffer;
/** Buffer to store information sent to the port */
Buffer output_buffer;

/*************************************************************************/
/** Initialise a buffer.
    Clear variables in the buffer structure.

    @param *buffer Buffer, a pointer to the buffer.
    @return void. */
/*************************************************************************/
void buffer_init(Buffer *buffer)
{
  buffer->start = 0;
  buffer->end  =  0;
  buffer->length = 0;
}

/*************************************************************************/
/** Write a character to the buffer.
    Add another character to storage and update buffer structure.

    @param *chr char, a pointer the the character to be stored.
    @param *buffer Buffer, a pointer to the buffer.
    @return -1 if the buffer is full, 0 otherwise. */
/*************************************************************************/
int write_buffer(char *chr, Buffer *buffer)
{ 
  /* Check if buffer is full */
  if(buffer_full(buffer))
    return -1;
  
  buffer->data[buffer->end] = *chr;

  buffer->length++;
  buffer->end++;
  if(buffer->end==BUFFER_LENGTH) /* wrap around */
    buffer->end = 0;
  
  return 0;
}

/*************************************************************************/
/** Read a character from the buffer.
    Read a character from the buffer structure.

    @param *chr char, a pointer the the character to be read.
    @param *buffer Buffer, a pointer to the buffer.
    @return -1 if the buffer is empty, 0 otherwise. */
/*************************************************************************/
int read_buffer(char *chr, Buffer *buffer)
{
  /* Check if buffer is empty */
  if(buffer_empty(buffer))
    return -1;

  /* Take a character */
  *chr = buffer->data[buffer->start];

  buffer->length--;
  buffer->start++;
  if(buffer->start==BUFFER_LENGTH) /* wrap around */
    buffer->start = 0;
  return 0;
}

/*************************************************************************/
/** Buffer Length.
    Return the length of the buffer.

    @param *buffer Buffer, a pointer to the buffer.
    @return int, the length  */
/*************************************************************************/
int buffer_length(Buffer *buffer)
{
  return buffer->length;
}

/*************************************************************************/
/** Buffer Full.
    Check if the buffer is full.

    @param *buffer Buffer, a pointer to the buffer.
    @return bool, buffer status. */
/*************************************************************************/
bool buffer_full(Buffer *buffer)
{
  return (buffer_length(buffer)>=BUFFER_LENGTH);
}

/*************************************************************************/
/** Buffer Empty.
    Check if the buffer is empty.

    @param *buffer Buffer, a pointer to the buffer.
    @return bool, buffer status. */
/*************************************************************************/
int buffer_empty(Buffer *buffer)
{
  return (buffer_length(buffer)<=0);
}

/*************************************************************************/
/** Read Serial Data.
    Read all available data from the serial port and store it.

    @param serial_port int, the serial port.
    @return void. */
/*************************************************************************/
void read_serial_data(int serial_port)
{
  int number;
  char c;
  int length, i;
  
  number = OSCheckInRS232(serial_port);
  while((number!=0)&&(!buffer_full(&input_buffer))) {
    if(OSRecvRS232(&c,serial_port)!=0) {
#if DEBUG
      LCDPrintf("Er: Trans\n");
#endif
    }
    write_buffer(&c, &input_buffer);
#if PC_SERIAL_CHECK /* Write incoming serial data to pt 1 for observation */
    if(c=='!') mid_packet=0;
    if(mid_packet==0) {
      OSSendRS232(&c,SERIAL1);
    }
    if(c=='#') mid_packet=1;
#endif
    number--;
  }
}

/*************************************************************************/
/** Write Serial Data.
    Write the serial data from the output buffer to the serial port.

    @param serial_port int, the serial port.
    @return void. */
/*************************************************************************/
void write_serial_data(int serial_port)
{
  char c;
  int number;

  number = OSCheckOutRS232(serial_port);
  
  while ((number<2000)&&(!buffer_empty(&output_buffer))) {
    read_buffer(&c, &output_buffer);
    OSSendRS232(&c, serial_port);
    number++;
  }
  if(number>=2000)
    LCDPrintf("Buffer Error\n");
}

/*************************************************************************/
/** Read a character from the input buffer.
    Get the next character from the input buffer.

    @param *character char, the character that will be read.
    @return int, -1 if the buffer is empty, 0 otherwise.
/*************************************************************************/
int OSRecvBuff(char* character)
{
  if(!buffer_empty(&input_buffer)){
    read_buffer(character, &input_buffer);
    return 0;
  }

  return -1;
}

/*************************************************************************/
/** Length of the input buffer.
    Return the length of the input buffer.

    @param void
    @return int, the buffer length.
/*************************************************************************/
int OSCheckInBuff()
{
  return buffer_length(&input_buffer);
}

/*************************************************************************/
/** Flush the input buffer
    Clear all pending data from the input buffer.

    @param void
    @return void.
/*************************************************************************/
void OSFlushInBuff()
{
  buffer_init(&input_buffer);
}

/*************************************************************************/
/** Write a character to the output buffer.
    Put a character at the end of the ouput buffer.

    @param *character char, the character to be written.
    @return int, -1 if the buffer is full, 0 otherwise.
/*************************************************************************/
int OSSendBuff(char* character)
{
  if(!buffer_full(&output_buffer)) {
    write_buffer(character, &output_buffer);
    return 0;
  }
  return -1;
}

/*************************************************************************/
/** Length of the output buffer.
    Return the length of the output buffer.

    @param void
    @return int, the buffer length.
/*************************************************************************/
int OSCheckOutBuff()
{
  return buffer_length(&output_buffer);
}

/*************************************************************************/
/** Flush the output buffer
    Clear all pending data from the output buffer.

    @param void
    @return void.
/*************************************************************************/
void OSFlushOutBuff()
{
  buffer_init(&output_buffer);
}










