/*******************************************************************************
 *
 * SERIALSWITCH.C
 *
 * Board-specific switch for Perseus
 *
 * (C) Texas Instruments 2000
 *
 ******************************************************************************/

#ifndef __SERIALSWITCH_C__
#define __SERIALSWITCH_C__

#include "main/sys_types.h"
#include "memif/mem.h"
#include "nucleus.h"
#include "csmi/csmi.h"
#include "uart/serialswitch.h"
#include "uart/uart.h"
#include "uart/uartfax.h"
#include "csmi/csmi_uart.h"
#include "csmi/csmi_uartfax.h"
#include "inth/iq.h"

static int serial_config;

#define NUMBER_OF_UART 2

// Constant used to avoid calling uart interrupt handler when using CSMI
#define DISABLE_UART_INTERRUPT_HANDLER 0x0

// Internal UART constants & macros - used by interrupt handler
#define IIR (0x02) /* UART interrupt ident. register - Read only */
#define SCR (0x10) /* UART suppl. control register   - Read/Write */
#define SSR (0x11) /* UART suppl. status register    - Read only  */

#define IIR_BITS_USED  (0x07)
#define IT_NOT_PENDING (0x01)

/*
 * Supplementary Control Register
 */

#define RX_CTS_WAKE_UP_ENABLE_BIT (4)

/*
 * Supplementary Status Register
 */

#define RX_CTS_WAKE_UP_STS (0x02) /* Wake-up interrupt occurred  */

/*
 * This macro allows to read an UART register.
 */

#define READ_UART_REGISTER(UART,REG) \
            *((volatile SYS_UWORD8 *) ((UART)->base_address + (REG)))

/*
 * This macro allows to disable the UART's wake-up interrupt.
 */

#define DISABLE_WAKE_UP_INTERRUPT(UART) \
            *((volatile SYS_UWORD8 *) ((UART)->base_address + SCR)) &= \
                ~(1 << (RX_CTS_WAKE_UP_ENABLE_BIT)); 

/*
 * Wake-up time duration in seconds and in number of TDMAs.
 * 1 TDMA = (6 / 1300) s = 0.004615 s (= 4.615 ms).
 */

#define WAKE_UP_TIME_DURATION (10)  /* 7200 seconds = 120 min. = 2 hours*/
#define WAKE_UP_TIME_IN_TDMA  (WAKE_UP_TIME_DURATION * 1300 / 6)

char ser_cfg_info[NUMBER_OF_TR_UART] = {0, 0};

/*
 * Types of flows supported.
 */

typedef enum {
    TRACE_FLOW,
    FAX_DATA_FLOW
} t_flow_type;

static const unsigned long uart_base_address[NUMBER_OF_UART] =
{
    MEM_UART_IRDA,
    MEM_UART_MODEM
};

static NU_TIMER uart_wake_up_duration_timer;
static unsigned char uart_waked_up_by_interrupt;

#if ((CHIPSET == 2) || (CHIPSET == 3))
static unsigned long uart_spurious_interrupts;
#elif ((CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 7))
  static unsigned long uart_modem_spurious_interrupts;
  static unsigned long uart_irda_spurious_interrupts;
#endif

// Structures representing the arrays
typedef struct
{
  void          (*tr_Init) (T_tr_UartId device, int baudrate, void (callback_function (void)));
  unsigned long (*tr_ReadNChars) (T_tr_UartId device, char *buffer, unsigned long chars_to_read);
  unsigned long (*tr_ReadNBytes) (T_tr_UartId device, char *buffer, unsigned long chars_to_read, unsigned char *eof_detected);
  unsigned long (*tr_WriteNChars) (T_tr_UartId device, char *buffer, unsigned long chars_to_write);
  unsigned long (*tr_EncapsulateNChars) (T_tr_UartId device, char *buffer, unsigned long chars_to_write);  
  unsigned long (*tr_WriteNBytes) (T_tr_UartId device, unsigned char *buffer, unsigned long chars_to_write);  
  void          (*tr_WriteChar) (T_tr_UartId device, char character);
  void          (*tr_WriteString) (T_tr_UartId device, char *buffer);
  unsigned char (*tr_EnterSleep) (T_tr_UartId device);
  void          (*tr_WakeUp) (T_tr_UartId device);
} TR_DRV;

/*
 * Set of function pointers for fax & data functions.
 */
 
typedef struct
{
  T_FDRET (*fd_Init) (T_fd_UartId uartNo);
  T_FDRET (*fd_Enable) (T_fd_UartId uartNo, unsigned char enable);
  T_FDRET (*fd_SetComPar) (T_fd_UartId uartNo, T_baudrate baudrate, T_bitsPerCharacter bpc,
                           T_stopBits sb, T_parity parity);
  T_FDRET (*fd_SetBuffer) (T_fd_UartId uartNo, unsigned short bufSize, unsigned short rxThreshold, unsigned short txThreshold);
  T_FDRET (*fd_SetFlowCtrl) (T_fd_UartId uartNo, T_flowCtrlMode fcMode, unsigned char XON, unsigned char XOFF);
  T_FDRET (*fd_SetEscape) (T_fd_UartId uartNo, unsigned char escChar, unsigned short guardPeriod);
  T_FDRET (*fd_InpAvail) (T_fd_UartId uartNo);
  T_FDRET (*fd_OutpAvail) (T_fd_UartId uartNo);
  T_FDRET (*fd_EnterSleep) (T_fd_UartId uartNo);
  T_FDRET (*fd_WakeUp) (T_fd_UartId uartNo);
  T_FDRET (*fd_ReadData) (T_fd_UartId uartNo, T_suspendMode suspend, void (readOutFunc (unsigned char cldFromIrq,
                          T_reInstMode *reInstall, unsigned char nsource, unsigned char *source[],
                          unsigned short size[], unsigned long state)));
  T_FDRET (*fd_WriteData) (T_fd_UartId uartNo, T_suspendMode suspend, void (writeInFunc (unsigned char cldFromIrq,
                           T_reInstMode *reInstall, unsigned char ndest, unsigned char *dest[],
                           unsigned short size[])));
  T_FDRET (*fd_StopRec) (T_fd_UartId uartNo);
  T_FDRET (*fd_StartRec) (T_fd_UartId uartNo);
  T_FDRET (*fd_GetLineState) (T_fd_UartId uartNo, unsigned long *state);
  T_FDRET (*fd_SetLineState) (T_fd_UartId uartNo, unsigned long state, unsigned long mask);
  T_FDRET (*fd_CheckXEmpty) (T_fd_UartId uartNo);
} FD_DRV;

/*
 * UART structure used for UARTs.
 */
    
