view src/cs/drivers/drv_app/uart/serialswitch_dp.c @ 303:f76436d19a7a default tip

!GPRS config: fix long-standing AT+COPS chance hanging bug There has been a long-standing bug in FreeCalypso going back years: sometimes in the AT command bring-up sequence of an ACI-only MS, the AT+COPS command would produce only a power scan followed by cessation of protocol stack activity (only L1 ADC traces), instead of the expected network search sequence. This behaviour was seen in different FC firmware versions going back to Citrine, and seemed to follow some law of chance, not reliably repeatable. This bug has been tracked down and found to be specific to !GPRS configuration, stemming from our TCS2/TCS3 hybrid and reconstruction of !GPRS support that was bitrotten in TCS3.2/LoCosto version. ACI module psa_mms.c, needed only for !GPRS, was missing in the TCS3 version and had to be pulled from TCS2 - but as it turns out, there is a new field in the MMR_REG_REQ primitive that needs to be set correctly, and that psa_mms.c module is the place where this initialization needed to be added.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 08 Jun 2023 08:23:37 +0000
parents 4e78acac3d88
children
line wrap: on
line source

/*******************************************************************************
 *
 * 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__