/***************************************************************************
                          amcserialport.cpp  -  description
                             -------------------
    begin                : Sun Nov 24 2002
    copyright            : (C) 2002 by Martin Merck
    email                : merck@astro.uni-wuerzburg.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is part of the MAGIC control software for the AMC.       *
 *   The software is only intended for use in the MAGIC telescope project  *
 *   All rights remain with the author.					   *
 ***************************************************************************/

#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

#include "amcserialport.h"
#include "amcerrors.h"
#include "amcerror.h"

AMCSerialPort::AMCSerialPort(){
}

AMCSerialPort::~AMCSerialPort()
{
    // close the device if open
    if( tcsetattr( m_fd, TCSANOW, &m_oldtio ) != 0)
    	perror("AMCSerialPort::~AMCSerialPort --- ERROR calling tcsetattr()");
    close( m_fd );
}

/** Open and initialize the serial port */
void AMCSerialPort::init( const char* p_csDevice )
{
    struct termios newtio;

    // open the device
    m_fd = open( p_csDevice, O_RDWR | O_NOCTTY );
    if( m_fd == -1 )
    {
    	perror( "AMCSerialPort::init() --- ERROR calling open()" );
      AMCError aErr( IDS_ERROR_PORT_OPEN );
      throw aErr;
    }

    // get old termio data structure so that we can
    // reset the serial port when exiting.
    if( tcgetattr( m_fd, &m_oldtio ) != 0)
    {
    	perror( "AMCSerialPort::init() --- ERROR calling tcgetattr()" );
      AMCError aErr( IDS_ERROR_PORT_GET_ATTR );
      throw aErr;
    }

    bzero( &newtio, sizeof( newtio ) );
		qDebug("%s", p_csDevice);
//    if( strcmp( p_csDevice, "/dev/ttyS4") == 0)
//		{
//			qDebug("Baudrate is 57600");
//    	newtio.c_cflag = BAUDRATE2 | CS8 | CREAD | CLOCAL;
//		}
//		else
//		{
			qDebug("Baudrate is 115200");
    	newtio.c_cflag = BAUDRATE | CS8 | CREAD | CLOCAL;
//		}

    newtio.c_iflag = IGNPAR | ICRNL;
    newtio.c_oflag = 0;
//    newtio.c_oflag = OCRNL;

    /* set input mode (non-canonical, no echo, ...) */
    newtio.c_lflag = 0;

    newtio.c_cc[VTIME] = 1;   /* inter-character timer set to 1/10 of a second */
    newtio.c_cc[VMIN]  = 0;    /* non-blocking read */

    tcflush( m_fd, TCIFLUSH );
   	if( tcsetattr( m_fd, TCSAFLUSH, &newtio ) != 0)
    {
    	perror( "AMCSerialPort::init() --- ERROR calling tcsetattr()" );
      AMCError aErr( IDS_ERROR_PORT_SET_ATTR );
      throw aErr;
    }

    fcntl( m_fd, F_SETFL, 0);
    return;
}

/** Write one charachter to the serial port */
int AMCSerialPort::transmitChar( char ch )
{
	return write( m_fd, (const void*) &ch, 1);
}

/** Read maxlen characters from the serial port into the buffer */
int AMCSerialPort::readBlock( char* p_pBuffer, int p_iMaxLen )
{
//  usleep(1000);
  int num, iTot = 0;
  char* pBuf = p_pBuffer;
//	for( int i=0; i<3; i++)
//	{
		num = read( m_fd, pBuf, p_iMaxLen );
    pBuf += num;
    iTot += num;
//    qDebug("Read %d Bytes", num);
//		if( num == 0) {
//			num = read( m_fd, pBuf, p_iMaxLen );
//		    usleep(100);
// 				break;
//		    continue;
//		}
//		if( iTot == p_iMaxLen) {
//        break;
//    }
//	}

//  qDebug("Total read %d Bytes", iTot);
	return iTot;
}

/** No descriptions */
void AMCSerialPort::flush()
{
    tcflush( m_fd, TCIOFLUSH );
}