typedef struct 
{
    SYS_UWORD32 base_address;
    SYS_BOOL    device_used;
    SYS_BOOL    deep_sleep_set_up;
    t_flow_type flow_type;
    SYS_WORD16  flow_id;
    void (*interrupt_handler) (int uart_id, SYS_UWORD8 interrupt_status);
} T_UART;

/*
 * Internal variables and prototypes of stubs
 */  
static unsigned short fd_bufSize;
static unsigned char  fd_buffer[FD_MAX_BUFFER_SIZE];
static unsigned char  fd_driver_enabled;

static void          dummy_tr_Init (int device, int baudrate, void (callback_function (void)));
static unsigned long dummy_tr_ReadNChars (int device, char *buffer, unsigned long chars_to_read);
static unsigned long dummy_tr_ReadNBytes (T_tr_UartId device, char *buffer, unsigned long chars_to_read, unsigned char *eof_detected);
static unsigned long dummy_tr_WriteNChars (int device, char *buffer, unsigned long chars_to_write);
static unsigned long dummy_tr_EncapsulateNChars (T_tr_UartId device, char *buffer, unsigned long chars_to_write);
static unsigned long dummy_tr_WriteNBytes (T_tr_UartId device, unsigned char *buffer, unsigned long chars_to_write);
static void          dummy_tr_WriteChar (int device, char character); 
static void          dummy_tr_WriteString (int device, char *buffer); 
static unsigned char dummy_tr_EnterSleep (T_tr_UartId device);
static void          dummy_tr_WakeUp (T_tr_UartId device);

static T_FDRET       dummy_fd_Init (T_fd_UartId uartNo);
static T_FDRET       dummy_fd_Enable (T_fd_UartId uartNo, unsigned char enable);
static T_FDRET       dummy_fd_SetComPar (T_fd_UartId uartNo, T_baudrate baudrate,
                                         T_bitsPerCharacter bpc,
                                         T_stopBits sb,
                                         T_parity parity);
static T_FDRET       dummy_fd_SetBuffer (T_fd_UartId uartNo, unsigned short bufSize, unsigned short rxThreshold, unsigned short txThreshold);
static T_FDRET       dummy_fd_SetFlowCtrl (T_fd_UartId uartNo, T_flowCtrlMode fcMode, unsigned char XON, unsigned char XOFF);
static T_FDRET       dummy_fd_SetEscape (T_fd_UartId uartNo, unsigned char escChar, unsigned short guardPeriod);
static T_FDRET       dummy_fd_InpAvail (T_fd_UartId uartNo);
static T_FDRET       dummy_fd_OutpAvail (T_fd_UartId uartNo);
static T_FDRET       dummy_fd_EnterSleep (T_fd_UartId uartNo);
static T_FDRET       dummy_fd_WakeUp (T_fd_UartId uartNo);
static T_FDRET       dummy_fd_ReadData (T_fd_UartId uartNo, 
                                        T_suspendMode suspend,
                                        void (readOutFunc (unsigned char cldFromIrq,
                                        T_reInstMode *reInstall,
                                        unsigned char nsource,
                                        unsigned char *source[],
                                        unsigned short size[],
                                        unsigned long state)));
static T_FDRET       dummy_fd_WriteData (T_fd_UartId uartNo, 
                                         T_suspendMode suspend,
                                         void (writeInFunc (unsigned char cldFromIrq,
                                         T_reInstMode *reInstall,
                                         unsigned char ndest,
                                         unsigned char *dest[],
                                         unsigned short size[])));
static T_FDRET       dummy_fd_StopRec (T_fd_UartId uartNo);
static T_FDRET       dummy_fd_StartRec (T_fd_UartId uartNo);
static T_FDRET       dummy_fd_GetLineState (T_fd_UartId uartNo, unsigned long *state);
static T_FDRET       dummy_fd_SetLineState (T_fd_UartId uartNo, unsigned long state, unsigned long mask);
static T_FDRET       dummy_fd_CheckXEmpty (T_fd_UartId uartNo);

// Arrays of pointers to functions
const TR_DRV TR_Uart =
{
  UA_Init,
  UA_ReadNChars,
  UA_ReadNBytes,
  UA_WriteNChars,
  UA_EncapsulateNChars,
  UA_WriteNBytes,
  UA_WriteChar,
  UA_WriteString,
  UA_EnterSleep,
  UA_WakeUp
};

const TR_DRV TR_Dummy =
{
  dummy_tr_Init,
  dummy_tr_ReadNChars,
  dummy_tr_ReadNBytes,
  dummy_tr_WriteNChars,
  dummy_tr_EncapsulateNChars,
  dummy_tr_WriteNBytes,
  dummy_tr_WriteChar,
  dummy_tr_WriteString,
  dummy_tr_EnterSleep,
  dummy_tr_WakeUp
};

const TR_DRV TR_Csmi =
{
  CU_Init,
  CU_ReadNChars,
  CU_ReadNBytes,
  CU_WriteNChars,
  CU_EncapsulateNChars,
  CU_WriteNBytes,
  CU_WriteChar,
  CU_WriteString,
  CU_EnterSleep,
  CU_WakeUp
};

const FD_DRV FD_Uart =
{
  UAF_Init,
  UAF_Enable,
  UAF_SetComPar,
  UAF_SetBuffer,
  UAF_SetFlowCtrl,
  UAF_SetEscape,
  UAF_InpAvail,
  UAF_OutpAvail,
  UAF_EnterSleep,
  UAF_WakeUp,
  UAF_ReadData,
  UAF_WriteData,
  UAF_StopRec,
  UAF_StartRec,
  UAF_GetLineState,
  UAF_SetLineState,
  UAF_CheckXEmpty
};

const FD_DRV FD_Csmi =
{
  CF_Init,
  CF_Enable,
  CF_SetComPar,
  CF_SetBuffer,
  CF_SetFlowCtrl,
  CF_SetEscape,
  CF_InpAvail,
  CF_OutpAvail,
  dummy_fd_EnterSleep,
  dummy_fd_WakeUp,
  CF_ReadData,
  CF_WriteData,
  CF_StopRec,
  CF_StartRec,
  CF_GetLineState,
  CF_SetLineState,
  dummy_fd_CheckXEmpty
};

const FD_DRV FD_Dummy =
{
  dummy_fd_Init,
  dummy_fd_Enable,
  dummy_fd_SetComPar,
  dummy_fd_SetBuffer,
  dummy_fd_SetFlowCtrl,
  dummy_fd_SetEscape,
  dummy_fd_InpAvail,
  dummy_fd_OutpAvail,
  dummy_fd_EnterSleep,
  dummy_fd_WakeUp,
  dummy_fd_ReadData,
  dummy_fd_WriteData,
  dummy_fd_StopRec,
  dummy_fd_StartRec,
  dummy_fd_GetLineState,
  dummy_fd_SetLineState,
  dummy_fd_CheckXEmpty
};

