/* ---------------------------------------------------------------------------
 * serial.c - v0.1                                       (c) 2007 Micro-key bv
 * ---------------------------------------------------------------------------
 * Micro-key bv
 * Industrieweg 28, 9804 TG Noordhorn
 * Postbus 92, 9800 AB Zuidhorn
 * The Netherlands
 * Tel: +31 594 503020
 * Fax: +31 594 505825
 * Email: support@microkey.nl  
 * Web: www.microkey.nl
 * ---------------------------------------------------------------------------
 * Description: Serial port interface.
 * ---------------------------------------------------------------------------
 * Version(s):  0.1, 28-11-2007, fvds.
 *                   Creation.
 * ---------------------------------------------------------------------------
 */

/* ---------------------------------------------------------------------------
 * System include files
 * ---------------------------------------------------------------------------
 */
#include <stdio.h>
#include <stdlib.h>


/* ---------------------------------------------------------------------------
 * Application include files
 * ---------------------------------------------------------------------------
 */
#include "LPC23xx.h"
#include "types.h"
#include "serial.h"
#include "armVIC.h"
#include "uart.h"

/* FreeRTOS includes */

/* ---------------------------------------------------------------------------
 * Local constant and macro definitions
 * ---------------------------------------------------------------------------
 */
#define NR_OF_COMPORTS        2


/* ---------------------------------------------------------------------------
 * Global variable definitions
 * ---------------------------------------------------------------------------
 */

/* ---------------------------------------------------------------------------
 * Local variable definitions
 * ---------------------------------------------------------------------------
 */

/* ---------------------------------------------------------------------------
 * Local function definitions
 * ---------------------------------------------------------------------------
 */


/** \brief Initialize of serial interface.*/  
void   serInit (
  t_serial_devices device, 
  UINT16 baudrate, /**< baudrate: B1200, B9600, B19200, B38400, B57600, B115200*/
  UINT8 mode, /**< mode: UART_8N1, UART_7N1, UART_8N2, UART_7N2, UART_8E1, 
                         UART_7E1, UART_8E2, UART_7E2, UART_8O1, UART_7O1, 
                         UART_8O2, UART_7O2 */
  UINT8 fmode /**< fmode: UART_FIFO_OFF, UART_FIFO_1, UART_FIFO_4, UART_FIFO_8, 
                          UART_FIFO_14*/
)
{
	switch( device )
	{
	case(COM1):
		uart0Init( baudrate, mode, fmode );
		break;
	case(COM2):
		uart1Init( baudrate, mode, fmode );
	
	    // Enable Handshake lines as well
        U1_CTS_PINSEL_REG = ( U1_CTS_PINSEL_REG & ~U1_CTS_PINMASK ) | U1_CTS_PINSEL;
        U1_RTS_PINSEL_REG = ( U1_RTS_PINSEL_REG & ~U1_RTS_PINMASK ) | U1_RTS_PINSEL;

		break;
	}
	
}

/** \brief Write data of a certain length to a serial port.*/  
void serWrite (
  t_serial_devices device, 
  UINT16 length, /**< Lengh of data in bytes */ 
  UINT8 * data   /**< Pointer to data */
)
{
	switch( device )
	{
	case(COM1):
		uart0Write( (char *)data, length);
		break;
	case(COM2):
		uart1Write( (char *)data, length);
		break;
	}
}

/** \brief Reads data from serial port.
    \retval Lengt of received data in bytes*/  
UINT16 serRead (
  t_serial_devices device, 
  UINT8 * data /**< Pointer to data */
)
{
    UINT16 bytesReceived = 0;
    BOOLEAN receivedSomething;
    
    do
        {
        receivedSomething = serGet( device, &(data[bytesReceived]));
        if (receivedSomething)
            bytesReceived++;
        } while(receivedSomething);
    
	return bytesReceived;
}

/** \brief Get byte from serial port.
    \retval bool Returns true if there was data */
BOOLEAN serGet(
  t_serial_devices device,
  UINT8 * byte /**< Pointer to byte to return data*/
)
{
	int receivedChar = -1;
	
	switch( device )
		{
		case(COM1):
			receivedChar = uart0Getch();
			break;
		case(COM2):
			receivedChar = uart1Getch();
			break;
		}
	
	if (receivedChar >= 0)
		{
		*byte = (UINT8)receivedChar;
		return TRUE;
		}
	else
		{
		return FALSE;
		}
}

/** \brief Send byte to serial port. */
void serPut(
  t_serial_devices device, 
  UINT8 value /**< Byte to send*/
)
{
	switch( device )
		{
		case(COM1):
			uart0Putch( value );
			break;
		case(COM2):
			uart1Putch( value );
			break;
		}

}

/** \brief Flush serial port buffers. */
void   serFlush(
  t_serial_devices device
)
{
	switch( device )
		{
		case(COM1):
			uart0TxFlush( );
			break;
		case(COM2):
			uart1TxFlush( );
			break;
		}
	
}

/** \brief Check if receive buffers is empty.
    \retval bool Returns true if recieve buffer is empty */
BOOLEAN serEmpty(
  t_serial_devices device
)
{
	switch( device )
		{
		case(COM1):
			return (uart0RxEmpty( ) != 0);
			break;
		case(COM2):
			return (uart1RxEmpty( ) != 0);
			break;
		}

	return FALSE;
}


RESULT serSetModemControl( 
  t_serial_devices device,
  BOOLEAN enable             
)
{
    if (device == COM2)
        {
        if (enable == TRUE)
            {
            U1MCR |= (UMCR_RTS_EN | UMCR_CTS_EN); 
            }
        else
            {
            U1MCR &= ~(UMCR_RTS_EN | UMCR_CTS_EN); 
            }
        
        return OK;
        }
    else
        {
        return ERROR;
        }
}