#define MAX_TRACE_STREAMS 4
#define MAX_FD_STREAMS 2

/*
 * The board's serial configuration includes :
 *     an array of trace drivers, each with its associated UART identifier
 *     a data driver, also with its UART identifier
 *
 */
typedef struct 
{
  const TR_DRV *trDrv;
  int   trId;
} 
T_TRACE_CONFIG;

typedef struct 
{
  const FD_DRV *fdDrv;
  int   fdId;
} 
T_DATA_CONFIG;


typedef struct
{
  T_TRACE_CONFIG trCfg[MAX_TRACE_STREAMS];
  T_DATA_CONFIG  fdCfg[MAX_FD_STREAMS];
}
T_SERIAL_CONFIG;



/*
 * All possible serial configurations are described in this table
 */
const T_SERIAL_CONFIG serialConfigs[] =
{
  // serial config 0 : TEST & DEBUG configuration
  //                     - Riviera trace (1) on serial port 1 (gsm uart modem)
  //                     - fax & data Dummy
  {
    {
      { &TR_Dummy, -1 }, { &TR_Uart, 1 }, { &TR_Dummy, -1 }, { &TR_Dummy, -1 },
    },
    { 
      { &FD_Dummy, -1 }, { &FD_Dummy, -1 }
    },
  },
  
  // serial config 1 : TEST & DEBUG configuration
  //                        - trace (0) Dummy
  //                        - fax & data on serial port 1 (gsm uart modem)
  {
    {
      { &TR_Dummy, -1 }, { &TR_Dummy, -1 }, { &TR_Dummy, -1 }, { &TR_Dummy, -1 },
    },
    { 
      { &FD_Uart, 1 },   { &FD_Dummy, -1 }
    },
  },

  // serial config 2 : PRODUCTION configuration
  //                        - Riviera trace (Dummy for debug)
  //                        - fax & data on CSMI port 5 (Fax Data #0)
  {
    {
      { &TR_Dummy, -1 }, { &TR_Dummy, -1 }, { &TR_Dummy, -1 }, { &TR_Dummy, -1 },
    },
    { 
      { &FD_Csmi, 0 },   { &FD_Dummy, -1 }
    },
  },

  // serial config 3 : PRODUCTION configuration (FaxData with dual port)
  //                        - Riviera trace (Dummy for debug)
  //                        - fax & data on CSMI port 5 and 6 (Fax Data #0 and #1)
  {
    {
      { &TR_Dummy, -1 }, { &TR_Dummy, -1 }, { &TR_Dummy, -1 }, { &TR_Dummy, -1 },
    },
    { 
      { &FD_Csmi, 0 },   { &FD_Csmi, 1 }
    },
  },
  
  // serial config 4 : TEST & DEBUG configuration (for ANITE dial up networking)
  //                     - trace (0) dummy
  //                     - fax & data on serial port 1 (gsm uart modem)
  {
    {
      { &TR_Dummy, -1 }, { &TR_Dummy, -1 }, { &TR_Dummy, -1 }, { &TR_Dummy, -1 },
    },
    { 
      { &FD_Uart, 1 },   { &FD_Dummy, -1 }
    },
  },
  
  // serial config 5 : TEST & DEBUG configuration
  //                        - trace (1) dummy
  //                        - fax & data on serial port 1 (gsm uart modem)
  {
    {
      { &TR_Dummy, -1 }, { &TR_Dummy, -1 }, { &TR_Dummy, -1 }, { &TR_Dummy, -1 },
    },
    { 
      { &FD_Uart, 1 },   { &FD_Dummy, -1 }
    },
  },  

  // serial config 6 : TEST & DEBUG configuration (CSMI debug)
  //                        - Riviera trace (1) on serial port 1 (gsm uart modem)
  //                        - fax & data on CSMI
  {
    {
      { &TR_Dummy, -1 }, { &TR_Uart, 1 }, { &TR_Dummy, -1 }, { &TR_Dummy, -1 },
    },
    { 
      { &FD_Csmi, 0 },   { &FD_Csmi, 1 }
    },
  },
  // serial config 7 : TEST & DEBUG configuration (stand-alone)
  //                     - Riviera trace (1) on csmi trace port
  //                     - fax & data on CSMI
  {
    {
      { &TR_Dummy, -1 }, { &TR_Csmi, 0 }, { &TR_Dummy, -1 }, { &TR_Dummy, -1 },
    },
    { 
      { &FD_Csmi, 0 },   { &FD_Csmi, 1 }
    },
  },

  // serial config 8 : TEST & DEBUG configuration for PGT
  //                        - trace (0) on serial port 1 (gsm uart modem)
  //                        - fax & data Dummy
  {
    {
      { &TR_Uart, 1 }, { &TR_Dummy, -1 }, { &TR_Dummy, -1 }, { &TR_Dummy, -1 },
    },
    { 
      { &FD_Dummy, -1 }, { &FD_Dummy, -1 }
    },
  }
};

const T_SERIAL_CONFIG *serialConfigP;


// Physical UART data structures
static T_UART int_uart[2];
static SYS_UWORD32 uart_spurious_interrupts;

/*******************************************************************************
 *
 *                     analyze_uart_wake_up_timer_expiration
 * 
 * Purpose  : The wake-up time duration has just expired. If requested, UARTs
 *            can again be set up to enter Deep Sleep.
 *
 * Arguments: In : id: parameter not used.
 *            Out: none
 *
 * Returns  : none 
 *
 ******************************************************************************/

void
analyze_uart_wake_up_timer_expiration (UNSIGNED id)
{
    /*
     * Wake-up time duration has expired.
     * UARTs can again be set up for Deep Sleep.
     */

    (void) NU_Control_Timer (&uart_wake_up_duration_timer,
                             NU_DISABLE_TIMER);
      
    uart_waked_up_by_interrupt = 0;
}

/*******************************************************************************
 *
 *                          start_uart_wake_up_timer
 * 
 * Purpose  : Starts the wake-up duration timer once UARTs have been waked-up
 *            by an interrupt.
 *
 * Arguments: In : none
 *            Out: none
 *
 * Returns  : none 
 *
 ******************************************************************************/

void
start_uart_wake_up_timer (void)
{
    /*
     * Wake-up duration timer is started.
     * UARTs can't no more be set up for Deep Sleep until the timer expires.
     */

    (void) NU_Reset_Timer (&uart_wake_up_duration_timer,
                           &analyze_uart_wake_up_timer_expiration,
                           WAKE_UP_TIME_IN_TDMA,
                           0, /* The timer expires once. */
                           NU_DISABLE_TIMER);

    (void) NU_Control_Timer (&uart_wake_up_duration_timer,
                             NU_ENABLE_TIMER);
}




/*******************************************************************************
 *
 *                          SER_WriteConfig
 *
 * Purpose: TBD
 *
 * Parameters: In : new_config: TBD
 *                  write_to_flash: TBD
 *             Out: none
 *
 * Return: 0 (FALSE)   : In case of error while trying to write file in FFS
 *         >= 1 (TRUE) : Successful operation.
 *
 ******************************************************************************/

SYS_BOOL SER_WriteConfig (char *new_config, SYS_BOOL write_to_flash)
{
    // Dummy function to make the linker happy. (SER_WriteConfig is called by cst)
    SYS_BOOL status = 0;
    return (status);
}

/*******************************************************************************
 *
 *                          SER_ImmediateSwitch
 *
 * Purpose: TBD
 *
 * Parameters: In : none
 *             Out: none
 *
 * Return: 0 (FALSE)   : In case of error.
 *         >= 1 (TRUE) : Successful operation.
 *
 ******************************************************************************/

SYS_BOOL SER_ImmediateSwitch (void)
{
    // Dummy function to make the linker happy. (SER_ImmediateSwitch is called by cst)
    SYS_BOOL status = 0;
    return (status);
}

/*
 *  SER_InitSerialConfig
 *
 *
 */
void
SER_InitSerialConfig (int cfg)
{
  int         uart_id;
  SYS_BOOL    uart_used;

    /*
     * Basic UARTs initializations.
     */

  for (uart_id = 0; uart_id < NUMBER_OF_UART; uart_id++)
  {
    int_uart[uart_id].base_address = uart_base_address[uart_id];
    int_uart[uart_id].device_used = 0;
    int_uart[uart_id].deep_sleep_set_up = 0;
  }

    uart_spurious_interrupts = 0;
    uart_waked_up_by_interrupt = 0;

  // Install the 2 interrupt handlers for each serial config
  switch (cfg)
  {
    case 0: 
      int_uart[0].interrupt_handler = DISABLE_UART_INTERRUPT_HANDLER;
      int_uart[1].interrupt_handler = UA_InterruptHandler;
      break;

    case 1: 
      int_uart[0].device_used = 0;
      int_uart[0].interrupt_handler = DISABLE_UART_INTERRUPT_HANDLER;

      int_uart[1].device_used = 1;
      int_uart[1].flow_id     = 1;
      int_uart[1].flow_type   = FAX_DATA_FLOW;
      int_uart[1].interrupt_handler = UAF_InterruptHandler;
      break;

    case 2: 
      int_uart[0].interrupt_handler = DISABLE_UART_INTERRUPT_HANDLER;
      int_uart[1].interrupt_handler = DISABLE_UART_INTERRUPT_HANDLER;
      break;

    case 3: 
      int_uart[0].interrupt_handler = DISABLE_UART_INTERRUPT_HANDLER;
      int_uart[1].interrupt_handler = DISABLE_UART_INTERRUPT_HANDLER;
      break;
      
    case 4: 
      int_uart[0].interrupt_handler = DISABLE_UART_INTERRUPT_HANDLER;
      int_uart[1].interrupt_handler = UAF_InterruptHandler;
      break;

    case 5: 
      int_uart[0].interrupt_handler = DISABLE_UART_INTERRUPT_HANDLER;
      int_uart[1].interrupt_handler = UAF_InterruptHandler;
      break; 
      
    case 6: 
      int_uart[0].device_used = 0;
      int_uart[0].interrupt_handler = DISABLE_UART_INTERRUPT_HANDLER;

      int_uart[1].device_used = 1;
      int_uart[1].flow_id     = 1;
      int_uart[1].flow_type   = TRACE_FLOW;
      int_uart[1].interrupt_handler = UA_InterruptHandler;
      break; 

    case 7: 
      int_uart[0].interrupt_handler = DISABLE_UART_INTERRUPT_HANDLER;
      int_uart[1].interrupt_handler = DISABLE_UART_INTERRUPT_HANDLER;
      break;

    case 8: 
      int_uart[0].interrupt_handler = DISABLE_UART_INTERRUPT_HANDLER;
      int_uart[1].interrupt_handler = UA_InterruptHandler;
      break;

    default :
      cfg=0;
      int_uart[0].interrupt_handler = DISABLE_UART_INTERRUPT_HANDLER;
      int_uart[1].interrupt_handler = UA_InterruptHandler;
      break;
  }

  serialConfigP = &serialConfigs[cfg];

      /*
     * Checks if both UARTs are used.
     * If not, performs minimum initialization including Sleep Mode.
     */

    uart_used = 0;
    for (uart_id = 0; uart_id < NUMBER_OF_UART; uart_id++) {

        if (!(int_uart[uart_id].device_used))
            initialize_uart_sleep (uart_id);

        else /* if (int_uart[uart_id].device_used) */
            uart_used = 1;  /* At least one UART is used */
    }

    /*
     * If at least one uart is used, create a timer to control the wake-up
     * time duration.
     */

    if (uart_used)
        (void) NU_Create_Timer (
                   &uart_wake_up_duration_timer,
                   "Wake Up",
                   &analyze_uart_wake_up_timer_expiration,
                   0, /* Parameter supplied to the routine: not used. */
                   WAKE_UP_TIME_IN_TDMA,
                   0, /* The timer expires once. */
                   NU_DISABLE_TIMER);

}


void SER_tr_Init (int id,
                         int baudrate,
                         void (callback_function (void)))
{
  const TR_DRV *trDrv;
  int trId;

  trDrv = serialConfigP->trCfg[id].trDrv;
  trId  = serialConfigP->trCfg[id].trId;

  (trDrv->tr_Init)(trId, baudrate, callback_function);
}

unsigned long SER_tr_ReadNChars (int id,
                                char *buffer,
                                unsigned long chars_to_read)
{
  const TR_DRV *trDrv;
  int trId;

  trDrv = serialConfigP->trCfg[id].trDrv;
  trId  = serialConfigP->trCfg[id].trId;
  
  return ((trDrv->tr_ReadNChars)(trId, buffer, chars_to_read));
}

unsigned long SER_tr_ReadNBytes (int id,
                                 char *buffer,
                                 unsigned long chars_to_read,
                                 unsigned char *eof_detected)
{
  const TR_DRV *trDrv;
  int trId;

  trDrv = serialConfigP->trCfg[id].trDrv;
  trId  = serialConfigP->trCfg[id].trId;
  
  return ((trDrv->tr_ReadNBytes) (trId, buffer, chars_to_read, eof_detected));
}

unsigned long SER_tr_WriteNChars (int id,
                                 char *buffer,
                                 unsigned long chars_to_write)
{
  const TR_DRV *trDrv;
  int trId;

  trDrv = serialConfigP->trCfg[id].trDrv;
  trId  = serialConfigP->trCfg[id].trId;

  return ((trDrv->tr_WriteNChars)(trId, buffer, chars_to_write));
}

unsigned long SER_tr_EncapsulateNChars (int id,
                                        char *buffer,
                                        unsigned long chars_to_write)
{
  const TR_DRV *trDrv;
  int trId;

  trDrv = serialConfigP->trCfg[id].trDrv;
  trId  = serialConfigP->trCfg[id].trId;

  return ((trDrv->tr_EncapsulateNChars) (trId, buffer, chars_to_write));
}

unsigned long SER_tr_WriteNBytes (int id,
                                  unsigned char *buffer,
                                  unsigned long chars_to_write)
{
  const TR_DRV *trDrv;
  int trId;

  trDrv = serialConfigP->trCfg[id].trDrv;
  trId  = serialConfigP->trCfg[id].trId;

  return ((trDrv->tr_WriteNBytes) (trId, buffer, chars_to_write));
}

void SER_tr_WriteChar (int id, char character)
{
  const TR_DRV *trDrv;
  int trId;

  trDrv = serialConfigP->trCfg[id].trDrv;
  trId  = serialConfigP->trCfg[id].trId;

  (trDrv->tr_WriteChar)(trId, character);
}

void SER_tr_WriteString (int id, char *buffer)
{
  const TR_DRV *trDrv;
  int trId;

  trDrv = serialConfigP->trCfg[id].trDrv;
  trId  = serialConfigP->trCfg[id].trId;
  
  (trDrv->tr_WriteString)(trId, buffer);
}

unsigned char SER_tr_EnterSleep (int id)
{
  const TR_DRV *trDrv;
  int trId;

  trDrv = serialConfigP->trCfg[id].trDrv;
  trId  = serialConfigP->trCfg[id].trId;
  
  return ((trDrv->tr_EnterSleep) (trId));
}

void SER_tr_WakeUp (int id)
{
  const TR_DRV *trDrv;
  int trId;

  trDrv = serialConfigP->trCfg[id].trDrv;
  trId  = serialConfigP->trCfg[id].trId;

  (trDrv->tr_WakeUp) (trId);
}

/*
 * SER_fd_xx : Fax/data functions 
 *
 */
T_FDRET SER_fd_Init(void)
{
    return UF_Init (0);
}


T_FDRET
SER_fd_Enable (unsigned char enable)
{
  return UF_Enable (0, enable);
}

T_FDRET
SER_fd_SetComPar (T_baudrate baudrate,
                  T_bitsPerCharacter bpc,
                  T_stopBits sb,
                  T_parity parity)
{
    return UF_SetComPar (0, baudrate, bpc, sb, parity);
}

T_FDRET
SER_fd_SetBuffer (unsigned short bufSize, unsigned short rxThreshold, unsigned short txThreshold)
{
    return UF_SetBuffer (0, bufSize, rxThreshold, txThreshold);
}

T_FDRET
SER_fd_SetFlowCtrl (T_flowCtrlMode fcMode, unsigned char XON, unsigned char XOFF)
{
    return UF_SetFlowCtrl (0, fcMode, XON, XOFF);
}

T_FDRET
SER_fd_SetEscape (char escChar, unsigned short guardPeriod)
{
    return UF_SetEscape (0, escChar, guardPeriod);
}

T_FDRET
SER_fd_InpAvail (void)
{
    return UF_InpAvail (0);
}

T_FDRET
SER_fd_OutpAvail (void)
{
    return UF_OutpAvail (0);
}

T_FDRET
SER_fd_EnterSleep (void)
{
  return UF_EnterSleep (0);
}

T_FDRET
SER_fd_WakeUp (void)
{
  UF_WakeUp (0);
}

T_FDRET
SER_fd_ReadData (T_suspendMode suspend,
                 void (readOutFunc (unsigned char cldFromIrq,
                                    T_reInstMode *reInstall,
                                    unsigned char nsource,
                                    unsigned char *source[],
                                    unsigned short size[],
                                    unsigned long state)))
{
    return UF_ReadData (0, suspend, readOutFunc);
}

T_FDRET
SER_fd_WriteData (T_suspendMode suspend,
                  void (writeInFunc (unsigned char cldFromIrq,
                                     T_reInstMode *reInstall,
                                     unsigned char ndest,
                                     unsigned char *dest[],
                                     unsigned short size[])))
{
    return UF_WriteData (0, suspend, writeInFunc);
}

T_FDRET
SER_fd_StopRec (void)
{
    return UF_StopRec(0);
}

T_FDRET
SER_fd_StartRec (void)
{
    return UF_StartRec(0);
}

T_FDRET
SER_fd_GetLineState (unsigned long *state)
{
    return UF_GetLineState(0, state);
}

T_FDRET
SER_fd_SetLineState (unsigned long state, unsigned long mask)
{
    return UF_SetLineState(0, state, mask);
}

T_FDRET
SER_fd_CheckXEmpty (void)
{
    return UF_CheckXEmpty(0);
}

/*
 *
 * SER_int_uart_handlerx
 * 
 * Internal UART interrupt handler.
 *
 * Perseus has 2 internal UARTs, each with its own interrupt vector
 *
 */

void
SER_uart_irda_handler (void)
{
    SYS_UWORD8 interrupt_status;
    T_UART *uart;
    int    uart_id;

    uart_id = 0;
    uart = &(int_uart[0]);

    // clear UART interrupt
    interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED;

    // call interrupt handler if necessary
    if(uart->interrupt_handler != DISABLE_UART_INTERRUPT_HANDLER)
      (*(uart->interrupt_handler)) (uart_id, interrupt_status);

}

void
SER_uart_modem_handler (void)
{
    SYS_UWORD8     interrupt_status;
    T_UART     *uart;
    SYS_BOOL   it_wakeup_identified;
    int        uart_id;

    uart_id = 1;
    it_wakeup_identified = 0;
    uart = &(int_uart[1]);


     /*
      * Check first for a wake-up interrupt.
      */
     interrupt_status = READ_UART_REGISTER (uart, SSR);

     if (interrupt_status & RX_CTS_WAKE_UP_STS) { /* Wake-up IT has occurred */
 
         it_wakeup_identified = 1;
         uart_waked_up_by_interrupt = 1;
         DISABLE_WAKE_UP_INTERRUPT (uart);
     }

     /*
      * If no wake-up interrupt has been detected, check UART for other
      * interrupt causes.
      */

     if (!it_wakeup_identified) {

    // clear UART interrupt
         interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED;

         if (!(interrupt_status & IT_NOT_PENDING))
             (*(uart->interrupt_handler)) (uart_id, interrupt_status);
         else
             uart_modem_spurious_interrupts++;
	}

}


T_FDRET UF_Init (int uartNo)
{
  const FD_DRV *fdDrv;
  int fdId;

  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;
  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  
  return ((fdDrv->fd_Init)(fdId));
}


T_FDRET UF_Enable (int uartNo, SYS_BOOL enable)
{
  const FD_DRV *fdDrv;
  int fdId;

  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;

  return((fdDrv->fd_Enable)(fdId, enable));
}

short
UF_SetComPar (int uartNo,
              T_baudrate baudrate,
              T_bitsPerCharacter bpc,
              T_stopBits sb,
              T_parity parity)
{
  const FD_DRV *fdDrv;
  int fdId;

  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;
  
  return((fdDrv->fd_SetComPar)(fdId, baudrate, bpc, sb, parity));
}

short
UF_SetBuffer (int uartNo,
              unsigned short bufSize,
              unsigned short rxThreshold,
              unsigned short txThreshold)
{
  const FD_DRV *fdDrv;
  int fdId;

  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;

  return((fdDrv->fd_SetBuffer)(fdId, bufSize, rxThreshold, txThreshold));
}

short
UF_SetFlowCtrl (int uartNo,
                T_flowCtrlMode fcMode,
                unsigned char XON,
                unsigned char XOFF)
{
  const FD_DRV *fdDrv;
  int fdId;

  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;

  return((fdDrv->fd_SetFlowCtrl)(fdId, fcMode, XON, XOFF));
}

short
UF_SetEscape (int uartNo, char escChar, unsigned short guardPeriod)
{
  const FD_DRV *fdDrv;
  int fdId;

  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;

  return ((fdDrv->fd_SetEscape) (fdId, escChar, guardPeriod));
}

T_FDRET UF_InpAvail (int uartNo)
{
  const FD_DRV *fdDrv;
  int fdId;

  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;

  return ((fdDrv->fd_InpAvail) (fdId));
}

T_FDRET UF_OutpAvail (int uartNo)
{
  const FD_DRV *fdDrv;
  int fdId;

  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;

  return ((fdDrv->fd_OutpAvail) (fdId));
}

short UF_EnterSleep (int uartNo)
{
  const FD_DRV *fdDrv;
  int fdId;

  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;

  return ((fdDrv->fd_EnterSleep) (fdId));
}

short UF_WakeUp (int uartNo)
{
  const FD_DRV *fdDrv;
  int fdId;

  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;

  return ((fdDrv->fd_WakeUp) (fdId));
}

short
UF_ReadData (int uartNo,
             T_suspendMode suspend,
             void (readOutFunc (unsigned char cldFromIrq,
                                T_reInstMode *reInstall,
                                unsigned char nsource,
                                unsigned char *source[],
                                unsigned short size[],
                                unsigned long state)))
{
  const FD_DRV *fdDrv;
  int fdId;

  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;

  return ((fdDrv->fd_ReadData) (fdId, suspend, readOutFunc));
}

short
UF_WriteData (int uartNo,
              T_suspendMode suspend,
              void (writeInFunc (unsigned char cldFromIrq,
                                 T_reInstMode *reInstall,
                                 unsigned char ndest,
                                 unsigned char *dest[],
                                 unsigned short size[])))
{
  const FD_DRV *fdDrv;
  int fdId;

  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;

  return ((fdDrv->fd_WriteData) (fdId, suspend, writeInFunc));
}

short
UF_StopRec (int uartNo)
{
  const FD_DRV *fdDrv;
  int fdId;
  
  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;

  return ((fdDrv->fd_StopRec) (fdId));
}

short
UF_StartRec (int uartNo)
{
  const FD_DRV *fdDrv;
  int fdId;
  
  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;

  return ((fdDrv->fd_StartRec) (fdId));
}

short
UF_GetLineState (int uartNo, unsigned long *state)
{
  const FD_DRV *fdDrv;
  int fdId;

  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;

  return ((fdDrv->fd_GetLineState) (fdId, state));
}

short
UF_SetLineState (int uartNo, unsigned long state, unsigned long mask)
{
  const FD_DRV *fdDrv;
  int fdId;
  
  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;

  return ((fdDrv->fd_SetLineState) (fdId, state, mask));
}

short
UF_CheckXEmpty (int uartNo)
{
  const FD_DRV *fdDrv;
  int fdId;

  fdId  = serialConfigP->fdCfg[uartNo].fdId;
  fdDrv = serialConfigP->fdCfg[uartNo].fdDrv;

  return ((fdDrv->fd_CheckXEmpty) (fdId));
}


/*******************************************************************************
 *
 *                              dummy_tr_Init
 *
 * Purpose: No action.
 *
 * Parameters: See SER_tr_Init.
 *
 * Return: none
 *
 ******************************************************************************/
 
static void
dummy_tr_Init (int device, int baudrate, void (callback_function (void)))
{
    /*
     * No action.
     */
}

/*******************************************************************************
 *
 *                          dummy_tr_ReadNChars
 *
 * Purpose: No action.
 *
 * Parameters: See SER_tr_ReadNChars.
 *
 * Return: 0
 *
 ******************************************************************************/
 
static unsigned long
dummy_tr_ReadNChars (int device, char *buffer, unsigned long chars_to_read)
{
    return (0);
}

/*******************************************************************************
 *
 *                          dummy_tr_ReadNBytes
 *
 * Purpose: No action.
 *
 * Parameters: See SER_tr_ReadNBytes.
 *
 * Return: 0
 *
 ******************************************************************************/
 
static unsigned long
dummy_tr_ReadNBytes (T_tr_UartId device,
                     char *buffer,
                     unsigned long chars_to_read,
                     unsigned char *eof_detected)
{
    return (0);
}

/*******************************************************************************
 *
 *                          dummy_tr_WriteNChars
 *
 * Purpose: No action.
 *
 * Parameters: See SER_tr_WriteNChars.
 *
 * Return: The number of character to write.
 *
 ******************************************************************************/
 
static unsigned long
dummy_tr_WriteNChars (int device, char *buffer, unsigned long chars_to_write)
{
    return (chars_to_write);
}

/*******************************************************************************
 *
 *                          dummy_tr_EncapsulateNChars
 *
 * Purpose: No action.
 *
 * Parameters: See SER_tr_EncapsulateNChars.
 *
 * Return: The number of character to write.
 *
 ******************************************************************************/
 
static unsigned long
dummy_tr_EncapsulateNChars (T_tr_UartId device,
                      char *buffer,
                      unsigned long chars_to_write)
{
    return (chars_to_write);
}

/*******************************************************************************
 *
 *                          dummy_tr_WriteNBytes
 *
 * Purpose: No action.
 *
 * Parameters: See SER_tr_WriteNBytes.
 *
 * Return: The number of byte to write.
 *
 ******************************************************************************/
 
static unsigned long
dummy_tr_WriteNBytes (T_tr_UartId device,
                      unsigned char *buffer,
                      unsigned long chars_to_write)
{
    return (chars_to_write);
}

/*******************************************************************************
 *
 *                              dummy_tr_WriteChar
 *
 * Purpose: No action.
 *
 * Parameters: See SER_tr_WriteChar.
 *
 * Return: none
 *
 ******************************************************************************/
 
static void
dummy_tr_WriteChar (int device, char character)
{
    /*
     * No action.
     */
}

/*******************************************************************************
 *
 *                          dummy_tr_WriteString
 *
 * Purpose: No action.
 *
 * Parameters: See SER_tr_WriteString.
 *
 * Return: none
 *
 ******************************************************************************/
 
static void
dummy_tr_WriteString (int device, char *buffer)
{
    /*
     * No action.
     */
}

/*******************************************************************************
 *
 *                          dummy_tr_EnterSleep
 *
 * Purpose: No action.
 *
 * Parameters: See SER_tr_EnterSleep.
 *
 * Return: 1
 *
 ******************************************************************************/
 
static unsigned char
dummy_tr_EnterSleep (T_tr_UartId device)
{
    return (1);
}

/*******************************************************************************
 *
 *                           dummy_tr_WakeUp
 *
 * Purpose: No action.
 *
 * Parameters: See SER_tr_WakeUp.
 *
 * Return: none
 *
 ******************************************************************************/
 
static void
dummy_tr_WakeUp (T_tr_UartId device)
{
    /*
     * No action.
     */
}

/*******************************************************************************
 *
 *                              dummy_fd_Init
 *
 * Purpose: Sets the size of the circular buffer to the maximum value and the
 *          state of the driver to 'disabled'.
 *
 * Parameters: See SER_fd_Init.
 *
 * Return: FD_OK: Successful operation.
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_Init (T_fd_UartId uartNo)
{
    fd_bufSize = FD_MAX_BUFFER_SIZE;
    fd_driver_enabled = 0;
    
    return (FD_OK);
}

/*******************************************************************************
 *
 *                              dummy_fd_Enable
 *
 * Purpose: Stores the state of the driver.
 *
 * Parameters: See SER_fd_Enable.
 *
 * Return: FD_OK: Successful operation.
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_Enable (T_fd_UartId uartNo, unsigned char enable)
{
    fd_driver_enabled = enable;
    
    return (FD_OK);
}

/*******************************************************************************
 *
 *                              dummy_fd_SetComPar
 *
 * Purpose: No action.
 *
 * Parameters: See SER_fd_SetComPar.
 *
 * Return: FD_OK: Successful operation.
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_SetComPar (T_fd_UartId uartNo, 
                    T_baudrate baudrate,
                    T_bitsPerCharacter bpc,
                    T_stopBits sb,
                    T_parity parity)
{
    return (FD_OK);
}

/*******************************************************************************
 *
 *                              dummy_fd_SetBuffer
 *
 * Purpose: Stores the size of the circular buffer.
 *
 * Parameters: See SER_fd_SetBuffer.
 *
 * Return: FD_OK: Successful operation.
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_SetBuffer (T_fd_UartId uartNo, unsigned short bufSize, unsigned short rxThreshold, unsigned short txThreshold)
{
    fd_bufSize = bufSize;
    
    return (FD_OK);
}

/*******************************************************************************
 *
 *                              dummy_fd_SetFlowCtrl
 *
 * Purpose: No action.
 *
 * Parameters: See SER_fd_SetFlowCtrl.
 *
 * Return: FD_OK: Successful operation.
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_SetFlowCtrl (T_fd_UartId uartNo, T_flowCtrlMode fcMode, unsigned char XON, unsigned char XOFF)
{
    return (FD_OK);
}

/*******************************************************************************
 *
 *                              dummy_fd_SetEscape
 *
 * Purpose: No action.
 *
 * Parameters: See SER_fd_SetEscape.
 *
 * Return: FD_OK: Successful operation.
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_SetEscape (T_fd_UartId uartNo, unsigned char escChar, unsigned short guardPeriod)
{
    return (FD_OK);
}

/*******************************************************************************
 *
 *                              dummy_fd_InpAvail
 *
 * Purpose: No action.
 *
 * Parameters: See SER_fd_InpAvail.
 *
 * Return: The size of the circular buffer.
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_InpAvail (T_fd_UartId uartNo)
{
    return (fd_bufSize);
}

/*******************************************************************************
 *
 *                              dummy_fd_OutpAvail
 *
 * Purpose: No action.
 *
 * Parameters: See SER_fd_OutpAvail.
 *
 * Return: The size of the circular buffer.
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_OutpAvail (T_fd_UartId uartNo)
{
    return (fd_bufSize);
}

/*******************************************************************************
 *
 *                          dummy_fd_EnterSleep
 *
 * Purpose: No action.
 *
 * Parameters: See SER_tr_EnterSleep.
 *
 * Return: 1
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_EnterSleep (T_fd_UartId uartNo)
{
    return (1);
}

/*******************************************************************************
 *
 *                           dummy_fd_WakeUp
 *
 * Purpose: No action.
 *
 * Parameters: See SER_tr_WakeUp.
 *
 * Return: FD_OK: Successful operation.
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_WakeUp (T_fd_UartId uartNo)
{
    return (FD_OK);
}

/*******************************************************************************
 *
 *                              dummy_fd_ReadData
 *
 * Purpose: No action.
 *
 * Parameters: See SER_fd_ReadData.
 *
 * Return: 0 if the suspend parameter is set to 'sm_noSuspend'.
 *         FD_SUSPENDED if the suspend parameter is set to 'sm_suspend'.
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_ReadData (T_fd_UartId uartNo, 
                   T_suspendMode suspend,
                   void (readOutFunc (unsigned char cldFromIrq,
                                      T_reInstMode *reInstall,
                                      unsigned char nsource,
                                      unsigned char *source[],
                                      unsigned short size[],
                                      unsigned long state)))
{
    T_FDRET result;
    
    if (suspend == sm_noSuspend)
        result = 0;
    else
        result = FD_SUSPENDED;
        
    return (result);
}

/*******************************************************************************
 *
 *                              dummy_fd_WriteData
 *
 * Purpose: The user's function is called with:
 *            - cldFromIrq = 0
 *            - ndest = 1
 *            - dest[0] is a unsigned char pointer on the beginning address of a local
 *              buffer
 *            - size[0] is set to fd_bufSize.
 *
 * Parameters: See SER_fd_WriteData.
 *
 * Return: The number of bytes written in the local buffer.
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_WriteData (T_fd_UartId uartNo,
                    T_suspendMode suspend,
                    void (writeInFunc (unsigned char cldFromIrq,
                                       T_reInstMode *reInstall,
                                       unsigned char ndest,
                                       unsigned char *dest[],
                                       unsigned short size[])))
{
    T_reInstMode dummyInstall;
    unsigned char        *destination[2];
    unsigned short       buffer_size[2];
    
    destination[0] = &(fd_buffer[0]);
    buffer_size[0] = fd_bufSize;
    
    (*writeInFunc) (0, &dummyInstall, 1, &(destination[0]), &(buffer_size[0]));
    
    return ((T_FDRET) (fd_bufSize - buffer_size[0]));
}

/*******************************************************************************
 *
 *                              dummy_fd_StopRec
 *
 * Purpose: No action.
 *
 * Parameters: See SER_fd_StopRec.
 *
 * Return: FD_OK: Successful operation.
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_StopRec (T_fd_UartId uartNo)
{
    return (FD_OK);
}

/*******************************************************************************
 *
 *                              dummy_fd_StartRec
 *
 * Purpose: No action.
 *
 * Parameters: See SER_fd_StartRec.
 *
 * Return: FD_OK: Successful operation.
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_StartRec (T_fd_UartId uartNo)
{
    return (FD_OK);
}

/*******************************************************************************
 *
 *                              dummy_fd_GetLineState
 *
 * Purpose: Sets the RXBLEV field to the bufSize value.
 *
 * Parameters: See SER_fd_GetLineState.
 *
 * Return: FD_OK: Successful operation.
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_GetLineState (T_fd_UartId uartNo, unsigned long *state)
{
    *state = fd_bufSize << RXBLEV;
    
    return (FD_OK);
}

/*******************************************************************************
 *
 *                              dummy_fd_SetLineState
 *
 * Purpose: No action.
 *
 * Parameters: See SER_fd_SetLineState.
 *
 * Return: FD_OK: Successful operation.
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_SetLineState (T_fd_UartId uartNo, unsigned long state, unsigned long mask)
{
    return (FD_OK);
}

/*******************************************************************************
 *
 *                              dummy_fd_CheckXEmpty
 *
 * Purpose: No action.
 *
 * Parameters: See SER_fd_CheckXEmpty.
 *
 * Return: FD_OK: Successful operation.
 *
 ******************************************************************************/
 
static T_FDRET
dummy_fd_CheckXEmpty (T_fd_UartId uartNo)
{
    return (FD_OK);
}

/*******************************************************************************
 *
 *                          SER_UartSleepStatus
 *
 * Purpose: This function checks if both UARTs are ready to enter Deep Sleep. 
 *
 * Parameters: In : none
 *             Out: none 
 *
 * Return: 0	 : Deep Sleep is not possible.
 *         >= 1  : Deep Sleep is possible.
 *
 ******************************************************************************/

unsigned char
SER_UartSleepStatus (void)
{
    T_UART   *uart;
    int      uart_id;
    SYS_BOOL status;

    /*
     * Check first if wake-up time duration is active.
     * A return is used to simplify the code.
     */

    /* Wake-up duration timer has not yet expired. */

       if (uart_waked_up_by_interrupt)    return (0); 

    /*
     * Check if both UARTs are ready to enter Deep Sleep.
     */

    status = 1;
    uart_id = 0;
    while ((uart_id < NUMBER_OF_UART) &&
           (status)) {

           uart = &(int_uart[uart_id]);

           /*
            * Check if the specified UART is actually used.
            */
           
           if (uart->device_used) {

               /*
                * Check if the specified UART is used by a Trace or
                * by a Fax & Data flow.
                */
               if (uart->flow_type == TRACE_FLOW)
                   status = SER_tr_EnterSleep (uart->flow_id);

               else
                   if (uart->flow_type == FAX_DATA_FLOW)
                   status = (SYS_BOOL) SER_fd_EnterSleep ();
                   else 
                       status = 0;

               if (status) {

                   /*
                    * The specified UART is now set up for Deep Sleep.
                    */

                   uart->deep_sleep_set_up = 1;

}
           }

           uart_id++;
    }

    /*
     * Check if Deep Sleep is finally possible.
     * If not revert eventual Deep Sleep settings.
     */
    if (!status) {

        for (uart_id = 0; uart_id < NUMBER_OF_UART; uart_id++) {

            uart = &(int_uart[uart_id]);

            /*
             * If the specified used UART has already been set up for
             * Deep Sleep, revert these settings.
             */

            if ((uart->device_used) &&
                (uart->deep_sleep_set_up)) {
				
                /*
                 * Check if the specified UART is used by a Trace or
                 * by a Fax & Data flow.
                 */

                if (uart->flow_type == TRACE_FLOW)
                    SER_tr_WakeUp (uart->flow_id);
				
                else /* if (uart->flow_type == FAX_DATA_FLOW) */
                SER_fd_WakeUp ();

                uart->deep_sleep_set_up = 0;

            }
        }
    }

    return (status);
}


/*******************************************************************************
 *
 *                            SER_WakeUpUarts
 *
 * Purpose: This function wakes up used UARTs after Deep Sleep.
 *
 * Parameters: In : none
 *             Out: none 
 *
 * Return: none
 *
 ******************************************************************************/

void
SER_WakeUpUarts (void)
{
    T_UART   *uart;
    int      uart_id;

    if (uart_waked_up_by_interrupt)
        start_uart_wake_up_timer ();

    for (uart_id = 0; uart_id < NUMBER_OF_UART; uart_id++) {

        uart = &(int_uart[uart_id]);

        /*
         * Check if the specified UART is actually used, and has not yet
         * been waked up.
         */

        if ((uart->device_used) &&
            (uart->deep_sleep_set_up)) {

            /*
             * Check if the specified UART is used by a Trace or
             * by a Fax & Data flow.
             * Bluetooth HCI can not yet handled Deep Sleep Mode.
             */

            if (uart->flow_type == TRACE_FLOW)
                SER_tr_WakeUp (uart->flow_id);

            else 
            SER_fd_WakeUp ();

            /*
             * The specified UART is no more set up for Deep Sleep.
             */

            uart->deep_sleep_set_up = 0;
		}
	}

}

#endif // end __SERIALSWITCH_C__

