changeset 853:ae254ffeaec3

AT command interface works! The cause of the breakage was the same Nucleus API issue with NU_Create_Timer() which we encountered at the very beginning of this project with Riviera timers: the code in uartfax.c from TCS211 was passing 0 as the initial dummy value for the timer duration, and our FreeNucleus version doesn't like it. The fix is the same: pass 1 as the initial dummy value instead.
author Space Falcon <falcon@ivan.Harhan.ORG>
date Thu, 30 Apr 2015 01:46:26 +0000
parents fc713944bd1c
children acc9e473e93f
files gsm-fw/gpf/conf/gsmcomp.c gsm-fw/serial/debug-chases/serialswitch.c gsm-fw/serial/debug-chases/uartfax.c gsm-fw/serial/uartfax.c
diffstat 4 files changed, 8600 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/gsm-fw/gpf/conf/gsmcomp.c	Sun Apr 26 03:06:32 2015 +0000
+++ b/gsm-fw/gpf/conf/gsmcomp.c	Thu Apr 30 01:46:26 2015 +0000
@@ -428,22 +428,26 @@
 
 /*
  * Partitions pool configuration for test interface communication
+ *
+ * FreeCalypso: I bumped the configuration up from what TI had in their
+ * (likely unmaintained) gsmcomp.c as I expect we'll be doing a lot of
+ * debugging. - Space Falcon
  */
-#define TESTPOOL_0_PARTITIONS      1 /*   10 */
-#define TESTPOOL_1_PARTITIONS     15 /*   50 */
-#define TESTPOOL_2_PARTITIONS      0 /*    2 */
+#define TESTPOOL_0_PARTITIONS     10	/* was 1 */
+#define TESTPOOL_1_PARTITIONS     50	/* was 15 */
+#define TESTPOOL_2_PARTITIONS      2	/* was 0 */
 
 #define TSTSND_QUEUE_ENTRIES         (TESTPOOL_0_PARTITIONS+TESTPOOL_1_PARTITIONS+TESTPOOL_2_PARTITIONS)
 #define TSTRCV_QUEUE_ENTRIES         50
 
-#define TEST_PARTITION_0_SIZE     16 /*   80 */
+#define TEST_PARTITION_0_SIZE     80	/* was 16 */
 #ifdef _TARGET_
   #define TEST_PARTITION_1_SIZE  160
 #else
   #define TEST_PARTITION_1_SIZE  260
 #endif /* else, #ifdef _TARGET_ */
 
-#define TEST_PARTITION_2_SIZE      0 /* 1600 */
+#define TEST_PARTITION_2_SIZE      1600
 
 const USHORT TST_SndQueueEntries    = TSTSND_QUEUE_ENTRIES;
 const USHORT TST_RcvQueueEntries    = TSTRCV_QUEUE_ENTRIES;
@@ -453,10 +457,13 @@
 
 char pool21 [ POOL_SIZE(TESTPOOL_1_PARTITIONS,ALIGN_SIZE(TEST_PARTITION_1_SIZE)) ] __attribute__ ((section ("ext.ram")));
 
+char pool22 [ POOL_SIZE(TESTPOOL_2_PARTITIONS,ALIGN_SIZE(TEST_PARTITION_2_SIZE)) ] __attribute__ ((section ("ext.ram")));
+
 const T_FRM_PARTITION_POOL_CONFIG test_grp_config[] =
 {
   { TESTPOOL_0_PARTITIONS, ALIGN_SIZE(TEST_PARTITION_0_SIZE), &pool20 },
   { TESTPOOL_1_PARTITIONS, ALIGN_SIZE(TEST_PARTITION_1_SIZE), &pool21 },
+  { TESTPOOL_2_PARTITIONS, ALIGN_SIZE(TEST_PARTITION_2_SIZE), &pool22 },
   { 0                    , 0                    , NULL	  }
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/serial/debug-chases/serialswitch.c	Thu Apr 30 01:46:26 2015 +0000
@@ -0,0 +1,3416 @@
+/*******************************************************************************
+ *
+ * SERIALSWITCH.C
+ *
+ * This module allows managing the use of the serial ports of TI GSM Evaluation
+ * Boards.
+ * An application may have to send several serial data flows. The board on which
+ * the application is running may have one or several devices. The purpose of
+ * this module is to establish connections between the serial data flows and the
+ * serial devices at runtime, when the application is started.
+ *
+ * (C) Texas Instruments 1999 - 2003
+ *
+ ******************************************************************************/
+
+#define __SERIALSWITCH_C__
+
+#define __STANDARD_H__ /* Avoid to define UBYTE, SYS_UWORD16 and UINT32. */
+
+#include "../include/config.h"
+#include "../include/sys_types.h"
+#include "../riviera/rv/rv_general.h"
+#include "../riviera/rvf/rvf_api.h"
+#include "../nucleus/nucleus.h"
+
+#include "serialswitch.h" 
+
+#include "uart.h"
+#include "uartfax.h"
+
+#include "../bsp/mem.h" 
+
+#include <string.h> /* needed for memcmp & memset */
+
+#if SERIAL_DYNAMIC_SWITCH
+  #include "ffs/ffs.h" 
+  #include "rvf/rvf_api.h"
+  #include "inth/iq.h"
+  #include "rvt/rvt_def_i.h" /* needed for Riviera/Layer1 Trace's callback function */
+#endif
+
+#if defined(BTEMOBILE)
+  #include "hci_ser.h"
+#endif
+
+#define DUMMY_DEVICE (0)
+
+#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  */
+
+/*
+ * Interrupt identification register.
+ * Bit 0 is set to 0 if an IT is pending.
+ * Bits 1 and 2 are used to identify the IT.
+ */
+
+#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)  /* 10 seconds */
+#define WAKE_UP_TIME_IN_TDMA  (WAKE_UP_TIME_DURATION * 1300 / 6)
+
+
+/*
+ * Global uartswitch variable as read from FFS.
+ * It is supposed that NUMBER_OF_TR_UART, NUMBER_OF_FD_UART
+ * and NUMBER_OF_BT_UART have the same values.
+ */
+
+#define DUMMY             ('0')
+#define G23_PANEL         ('G')
+#define RIVIERA_TRACE_MUX ('R')
+#define FD_AT_COMMAND     ('D')
+#define BLUETOOTH_HCI     ('B')
+
+#if (CHIPSET == 12)
+  char ser_cfg_info[NUMBER_OF_TR_UART] = {DUMMY, DUMMY, DUMMY};
+#else
+  char ser_cfg_info[NUMBER_OF_TR_UART] = {DUMMY, DUMMY};
+#endif
+static SYS_UWORD16 serial_cfg = 0x0048; /* All dummies */
+
+#if SERIAL_DYNAMIC_SWITCH
+  /*
+   * Global variables used for Dynamic Switch.
+   */
+
+  static char ser_new_cfg[NUMBER_OF_TR_UART]  = {DUMMY, DUMMY};
+  const static char uart_config_file[] = "/sys/uartswitch";
+  static SYS_BOOL dynamic_switch = 0;
+
+  /* Import Serial Info structure. */
+  extern T_AppliSerialInfo appli_ser_cfg_info;
+#endif
+
+/*
+ * Types of flows supported.
+ */
+
+typedef enum {
+    TRACE_FLOW,
+    FAX_DATA_FLOW,
+    BLUETOOTH_HCI_FLOW
+} t_flow_type;
+
+/*
+ * For each serial data flow, a set of function pointers allows calling the
+ * functions associated to a serial device.
+ */
+
+typedef struct s_tr_functions {
+
+    T_tr_UartId   device;
+    
+    void (*tr_Init) (T_tr_UartId device,
+                     T_tr_Baudrate baudrate,
+                     void (callback_function (void)));
+                         
+    SYS_UWORD32 (*tr_ReadNChars) (T_tr_UartId device,
+                                  char *buffer,
+                                  SYS_UWORD32 chars_to_read);
+
+    SYS_UWORD32 (*tr_ReadNBytes) (T_tr_UartId device,
+                                  char *buffer,
+                                  SYS_UWORD32 chars_to_read,
+                                  SYS_BOOL *eof_detected);
+
+    SYS_UWORD32 (*tr_WriteNChars) (T_tr_UartId device,
+                                   char *buffer,
+                                   SYS_UWORD32 chars_to_write);
+
+    SYS_UWORD32 (*tr_EncapsulateNChars) (T_tr_UartId device,
+                                         char *buffer,
+                                         SYS_UWORD32 chars_to_write);
+
+    SYS_UWORD32 (*tr_WriteNBytes) (T_tr_UartId device,
+                                   SYS_UWORD8 *buffer,
+                                   SYS_UWORD32 chars_to_write);
+
+    void  (*tr_WriteChar) (T_tr_UartId device,
+                           char character);
+
+    void  (*tr_WriteString) (T_tr_UartId device,
+                             char *buffer);
+
+    SYS_BOOL (*tr_EnterSleep) (T_tr_UartId device);
+
+    void (*tr_WakeUp) (T_tr_UartId device);
+
+} t_tr_functions;
+
+/*
+ * Set of function pointers for fax & data functions.
+ */
+ 
+typedef struct s_fd_functions {
+
+    T_fd_UartId   device;
+    
+    T_FDRET (*fd_Initialize) (T_fd_UartId device);
+
+    T_FDRET (*fd_Enable) (T_fd_UartId device,
+                          SYS_BOOL enable);
+
+    T_FDRET (*fd_SetComPar) (T_fd_UartId device,
+                             T_baudrate baudrate,
+                             T_bitsPerCharacter bpc,
+                             T_stopBits sb,
+                             T_parity parity);
+
+    T_FDRET (*fd_SetBuffer) (T_fd_UartId device,
+                             SYS_UWORD16 bufSize,
+                             SYS_UWORD16 rxThreshold,
+                             SYS_UWORD16 txThreshold);
+
+    T_FDRET (*fd_SetFlowCtrl) (T_fd_UartId device,
+                               T_flowCtrlMode fcMode,
+                               SYS_UWORD8 XON,
+                               SYS_UWORD8 XOFF);
+
+    T_FDRET (*fd_SetEscape) (T_fd_UartId device,
+                             SYS_UWORD8 escChar,
+                             SYS_UWORD16 guardPeriod);
+
+    T_FDRET (*fd_InpAvail) (T_fd_UartId device);
+
+    T_FDRET (*fd_OutpAvail) (T_fd_UartId device);
+
+    T_FDRET (*fd_EnterSleep) (T_fd_UartId device);
+
+    T_FDRET (*fd_WakeUp) (T_fd_UartId device);
+
+    T_FDRET (*fd_ReadData) (T_fd_UartId device,
+                            T_suspendMode suspend,
+                            void (readOutFunc (SYS_BOOL cldFromIrq,
+                                               T_reInstMode *reInstall,
+                                               SYS_UWORD8 nsource,
+                                               SYS_UWORD8 *source[],
+                                               SYS_UWORD16 size[],
+                                               SYS_UWORD32 state)));
+
+    T_FDRET (*fd_WriteData) (T_fd_UartId device,
+                             T_suspendMode suspend,
+                             void (writeInFunc (SYS_BOOL cldFromIrq,
+                                                T_reInstMode *reInstall,
+                                                SYS_UWORD8 ndest,
+                                                SYS_UWORD8 *dest[],
+                                                SYS_UWORD16 size[])));
+
+    T_FDRET (*fd_StopRec) (T_fd_UartId device);
+
+    T_FDRET (*fd_StartRec) (T_fd_UartId device);
+
+    T_FDRET (*fd_GetLineState) (T_fd_UartId device,
+                                SYS_UWORD32 *state);
+
+    T_FDRET (*fd_SetLineState) (T_fd_UartId device,
+                                SYS_UWORD32 state,
+                                SYS_UWORD32 mask);
+
+    T_FDRET (*fd_CheckXEmpty) (T_fd_UartId device);
+
+} t_fd_functions;
+
+#ifdef BTEMOBILE
+  /*
+   * Set of function pointers for Bluetooth HCI functions.
+   */
+   
+  typedef struct s_bt_functions {
+
+      T_bt_UartId   device;
+
+      T_HCI_RET (*bt_Init) (T_bt_UartId uart_device);
+
+      T_HCI_RET (*bt_Start) (void);
+
+      T_HCI_RET (*bt_Stop) (void);
+
+      T_HCI_RET (*bt_Kill) (void);
+
+      T_HCI_RET (*bt_SetBaudrate) (UINT8 baudrate);
+
+      T_HCI_RET (*bt_TransmitPacket) (void *uart_tx_buffer);
+
+      SYS_BOOL  (*bt_EnterSleep) (void);
+
+      void      (*bt_WakeUp) (void);
+
+  } t_bt_functions;
+#endif
+
+/*
+ * Prototypes of dummy functions.
+ * Dummy functions for Trace.
+ */
+
+static void dummy_tr_Init (T_tr_UartId device,
+                           T_tr_Baudrate baudrate,
+                           void (callback_function (void)));
+ 
+static SYS_UWORD32 dummy_tr_ReadNChars (T_tr_UartId device,
+                                        char *buffer,
+                                        SYS_UWORD32 chars_to_read);
+
+static SYS_UWORD32 dummy_tr_ReadNBytes (T_tr_UartId device,
+                                        char *buffer,
+                                        SYS_UWORD32 chars_to_read,
+                                        SYS_BOOL *eof_detected);
+ 
+static SYS_UWORD32 dummy_tr_WriteNChars (T_tr_UartId device,
+                                         char *buffer,
+                                         SYS_UWORD32 chars_to_write);
+ 
+static SYS_UWORD32 dummy_tr_EncapsulateNChars (T_tr_UartId device,
+                                               char *buffer,
+                                               SYS_UWORD32 chars_to_write);
+ 
+static SYS_UWORD32 dummy_tr_WriteNBytes (T_tr_UartId device,
+                                         SYS_UWORD8 *buffer,
+                                         SYS_UWORD32 chars_to_write);
+ 
+static void dummy_tr_WriteChar (T_tr_UartId device,
+                                char character);
+ 
+static void dummy_tr_WriteString (T_tr_UartId device,
+                                  char *buffer);
+ 
+static SYS_BOOL dummy_tr_EnterSleep (T_tr_UartId device);
+ 
+static void dummy_tr_WakeUp (T_tr_UartId device);
+ 
+/*
+ * Dummy functions for Fax & Data.
+ */
+
+static T_FDRET dummy_fd_Init (T_fd_UartId device);
+ 
+static T_FDRET dummy_fd_Enable (T_fd_UartId device,
+                                SYS_BOOL enable);
+ 
+static T_FDRET dummy_fd_SetComPar (T_fd_UartId device,
+                                   T_baudrate baudrate,
+                                   T_bitsPerCharacter bpc,
+                                   T_stopBits sb,
+                                   T_parity parity);
+ 
+static T_FDRET dummy_fd_SetBuffer (T_fd_UartId device,
+                                   SYS_UWORD16 bufSize,
+                                   SYS_UWORD16 rxThreshold,
+                                   SYS_UWORD16 txThreshold);
+ 
+static T_FDRET dummy_fd_SetFlowCtrl (T_fd_UartId device,
+                                     T_flowCtrlMode fcMode,
+                                     SYS_UWORD8 XON,
+                                     SYS_UWORD8 XOFF);
+ 
+static T_FDRET dummy_fd_SetEscape (T_fd_UartId device,
+                                   SYS_UWORD8 escChar,
+                                   SYS_UWORD16 guardPeriod);
+ 
+static T_FDRET dummy_fd_InpAvail (T_fd_UartId device);
+ 
+static T_FDRET dummy_fd_OutpAvail (T_fd_UartId device);
+ 
+static T_FDRET dummy_fd_EnterSleep (T_fd_UartId device);
+ 
+static T_FDRET dummy_fd_WakeUp (T_fd_UartId device);
+ 
+static T_FDRET dummy_fd_ReadData (T_fd_UartId device,
+                                  T_suspendMode suspend,
+                                  void (readOutFunc (SYS_BOOL cldFromIrq,
+                                                     T_reInstMode *reInstall,
+                                                     SYS_UWORD8 nsource,
+                                                     SYS_UWORD8 *source[],
+                                                     SYS_UWORD16 size[],
+                                                     SYS_UWORD32 state)));
+ 
+static T_FDRET dummy_fd_WriteData (T_fd_UartId device,
+                                   T_suspendMode suspend,
+                                   void (writeInFunc (SYS_BOOL cldFromIrq,
+                                                      T_reInstMode *reInstall,
+                                                      SYS_UWORD8 ndest,
+                                                      SYS_UWORD8 *dest[],
+                                                      SYS_UWORD16 size[])));
+ 
+static T_FDRET dummy_fd_StopRec (T_fd_UartId device);
+ 
+static T_FDRET dummy_fd_StartRec (T_fd_UartId device);
+ 
+static T_FDRET dummy_fd_GetLineState (T_fd_UartId device,
+                                      SYS_UWORD32 *state);
+ 
+static T_FDRET dummy_fd_SetLineState (T_fd_UartId device,
+                                      SYS_UWORD32 state,
+                                      SYS_UWORD32 mask);
+ 
+static T_FDRET dummy_fd_CheckXEmpty (T_fd_UartId device);
+ 
+#ifdef BTEMOBILE
+  /*
+   * Dummy functions for Bluetooth HCI.
+   */
+
+  static T_HCI_RET dummy_bt_Init (T_bt_UartId uart_device);
+   
+  static T_HCI_RET dummy_bt_Start (void);
+   
+  static T_HCI_RET dummy_bt_Stop (void);
+   
+  static T_HCI_RET dummy_bt_Kill (void);
+   
+  static T_HCI_RET dummy_bt_SetBaudrate (UINT8 baudrate);
+   
+  static T_HCI_RET dummy_bt_TransmitPacket (void *uart_tx_buffer);
+
+  static SYS_BOOL  dummy_bt_EnterSleep (void);
+  
+  static void      dummy_bt_WakeUp (void);
+
+#endif
+
+/*
+ * Constants tables representing the various possible configurations
+ * for Trace, Fax & Data and Bluetooth HCI according to the different devices.
+ * Constant table for Trace using no device.
+ */
+
+static const t_tr_functions dummy_trace = {
+
+    DUMMY_DEVICE,
+    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
+};
+
+/*
+ * Constant table for Trace using UART IrDA.
+ */
+
+static const t_tr_functions uart_irda_trace = {
+
+    UA_UART_0,
+    UA_Init,
+    UA_ReadNChars,
+    UA_ReadNBytes,
+    UA_WriteNChars,
+    UA_EncapsulateNChars,
+    UA_WriteNBytes,
+    UA_WriteChar,
+    UA_WriteString,
+    UA_EnterSleep,
+    UA_WakeUp
+};
+
+/*
+ * Constant table for Trace using UART Modem.
+ */
+
+static const t_tr_functions uart_modem_trace = {
+
+    UA_UART_1,
+    UA_Init,
+    UA_ReadNChars,
+    UA_ReadNBytes,
+    UA_WriteNChars,
+    UA_EncapsulateNChars,
+    UA_WriteNBytes,
+    UA_WriteChar,
+    UA_WriteString,
+    UA_EnterSleep,
+    UA_WakeUp
+};
+
+#if (CHIPSET == 12)
+  /*
+   * Constant table for Trace using UART Modem2.
+   */
+
+  static const t_tr_functions uart_modem2_trace = {
+
+      UA_UART_2,
+      UA_Init,
+      UA_ReadNChars,
+      UA_ReadNBytes,
+      UA_WriteNChars,
+      UA_EncapsulateNChars,
+      UA_WriteNBytes,
+      UA_WriteChar,
+      UA_WriteString,
+      UA_EnterSleep,
+      UA_WakeUp
+  };
+#endif
+
+/*
+ * Constant table for Fax & Data using no device.
+ */
+
+static const t_fd_functions dummy_fax_data = {
+
+    DUMMY_DEVICE,
+    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
+};
+
+/*
+ * Constant table for Fax & Data using UART Modem.
+ */
+
+#if CONFIG_FDMODEM
+static const t_fd_functions uart_modem_fax_data = {
+
+    UAF_UART_1,
+    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
+};
+#endif
+
+#ifdef BTEMOBILE
+  /*
+   * Constant table for BT HCI using no device.
+   */
+
+  static const t_bt_functions dummy_bt_hci = {
+
+      DUMMY_DEVICE,
+      dummy_bt_Init,
+      dummy_bt_Start,
+      dummy_bt_Stop,
+      dummy_bt_Kill,
+      dummy_bt_SetBaudrate,
+      dummy_bt_TransmitPacket,
+      dummy_bt_EnterSleep,
+      dummy_bt_WakeUp
+  };
+
+  /*
+   * Constant table for BT HCI using UART IrDA.
+   */
+
+  static const t_bt_functions uart_irda_bt_hci = {
+
+      UABT_UART_0,
+      hciu_init,
+      hciu_start,
+      hciu_stop,
+      hciu_kill,
+      hciu_set_baudrate,
+      hciu_transmit_packet,
+      hciu_enter_sleep,
+      hciu_wakeup
+  };
+
+  /*
+   * Constant table for BT HCI using UART Modem.
+   */
+
+  static const t_bt_functions uart_modem_bt_hci = {
+
+      UABT_UART_1,
+      hciu_init,
+      hciu_start,
+      hciu_stop,
+      hciu_kill,
+      hciu_set_baudrate,
+      hciu_transmit_packet,
+      hciu_enter_sleep,
+      hciu_wakeup
+  };
+
+  #if (CHIPSET == 12)
+    /*
+     * Constant table for BT HCI using UART Modem2.
+     */
+
+    static const t_bt_functions uart_modem2_bt_hci = {
+
+        UABT_UART_2,
+        hciu_init,
+        hciu_start,
+        hciu_stop,
+        hciu_kill,
+        hciu_set_baudrate,
+        hciu_transmit_packet,
+        hciu_go_to_sleep,
+        hciu_wakeup
+    };
+  #endif
+#endif
+
+#if SERIAL_DYNAMIC_SWITCH
+  /*
+   * Structure used to store initialization parameters related to the AT-Cmd/F&D flow.
+   * Numbers of paramaters (in case of multiple calls) have been figured out from
+   * Condat AT-Command/F&D flow initialization.
+   */
+   
+  typedef struct s_data_flow {
+    
+      /*
+       * Parameters related to SER_fd_SetComPar (2 calls)
+       */
+      T_baudrate         baudrate[2];
+      T_bitsPerCharacter bpc[2];
+      T_stopBits         sb[2];
+      T_parity           parity[2];
+
+      /*
+       * Parameters related to SER_fd_SetBuffer
+       */
+      SYS_WORD16         bufSize;
+      SYS_WORD16         rxThreshold;
+      SYS_WORD16         txThreshold;
+
+      /*
+       * Parameters related to SER_fd_SetFlowCtrl (2 calls)
+       */
+      T_flowCtrlMode     fcMode[2];
+      SYS_UWORD8         XON[2];
+      SYS_UWORD8         XOFF[2];
+
+      /*
+       * Parameters related to SER_fd_SetEscape (2 calls)
+       */
+      SYS_UWORD8         escChar[2];
+      SYS_UWORD16        guardPeriod[2];
+
+      /*
+       * Parameters related to SER_fd_SetLineState (4 calls)
+       */
+      SYS_UWORD32        state[4];
+      SYS_UWORD32        mask[4];
+
+      /*
+       * Parameters related to SER_fd_ReadData
+       */
+      T_suspendMode      suspend_rd;
+      void               (*readOutFunc) (SYS_BOOL cldFromIrq,
+                                         T_reInstMode *reInstall,
+                                         SYS_UWORD8 nsource,
+                                         SYS_UWORD8 *source[],
+                                         SYS_UWORD16 size[],
+                                         SYS_UWORD32 state);
+      /*
+       * Parameters related to SER_fd_WriteData
+       */
+      T_suspendMode      suspend_wr;
+      void               (*writeInFunc) (SYS_BOOL cldFromIrq,
+                                         T_reInstMode *reInstall,
+                                         SYS_UWORD8 ndest,
+                                         SYS_UWORD8 *dest[],
+                                         SYS_UWORD16 size[]);
+
+  } t_data_flow;
+#endif /* (defined BTEMOBILE && (CHIPSET != 12)) */
+
+/*
+ * UART structure used for UARTs.
+ */
+ 
+typedef struct s_uart {
+    
+    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;
+
+static const t_tr_functions *tr_functions[SER_MAX_NUMBER_OF_FLOWS];
+static const t_fd_functions *fd_functions;
+
+#ifdef BTEMOBILE
+  static const t_bt_functions *bt_functions;
+#endif
+
+#if SERIAL_DYNAMIC_SWITCH
+  static SYS_BOOL uart_fd_initialized = 0;
+#endif
+
+static SYS_UWORD8  fd_buffer[FD_MAX_BUFFER_SIZE];
+static SYS_BOOL    fd_driver_enabled;
+
+#if SERIAL_DYNAMIC_SWITCH
+  static t_data_flow data_flow_parameters;
+#else
+  static SYS_WORD16 bufSize;
+#endif
+
+#if SERIAL_DYNAMIC_SWITCH
+  /*
+   * Variables used to count calls to SER_fd_XXX functions.
+   */
+
+  static SYS_UWORD8 fd_UAF_SetBuffer = 0;
+  static SYS_UWORD8 fd_UAF_SetEscape = 0;
+  static SYS_UWORD8 fd_UAF_SetComPar = 0;
+  static SYS_UWORD8 fd_UAF_SetFlowCtrl = 0;
+  static SYS_UWORD8 fd_UAF_ReadData = 0;
+  static SYS_UWORD8 fd_UAF_SetLineState = 0;
+  static SYS_UWORD8 fd_UAF_WriteData = 0;
+#endif
+
+/*
+ * Timer used for duration control when UARTs are waked up by an interrupt or
+ * each time any new incoming characters are received; This timer prevents the
+ * system to enter deep sleep mode.
+ */
+
+static NU_TIMER uart_sleep_timer;
+       SYS_BOOL uart_sleep_timer_enabled;
+
+/*
+ * HISR used to reset and restart the sleep timer from an UART use by a Trace
+ * flow in case of incoming characters.
+ */
+
+#define TIMER_HISR_PRIORITY      (2)
+#define TIMER_HISR_STACK_SIZE  (512) /* Bytes. */ 
+
+static NU_HISR timer_hisr_ctrl_block;
+static char    timer_hisr_stack[TIMER_HISR_STACK_SIZE];
+
+/*
+ * For next arrays, it is supposed that NUMBER_OF_TR_UART, NUMBER_OF_FD_UART
+ * and NUMBER_OF_BT_UART have the same values.
+ * An index on an internal uart for trace, fax & data or bluetooth hci reffers
+ * to the same uart device.
+ */
+ 
+static t_uart int_uart[NUMBER_OF_TR_UART];
+
+#if ((CHIPSET == 2) || (CHIPSET == 3))
+  static SYS_UWORD32 uart_spurious_interrupts;
+#elif ((CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12))
+  static SYS_UWORD32 uart_modem_spurious_interrupts;
+  static SYS_UWORD32 uart_irda_spurious_interrupts;
+#endif
+#if (CHIPSET == 12)
+  static SYS_UWORD32 uart_modem2_spurious_interrupts;
+#endif
+
+static const SYS_UWORD32 uart_base_address[NUMBER_OF_TR_UART] =
+{
+    MEM_UART_IRDA,
+    MEM_UART_MODEM
+    #if (CHIPSET == 12)
+      , MEM_UART_MODEM2
+    #endif
+};
+
+ 
+/*******************************************************************************
+ *
+ *                              dummy_tr_Init
+ *
+ * Purpose: No action.
+ *
+ * Parameters: See SER_tr_Init.
+ *
+ * Return: none
+ *
+ ******************************************************************************/
+ 
+static void
+dummy_tr_Init (T_tr_UartId device,
+               T_tr_Baudrate baudrate,
+               void (callback_function (void)))
+{
+    /*
+     * No action.
+     */
+}
+
+/*******************************************************************************
+ *
+ *                          dummy_tr_ReadNChars
+ *
+ * Purpose: No action.
+ *
+ * Parameters: See SER_tr_ReadNChars.
+ *
+ * Return: 0
+ *
+ ******************************************************************************/
+ 
+static SYS_UWORD32
+dummy_tr_ReadNChars (T_tr_UartId device,
+                     char *buffer,
+                     SYS_UWORD32 chars_to_read)
+{
+    return (0);
+}
+
+/*******************************************************************************
+ *
+ *                          dummy_tr_ReadNBytes
+ *
+ * Purpose: No action.
+ *
+ * Parameters: See SER_tr_ReadNBytes.
+ *
+ * Return: 0
+ *
+ ******************************************************************************/
+ 
+static SYS_UWORD32
+dummy_tr_ReadNBytes (T_tr_UartId device,
+                     char *buffer,
+                     SYS_UWORD32 chars_to_read,
+                     SYS_BOOL *eof_detected)
+{
+    return (0);
+}
+
+/*******************************************************************************
+ *
+ *                          dummy_tr_WriteNChars
+ *
+ * Purpose: No action.
+ *
+ * Parameters: See SER_tr_WriteNChars.
+ *
+ * Return: The number of character to write.
+ *
+ ******************************************************************************/
+ 
+static SYS_UWORD32
+dummy_tr_WriteNChars (T_tr_UartId device,
+                      char *buffer,
+                      SYS_UWORD32 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 SYS_UWORD32
+dummy_tr_EncapsulateNChars (T_tr_UartId device,
+                      char *buffer,
+                      SYS_UWORD32 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 SYS_UWORD32
+dummy_tr_WriteNBytes (T_tr_UartId device,
+                      SYS_UWORD8 *buffer,
+                      SYS_UWORD32 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 (T_tr_UartId device,
+                    char character)
+{
+    /*
+     * No action.
+     */
+}
+
+/*******************************************************************************
+ *
+ *                          dummy_tr_WriteString
+ *
+ * Purpose: No action.
+ *
+ * Parameters: See SER_tr_WriteString.
+ *
+ * Return: none
+ *
+ ******************************************************************************/
+ 
+static void
+dummy_tr_WriteString (T_tr_UartId device,
+                      char *buffer)
+{
+    /*
+     * No action.
+     */
+}
+
+/*******************************************************************************
+ *
+ *                          dummy_tr_EnterSleep
+ *
+ * Purpose: No action.
+ *
+ * Parameters: See SER_tr_EnterSleep.
+ *
+ * Return: 1
+ *
+ ******************************************************************************/
+ 
+static SYS_BOOL
+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 device)
+{
+    #if SERIAL_DYNAMIC_SWITCH
+      data_flow_parameters.bufSize = FD_MAX_BUFFER_SIZE;
+    #else
+      bufSize = FD_MAX_BUFFER_SIZE;
+    #endif
+    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 device,
+                 SYS_BOOL 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 device,
+                    T_baudrate baudrate,
+                    T_bitsPerCharacter bpc,
+                    T_stopBits sb,
+                    T_parity parity)
+{
+    return (FD_OK);
+}
+
+/*******************************************************************************
+ *
+ *                              dummy_fd_SetBuffer
+ *
+ * Purpose: No action.
+ *
+ * Parameters: See SER_fd_SetBuffer.
+ *
+ * Return: FD_OK: Successful operation.
+ *
+ ******************************************************************************/
+ 
+static T_FDRET
+dummy_fd_SetBuffer (T_fd_UartId device,
+                    SYS_UWORD16 bufSize,
+                    SYS_UWORD16 rxThreshold,
+                    SYS_UWORD16 txThreshold)
+{
+    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 device,
+                      T_flowCtrlMode fcMode,
+                      SYS_UWORD8 XON,
+                      SYS_UWORD8 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 device,
+                    SYS_UWORD8 escChar,
+                    SYS_UWORD16 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 device)
+{
+    #if SERIAL_DYNAMIC_SWITCH
+      return (data_flow_parameters.bufSize);
+    #else
+      return (bufSize);
+    #endif
+}
+
+/*******************************************************************************
+ *
+ *                              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 device)
+{
+    #if SERIAL_DYNAMIC_SWITCH
+      return (data_flow_parameters.bufSize);
+    #else
+      return (bufSize);
+    #endif
+}
+
+/*******************************************************************************
+ *
+ *                          dummy_fd_EnterSleep
+ *
+ * Purpose: No action.
+ *
+ * Parameters: See SER_tr_EnterSleep.
+ *
+ * Return: 1
+ *
+ ******************************************************************************/
+ 
+static T_FDRET
+dummy_fd_EnterSleep (T_fd_UartId device)
+{
+    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 device)
+{
+    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 device,
+                   T_suspendMode suspend,
+                   void (readOutFunc (SYS_BOOL cldFromIrq,
+                                      T_reInstMode *reInstall,
+                                      SYS_UWORD8 nsource,
+                                      SYS_UWORD8 *source[],
+                                      SYS_UWORD16 size[],
+                                      SYS_UWORD32 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 SYS_UWORD8 pointer on the beginning address of a local
+ *              buffer
+ *            - size[0] is set to data_flow_parameters.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 device,
+                    T_suspendMode suspend,
+                    void (writeInFunc (SYS_BOOL cldFromIrq,
+                                       T_reInstMode *reInstall,
+                                       SYS_UWORD8 ndest,
+                                       SYS_UWORD8 *dest[],
+                                       SYS_UWORD16 size[])))
+{
+    T_reInstMode dummyInstall;
+    SYS_UWORD8   *destination[2];
+    SYS_UWORD16  buffer_size[2];
+
+    destination[0] = &(fd_buffer[0]);
+    #if SERIAL_DYNAMIC_SWITCH
+      buffer_size[0] = data_flow_parameters.bufSize;
+    #else
+      buffer_size[0] = bufSize;
+    #endif
+
+    (*writeInFunc) (0, &dummyInstall, 1, &(destination[0]), &(buffer_size[0]));
+
+    #if SERIAL_DYNAMIC_SWITCH
+      return ((T_FDRET) (data_flow_parameters.bufSize - buffer_size[0]));
+    #else
+      return ((T_FDRET) (bufSize - buffer_size[0]));
+    #endif
+}
+
+/*******************************************************************************
+ *
+ *                              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 device)
+{
+    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 device)
+{
+    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 device,
+                       SYS_UWORD32 *state)
+{
+    #if SERIAL_DYNAMIC_SWITCH
+      *state = data_flow_parameters.bufSize << RXBLEV;
+    #else
+      *state = bufSize << RXBLEV;
+    #endif
+    
+    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 device,
+                       SYS_UWORD32 state,
+                       SYS_UWORD32 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 device)
+{
+    return (FD_OK);
+}
+
+#ifdef BTEMOBILE
+/*******************************************************************************
+ *
+ *                              dummy_bt_Init
+ *
+ * Purpose: No action.
+ *
+ * Parameters: See SER_bt_Init.
+ *
+ * Return: HCI_OK: Successful operation.
+ *
+ ******************************************************************************/
+ 
+static T_HCI_RET
+dummy_bt_Init (T_bt_UartId uart_device)
+{
+    return (HCI_OK);
+}
+
+/*******************************************************************************
+ *
+ *                              dummy_bt_Start
+ *
+ * Purpose: No action.
+ *
+ * Parameters: See SER_bt_Start.
+ *
+ * Return: HCI_OK: Successful operation.
+ *
+ ******************************************************************************/
+ 
+static T_HCI_RET
+dummy_bt_Start (void)
+{
+    return (HCI_OK);
+}
+
+/*******************************************************************************
+ *
+ *                              dummy_bt_Stop
+ *
+ * Purpose: No action.
+ *
+ * Parameters: See SER_bt_Stop.
+ *
+ * Return: HCI_OK: Successful operation.
+ *
+ ******************************************************************************/
+ 
+static T_HCI_RET
+dummy_bt_Stop (void)
+{
+    return (HCI_OK);
+}
+
+/*******************************************************************************
+ *
+ *                              dummy_bt_Kill
+ *
+ * Purpose: No action.
+ *
+ * Parameters: See SER_bt_Kill.
+ *
+ * Return: HCI_OK: Successful operation.
+ *
+ ******************************************************************************/
+ 
+static T_HCI_RET
+dummy_bt_Kill (void)
+{
+    return (HCI_OK);
+}
+
+/*******************************************************************************
+ *
+ *                           dummy_bt_SetBaudrate
+ *
+ * Purpose: No action.
+ *
+ * Parameters: See SER_bt_SetBaudrate.
+ *
+ * Return: HCI_OK: Successful operation.
+ *
+ ******************************************************************************/
+ 
+static T_HCI_RET
+dummy_bt_SetBaudrate (UINT8 baudrate)
+{
+    return (HCI_OK);
+}
+
+/*******************************************************************************
+ *
+ *                         dummy_bt_TransmitPacket
+ *
+ * Purpose: No action.
+ *
+ * Parameters: See SER_bt_TransmitPacket.
+ *
+ * Return: HCI_OK: Successful operation.
+ *
+ ******************************************************************************/
+ 
+static T_HCI_RET dummy_bt_TransmitPacket (void *uart_tx_buffer)
+
+{
+    return (HCI_OK);
+}
+
+/*******************************************************************************
+ *
+ *                              dummy_bt_EnterSleep
+ *
+ * Purpose: No action.
+ *
+ * Parameters: See SER_bt_EnterSleep.
+ *
+ * Return: TRUE.
+ *
+ ******************************************************************************/ 
+
+static SYS_BOOL
+dummy_bt_EnterSleep (void)
+{
+    return (TRUE);
+}
+
+/*******************************************************************************
+ *
+ *                              dummy_bt_WakeUp
+ *
+ * Purpose: No action.
+ *
+ * Parameters: See SER_bt_WakeUp
+ *
+ * Return: HCI_OK: none
+ *
+ ******************************************************************************/ 
+
+static void
+dummy_bt_WakeUp (void)
+{
+    /*
+     * No action.
+     */
+}
+
+#endif /* BTEMOBILE */
+
+/*******************************************************************************
+ *
+ *                     analyze_uart_sleep_timer_expiration
+ * 
+ * Purpose  : The timer 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 
+ *
+ ******************************************************************************/
+
+static VOID
+analyze_uart_sleep_timer_expiration (UNSIGNED id)
+{
+    /*
+     * Timer has expired.
+     * UARTs can again be set up for Deep Sleep.
+     */
+
+    (void) NU_Control_Timer (&uart_sleep_timer,
+                             NU_DISABLE_TIMER);
+      
+    uart_sleep_timer_enabled = 0;
+}
+
+/*******************************************************************************
+ *
+ *                          start_uart_sleep_timer
+ * 
+ * Purpose  : Starts the sleep timer once UARTs have been waked-up by an
+ *            interrupt or if new incoming characters have been received.
+ *
+ * Arguments: In : none
+ *            Out: none
+ *
+ * Returns  : none 
+ *
+ ******************************************************************************/
+
+static void
+start_uart_sleep_timer (void)
+{
+    /*
+     * UART sleep timer is started.
+     * UARTs can't no more be set up for Deep Sleep until the timer expires.
+     */
+
+    (void) NU_Reset_Timer (&uart_sleep_timer,
+                           &analyze_uart_sleep_timer_expiration,
+                           WAKE_UP_TIME_IN_TDMA,
+                           0, /* The timer expires once. */
+                           NU_DISABLE_TIMER);
+
+    (void) NU_Control_Timer (&uart_sleep_timer,
+                             NU_ENABLE_TIMER);
+}
+
+/*******************************************************************************
+ *
+ *                              set_flow_functions
+ *
+ * Purpose: Initializes a serial data flow functions set with the set of
+ *          functions of the selected device.
+ *
+ * Parameters: In : flow         : index of the serial data flow
+ *                  serial_driver: allows knowing which set of functions must
+ *                                 be selected
+ *             Out: none
+ *
+ * Return: none
+ *
+ ******************************************************************************/
+
+static void
+set_flow_functions (int flow,
+                    T_SerialDriver serial_driver)
+{
+
+    switch (serial_driver) {
+
+    case UART_MODEM_FAX_DATA:
+
+#if CONFIG_FDMODEM
+        fd_functions = &uart_modem_fax_data;
+        int_uart[fd_functions->device].device_used = 1;
+        int_uart[fd_functions->device].flow_type   = FAX_DATA_FLOW;
+        int_uart[fd_functions->device].flow_id     = flow;
+        int_uart[fd_functions->device].interrupt_handler =
+                                           UAF_InterruptHandler;
+        break;
+#endif
+
+    case DUMMY_FAX_DATA:
+        
+        fd_functions = &dummy_fax_data;                               
+        break;
+
+
+    case UART_IRDA_TRACE:
+    case UART_MODEM_TRACE:
+    #if (CHIPSET == 12)
+      case UART_MODEM2_TRACE:
+    #endif
+
+        if (serial_driver == UART_IRDA_TRACE)
+            tr_functions[flow] = &uart_irda_trace;
+        else {
+          #if (CHIPSET == 12)
+            if (serial_driver == UART_MODEM2_TRACE)
+                tr_functions[flow] = &uart_modem2_trace;
+            else
+          #endif
+                tr_functions[flow] = &uart_modem_trace;
+        }
+
+        int_uart[tr_functions[flow]->device].device_used = 1;
+        int_uart[tr_functions[flow]->device].flow_type   = TRACE_FLOW;
+        int_uart[tr_functions[flow]->device].flow_id     = flow;
+        int_uart[tr_functions[flow]->device].interrupt_handler =
+                                      UA_InterruptHandler;
+        break;
+
+    case DUMMY_TRACE:
+
+        tr_functions[flow] = &dummy_trace;
+        break;
+
+    case DUMMY_BT_HCI:
+
+        /*
+         * if serial_driver = DUMMY_BT_HCI & if BTEMOBILE is not defined
+         * no action is performed.
+         */
+
+#ifdef BTEMOBILE
+        bt_functions = &dummy_bt_hci;                               
+        break;
+
+    case UART_IRDA_BT_HCI:
+    case UART_MODEM_BT_HCI:
+    #if (CHIPSET == 12)
+      case UART_MODEM2_BT_HCI:
+    #endif
+
+        if (serial_driver == UART_IRDA_BT_HCI)
+            bt_functions = &uart_irda_bt_hci;
+        else {
+          #if (CHIPSET == 12)
+            if (serial_driver == UART_MODEM2_BT_HCI)
+                bt_functions = &uart_modem2_bt_hci;
+            else
+          #endif
+                bt_functions = &uart_modem_bt_hci;
+        }
+
+        int_uart[bt_functions->device].device_used = 1;
+        int_uart[bt_functions->device].flow_type   = BLUETOOTH_HCI_FLOW;
+        int_uart[bt_functions->device].flow_id     = flow;
+        int_uart[bt_functions->device].interrupt_handler =
+                                             hciu_interrupt_handler;
+#endif /* BTEMOBILE */
+          break;
+    }
+}
+
+/*******************************************************************************
+ *
+ *                          SER_InitSerialConfig
+ *
+ * Purpose: The parameter serial_info allows knowing all serial information
+ *          necessary to set up the serial configuration of an application.
+ *          From this information, the function is able to determine if the
+ *          current serial configuration read out from the flash memory is
+ *          valid. If it does not correspond to an allowed configuration, the
+ *          default configuration is selected. This function must be called at
+ *          the application's initialization, but never after.
+ *
+ * Parameters: In : serial_info: application serial information like the default
+ *                               configuration and all allowed configurations.
+ *             Out: none
+ *
+ * Return: none
+ *
+ ******************************************************************************/
+
+void
+SER_InitSerialConfig (const T_AppliSerialInfo *serial_info)
+{
+    int         uart_id;
+    int         flow;
+    SYS_UWORD16 serial_driver;
+    SYS_UWORD16 *allowed_config;
+    SYS_UWORD8  nb_allowed_config;
+    SYS_BOOL    valid_config_selected;
+    SYS_BOOL    uart_used;
+    SYS_BOOL    uart_used_for_trace;
+    SYS_UWORD16 current_config;
+    SYS_UWORD16 *pt_current_config = &(current_config);
+
+    /*
+	 * Basic UARTs initializations.
+	 */
+
+    for (uart_id = 0; uart_id < NUMBER_OF_TR_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;
+    }
+						  
+#if ((CHIPSET == 2) || (CHIPSET == 3))
+    uart_spurious_interrupts = 0;
+#elif ((CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12))
+    uart_modem_spurious_interrupts = 0;
+    uart_irda_spurious_interrupts = 0;
+#endif
+#if (CHIPSET == 12)
+    uart_modem2_spurious_interrupts = 0;
+#endif
+    uart_sleep_timer_enabled = 0;
+
+    /*
+     * Compute the current serial configuration.
+     */
+
+    for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++) {
+
+        switch (ser_cfg_info[uart_id]) { 
+
+            case G23_PANEL:
+                serial_cfg = serial_cfg +
+                    ((uart_id + 1) << (12 - (4 * SER_PROTOCOL_STACK)));
+                break;
+
+            case RIVIERA_TRACE_MUX:
+                serial_cfg = serial_cfg +
+                    ((uart_id + 1) << (12 - (4 * SER_LAYER_1)));
+                break;
+
+            case FD_AT_COMMAND:
+                serial_cfg = serial_cfg +
+                    ((uart_id + 1) << (12 - (4 * SER_FAX_DATA)));
+                break;
+
+            case BLUETOOTH_HCI:
+                serial_cfg = serial_cfg +
+                    ((uart_id + 1) << (12 - (4 * SER_BLUETOOTH_HCI)));
+                break;
+
+            case DUMMY:
+                break;
+        }
+    }
+
+    current_config = serial_cfg;
+    valid_config_selected = 0;
+    nb_allowed_config = serial_info->num_config;
+
+    /*
+     * Checks if the current serial config is one of the allowed.
+     */
+     
+    while ((nb_allowed_config > 0) && !valid_config_selected) {
+        
+        nb_allowed_config--;
+        allowed_config = (SYS_UWORD16 *)
+                          &(serial_info->allowed_config[nb_allowed_config]);
+        
+        if (*pt_current_config == *allowed_config)
+            valid_config_selected = 1;
+    }
+
+    /*
+     * If not, the default configuration is selected.
+     */
+
+    if (!valid_config_selected) {
+
+        pt_current_config = (SYS_UWORD16 *)&(serial_info->default_config);
+
+        #if SERIAL_DYNAMIC_SWITCH
+          /*
+           * Setup the global variable accordingly.
+           * The following default value are identical to the ones defined at
+           * the application initialization in init.c.
+           */
+
+          #ifdef BT_UART_USED_MODEM
+            memcpy (ser_cfg_info, "RB", NUMBER_OF_TR_UART);
+          #else
+            memcpy (ser_cfg_info, "BR", NUMBER_OF_TR_UART);
+          #endif
+        #endif
+    }
+
+    /*
+     * The serial data flow functions set is initialized.
+     */
+
+    flow = 0;
+    while (flow < SER_MAX_NUMBER_OF_FLOWS) {
+
+        serial_driver = (T_SerialDriver)
+                            (((*pt_current_config) >> (12 - flow * 4)) & 0x000F);
+
+        set_flow_functions (flow, serial_driver);
+        flow++;
+    }
+    
+    /*
+     * Checks if both UARTs are used.
+     * If not, performs minimum initialization including Sleep Mode.
+     * Checks also if at least one UART is used by a Trace flow.
+     * If so, create a HISR in order to reset and restart the sleep timer
+     * in case of incoming characters.
+     */
+
+    uart_used = 0;
+    uart_used_for_trace = 0;
+    for (uart_id = 0; uart_id < NUMBER_OF_TR_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 (int_uart[uart_id].flow_type == TRACE_FLOW) {
+
+                /* At least one UART used by a Trace flow */
+                uart_used_for_trace = 1;
+            }
+        }
+    }
+
+    /*
+     * If at least one uart is used, create a timer to figure out if the system
+     * can enter deep sleep mode regarding the UARTs.
+     */
+
+    if (uart_used) {
+
+        (void) NU_Create_Timer (
+                   &uart_sleep_timer,
+                   "Sleep",
+                   &analyze_uart_sleep_timer_expiration,
+                   0, /* Parameter supplied to the routine: not used. */
+                   WAKE_UP_TIME_IN_TDMA,
+                   0, /* The timer expires once. */
+                   NU_DISABLE_TIMER);
+
+        /*
+         * If at least one uart is used by a Trace flow, create a HISR to reset
+         * and restart the sleep timer.
+         */
+
+        if (uart_used_for_trace) {
+
+            /*
+             * The stack is entirely filled with the pattern 0xFE.
+             */
+
+            memset (&(timer_hisr_stack[0]), 0xFE, TIMER_HISR_STACK_SIZE);
+
+            /*
+             * The HISR entry function is the same function than the one called
+             * by the Rx HISR of the UARTFAX, since the only aim is to reset
+             * and restart the sleep timer in case of incoming characters on
+             * the Trace UART.
+             */
+
+            (void) NU_Create_HISR (
+                       &timer_hisr_ctrl_block,
+                       "Tim_HISR",
+                       SER_restart_uart_sleep_timer,
+                       TIMER_HISR_PRIORITY,
+                       &(timer_hisr_stack[0]),
+                       TIMER_HISR_STACK_SIZE);
+        }
+    }
+}
+
+
+/*******************************************************************************
+ *
+ *                          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)
+{
+#if SERIAL_DYNAMIC_SWITCH
+    int      uart_id;
+    SYS_BOOL status = 1;
+
+    for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++)
+        ser_new_cfg[uart_id] = *new_config++;
+
+    /*
+     * Write in flash the new serial configuration if requested.
+     */
+
+    if (write_to_flash) {
+        if (ffs_fwrite (uart_config_file,
+                        ser_new_cfg,
+                        NUMBER_OF_TR_UART) < EFFS_OK) {
+            status = 0;
+        }
+    }
+
+    return (status);
+#else
+    /*
+     * Real Dynamic Switch is only available with Bluetooth AND all chips but
+     * Calypso+.
+     */
+
+    return (1);
+#endif
+}
+
+/*******************************************************************************
+ *
+ *                          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)
+{
+#if SERIAL_DYNAMIC_SWITCH
+    int                uart_id;
+    SYS_BOOL           valid_config = 0;
+    T_AppliSerialInfo *serial_info = &appli_ser_cfg_info;
+    SYS_UWORD8         nb_allowed_config = serial_info->num_config;
+    SYS_UWORD16       *allowed_config;
+    int                flow;
+    T_SerialDriver     serial_flows[SER_MAX_NUMBER_OF_FLOWS];
+    T_tr_UartId        uart_nb;
+
+    /*
+     * First check if the new serial configuration is actually different from
+     * the previous one. A return is used to simplify the code.
+     */
+
+    if (!memcmp (ser_new_cfg,
+                 ser_cfg_info,
+                 NUMBER_OF_TR_UART))
+        return (1); /* new config and old config are identical => nothing to do */
+
+    /*
+     * Then check if the new serial config is valid or not.
+     * At that point, we assume that a serial config is valid if and only if the
+     * Bluetooth HCI flow is still enabled and still uses the same UART.
+     * Reset the current serial config, and compute the new one.
+     */
+
+    serial_cfg = 0x0048; /* All dummies */
+    for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++) {
+
+        switch (ser_new_cfg[uart_id]) { 
+
+            case G23_PANEL:
+                serial_cfg = serial_cfg +
+                    ((uart_id + 1) << (12 - (4 * SER_PROTOCOL_STACK)));
+                break;
+
+            case RIVIERA_TRACE_MUX:
+                serial_cfg = serial_cfg +
+                    ((uart_id + 1) << (12 - (4 * SER_LAYER_1)));
+                break;
+
+            case FD_AT_COMMAND:
+                serial_cfg = serial_cfg +
+                    ((uart_id + 1) << (12 - (4 * SER_FAX_DATA)));
+                break;
+
+            case BLUETOOTH_HCI:
+                serial_cfg = serial_cfg +
+                    ((uart_id + 1) << (12 - (4 * SER_BLUETOOTH_HCI)));
+
+                /*
+                 * Check if the Bluetooth HCI flow is enabled on the same UART.
+                 */
+
+                if (ser_cfg_info[uart_id] == BLUETOOTH_HCI)
+                    valid_config = 1;
+
+                break;
+
+            case DUMMY:
+                break;
+        }
+    }
+
+    if (!valid_config)
+        return (0); /* Bluetooth HCI flow not enabled in the new serial config,
+                       or enabled but using a different UART. */
+
+    /*
+     * Finally check if the new serial config is allowed by the application.
+     */
+     
+    valid_config = 0;
+    while ((nb_allowed_config > 0) && !valid_config) {
+        
+        nb_allowed_config--;
+        allowed_config = (SYS_UWORD16 *)
+                          &(serial_info->allowed_config[nb_allowed_config]);
+        
+        if (serial_cfg == *allowed_config)
+            valid_config = 1;
+    }
+
+    if (!valid_config) /* the new config is not allowed by the application */
+        return (0);
+
+    /*
+     * From now on, Dynamic Switch is being processed.
+     */
+
+    dynamic_switch = 1;
+
+    /*
+     * Disable UART interrupts until new serial config setup is complete.
+     */
+
+    #if ((CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11))
+      IQ_Mask (IQ_UART_IRDA_IT);
+    #endif
+    IQ_Mask (IQ_UART_IT);
+
+    /*
+     * Reset UARTs set-up.
+     */
+
+    for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++) {
+
+        int_uart[uart_id].device_used = 0;
+        int_uart[uart_id].deep_sleep_set_up = 0;
+        int_uart[uart_id].interrupt_handler = NULL;
+    }
+
+    /*
+     * All function pointers are set to dummy functions.
+     */
+
+    rvf_disable (21); /* beginning of the critical section */
+
+    for (flow = 0; flow < SER_MAX_NUMBER_OF_FLOWS; flow++)
+        tr_functions[flow] = &dummy_trace;
+
+    fd_functions = &dummy_fax_data;
+    bt_functions = &dummy_bt_hci;
+
+    rvf_enable (); /* end of the critical section */
+
+    /*
+     * Calls the Exit function of the UARTFAX driver if it was previously used.
+     */
+
+    if (uart_fd_initialized) {
+
+        /*
+         * UART IrDA can't be used for F&D/AT-Cmd flow => UART Modem was used
+         * by the F&D/AT-Cmd flow.
+         */
+
+        if (UAF_Exit (UAF_UART_1) == FD_OK) {
+            uart_fd_initialized = 0;
+        }
+    }
+    else {
+
+        /*
+         * AT that point, since the Bluetooth HCI flow already uses one UART,
+         * and since the second UART was not used by the F&D/AT-Cmd flow, we
+         * assume it was used by a Trace flow. Therefore, the HISR used to 
+         * reset and restart the sleep timer is deleted.
+         */
+
+        (void) NU_Delete_HISR (&timer_hisr_ctrl_block);
+    }
+
+    /*
+     * Initialization of the new flows (Only AT-Cmd/F&D or Riviera/Layer1 Trace)
+     * and their associated UARTs HW (Irda or Modem) & SW (Trace or Fax&Data).
+     */
+
+    for (flow = 0; flow < SER_MAX_NUMBER_OF_FLOWS; flow++) {
+
+        serial_flows[flow] = (T_SerialDriver)
+                             ((serial_cfg >> (12 - flow * 4)) & 0x000F);
+
+        switch (serial_flows[flow]) {
+
+            /*
+             * For Riviera/Layer1 Trace flow, default baudrate is 115200 bps
+             * and callback function is defined in rvt_def_i.h.
+             */
+
+            case UART_IRDA_TRACE:
+            case UART_MODEM_TRACE:
+
+                if (serial_flows[flow] == UART_IRDA_TRACE)
+                    uart_nb = UA_UART_0;
+                else /* if (serial_flows[flow] == UART_MODEM_TRACE) */
+                    uart_nb = UA_UART_1;
+
+                if (flow == SER_LAYER_1) {
+
+                    UA_Init (uart_nb,
+                             TR_BAUD_CONFIG,
+                             rvt_activate_RX_HISR);
+
+                    /*
+                     * Create the HISR used to reset and restart the sleep
+                     * timer in case of incoming characters on the Trace flow.
+                     * The stack is entirely filled with the pattern 0xFE.
+                     */
+
+                    memset (&(timer_hisr_stack[0]),
+                            0xFE,
+                            TIMER_HISR_STACK_SIZE);
+
+                    (void) NU_Create_HISR (
+                               &timer_hisr_ctrl_block,
+                               "Tim_HISR",
+                               SER_restart_uart_sleep_timer,
+                               TIMER_HISR_PRIORITY,
+                               &(timer_hisr_stack[0]),
+                               TIMER_HISR_STACK_SIZE);
+                }
+                else /* Other Trace flows are disabled */
+                    initialize_uart_sleep (uart_nb);
+                break;
+
+            /*
+             * For At-Cmd/F&D flow, functions are called in the appropriate
+             * order with the saved parameters.
+             * This has been figured out from the G23 initialization.
+             */
+
+            case UART_MODEM_FAX_DATA:
+
+                /* Global Initialization */
+                if (UAF_Init (UAF_UART_1) == FD_OK) {
+                    uart_fd_initialized = 1;
+                }
+
+                /* Disable the driver */
+                UAF_Enable (UAF_UART_1,
+                            0);
+
+                /* Set the SW Buffers parameters */
+                UAF_SetBuffer (UAF_UART_1,
+                               data_flow_parameters.bufSize,
+                               data_flow_parameters.rxThreshold,
+                               data_flow_parameters.txThreshold);
+
+                /* Set the Escape Sequence parameters (1st call) */
+                UAF_SetEscape (UAF_UART_1,
+                               data_flow_parameters.escChar[0],
+                               data_flow_parameters.guardPeriod[0]);
+
+                /* Set the Communication parameters (1st call) */
+                UAF_SetComPar (UAF_UART_1,
+                               data_flow_parameters.baudrate[0],
+                               data_flow_parameters.bpc[0],
+                               data_flow_parameters.sb[0],
+                               data_flow_parameters.parity[0]);
+
+                /* Set the Flow Control parameters (1st call) */
+                UAF_SetFlowCtrl (UAF_UART_1,
+                                 data_flow_parameters.fcMode[0],
+                                 data_flow_parameters.XON[0],
+                                 data_flow_parameters.XOFF[0]);
+
+                /* Set the Communication parameters (2nd call) */
+                UAF_SetComPar (UAF_UART_1,
+                               data_flow_parameters.baudrate[1],
+                               data_flow_parameters.bpc[1],
+                               data_flow_parameters.sb[1],
+                               data_flow_parameters.parity[1]);
+
+                /* Set the Flow Control parameters (2nd call) */
+                UAF_SetFlowCtrl (UAF_UART_1,
+                                 data_flow_parameters.fcMode[1],
+                                 data_flow_parameters.XON[1],
+                                 data_flow_parameters.XOFF[1]);
+
+                /* Set the Escape Sequence parameters (2nd call) */
+                UAF_SetEscape (UAF_UART_1,
+                               data_flow_parameters.escChar[1],
+                               data_flow_parameters.guardPeriod[1]);
+
+                /* Enable the driver */
+                UAF_Enable (UAF_UART_1,
+                            1);
+
+                /* Get the number of input bytes available */
+                UAF_InpAvail (UAF_UART_1);
+
+                /* Set the readOutFunc and the suspend mode */
+                UAF_ReadData (UAF_UART_1,
+                              data_flow_parameters.suspend_rd,
+                              data_flow_parameters.readOutFunc);
+
+                /* Get the number of output bytes available (1st call) */
+                UAF_OutpAvail (UAF_UART_1);
+
+                /* Set the states of the V.24 status lines (1st call) */
+                UAF_SetLineState (UAF_UART_1,
+                                  data_flow_parameters.state[0],
+                                  data_flow_parameters.mask[0]);
+
+                /* Set the states of the V.24 status lines (2nd call) */
+                UAF_SetLineState (UAF_UART_1,
+                                  data_flow_parameters.state[1],
+                                  data_flow_parameters.mask[1]);
+
+                /* Set the states of the V.24 status lines (3rd call) */
+                UAF_SetLineState (UAF_UART_1,
+                                  data_flow_parameters.state[2],
+                                  data_flow_parameters.mask[2]);
+
+                /* Set the states of the V.24 status lines (4th call) */
+                UAF_SetLineState (UAF_UART_1,
+                                  data_flow_parameters.state[3],
+                                  data_flow_parameters.mask[3]);
+
+                /* Set the writeInFunc and the suspend mode */
+                UAF_WriteData (UAF_UART_1,
+                               data_flow_parameters.suspend_wr,
+                               data_flow_parameters.writeInFunc);
+
+                /* Get the number of output bytes available (2nd call) */
+                UAF_OutpAvail (UAF_UART_1);
+
+                break;
+
+            case UART_IRDA_BT_HCI:
+            case UART_MODEM_BT_HCI:
+                /*
+                 * Nothing to initialize for Bluetooth HCI flow since it does
+                 * use the same UART.
+                 */
+
+            case DUMMY_TRACE:
+            case DUMMY_FAX_DATA:
+            case DUMMY_BT_HCI:
+                /*
+                 * Of course nothing to perform for Dummy flows.
+                 */
+
+                break;
+        }
+    }
+
+    /*
+     * All function pointers are set to the appropriate functions set.
+     */
+
+    for (flow = 0; flow < SER_MAX_NUMBER_OF_FLOWS; flow++){
+
+        /*
+         * For Dummy flows, pointers to dummy functions are already set.
+         */
+
+        if ((serial_flows[flow] != DUMMY_TRACE) &&
+            (serial_flows[flow] != DUMMY_FAX_DATA) &&
+            (serial_flows[flow] != DUMMY_BT_HCI)) {
+
+            rvf_disable (21); /* beginning of the critical section */
+            set_flow_functions (flow, serial_flows[flow]);
+            rvf_enable (); /* end of the critical section */
+        }
+    }
+
+    /*
+     * Dynamic Switch has been processed.
+     * The new serial config is actually stored.
+     */
+
+    dynamic_switch = 0;
+    for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++)
+        ser_cfg_info[uart_id] = ser_new_cfg[uart_id];
+
+    /*
+     * Re-enable UART interrupts.
+     */
+
+    #if ((CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11))
+      IQ_Unmask (IQ_UART_IRDA_IT);
+    #endif
+    IQ_Unmask (IQ_UART_IT);
+
+#endif
+    /*
+     * Real Dynamic Switch is only available with Bluetooth AND all chips but
+     * Calypso+.
+     */
+
+    return (1);
+}
+
+/*******************************************************************************
+ *
+ * All functions SER_tr_xxx and SER_fd_xxx call a function of the UART trace
+ * driver or the UART fax & data driver.
+ * All functions SER_bt_xxx call a function of the UART Bluetooth HCI driver.
+ * See the function call for parameters and return values.
+ *
+ ******************************************************************************/
+ 
+void
+SER_tr_Init (int serial_data_flow,
+             T_tr_Baudrate baudrate,
+             void (callback_function (void)))
+{
+    tr_functions[serial_data_flow]->tr_Init (
+                tr_functions[serial_data_flow]->device, baudrate, callback_function);
+}
+
+SYS_UWORD32
+SER_tr_ReadNChars (int serial_data_flow,
+                   char *buffer,
+                   SYS_UWORD32 chars_to_read)
+{
+    return (tr_functions[serial_data_flow]->tr_ReadNChars (
+                tr_functions[serial_data_flow]->device, buffer, chars_to_read));
+}
+
+SYS_UWORD32
+SER_tr_ReadNBytes (int serial_data_flow,
+                   char *buffer,
+                   SYS_UWORD32 chars_to_read,
+                   SYS_BOOL *eof_detected)
+{
+    return (tr_functions[serial_data_flow]->tr_ReadNBytes (
+                tr_functions[serial_data_flow]->device, buffer, chars_to_read, eof_detected));
+}
+
+SYS_UWORD32
+SER_tr_WriteNChars (int serial_data_flow,
+                    char *buffer,
+                    SYS_UWORD32 chars_to_write)
+{
+    return (tr_functions[serial_data_flow]->tr_WriteNChars (
+                tr_functions[serial_data_flow]->device, buffer, chars_to_write));
+}
+
+SYS_UWORD32
+SER_tr_EncapsulateNChars (int serial_data_flow,
+                          char *buffer,
+                          SYS_UWORD32 chars_to_write)
+{
+    return (tr_functions[serial_data_flow]->tr_EncapsulateNChars (
+                tr_functions[serial_data_flow]->device, buffer, chars_to_write));
+}
+
+SYS_UWORD32
+SER_tr_WriteNBytes (int serial_data_flow,
+                    SYS_UWORD8 *buffer,
+                    SYS_UWORD32 chars_to_write)
+{
+    return (tr_functions[serial_data_flow]->tr_WriteNBytes (
+                tr_functions[serial_data_flow]->device, buffer, chars_to_write));
+}
+
+void
+SER_tr_WriteChar (int serial_data_flow,
+                  char character)
+{
+    tr_functions[serial_data_flow]->tr_WriteChar (
+                tr_functions[serial_data_flow]->device, character);
+}
+
+void
+SER_tr_WriteString (int serial_data_flow,
+                    char *buffer)
+{
+    tr_functions[serial_data_flow]->tr_WriteString (
+                tr_functions[serial_data_flow]->device, buffer);
+}
+
+SYS_BOOL
+SER_tr_EnterSleep (int serial_data_flow)
+{
+    return (tr_functions[serial_data_flow]->tr_EnterSleep (
+                tr_functions[serial_data_flow]->device));
+}
+
+void
+SER_tr_WakeUp (int serial_data_flow)
+{
+    tr_functions[serial_data_flow]->tr_WakeUp (
+                tr_functions[serial_data_flow]->device);
+}
+
+/* Dummy function for backward compatibility. */
+T_FDRET
+SER_fd_Init (void)
+{
+    return (FD_OK);
+}
+
+T_FDRET
+SER_fd_Initialize (void)
+{
+    T_FDRET status;
+
+    #if SERIAL_DYNAMIC_SWITCH
+      data_flow_parameters.bufSize = FD_MAX_BUFFER_SIZE;
+    #else
+      bufSize = FD_MAX_BUFFER_SIZE;
+    #endif
+    status = fd_functions->fd_Initialize (fd_functions->device);
+
+    #if SERIAL_DYNAMIC_SWITCH
+      /*
+       *  Check if the UARTFAX driver has actually been initialized.
+       */
+
+      if ((fd_functions->fd_Initialize == UAF_Init) &&
+          (status = FD_OK)) {
+
+          uart_fd_initialized = 1;
+      }
+    #endif
+
+    return (status);
+}
+
+static void
+fd_dbgtrace(char *msg, UINT32 val)
+{
+	rvf_send_trace(msg, strlen(msg), val, RV_TRACE_LEVEL_DEBUG_HIGH, 0);
+}
+
+T_FDRET
+SER_fd_Enable (SYS_BOOL enable)
+{
+	T_FDRET rc;
+
+	fd_dbgtrace("SER_fd_Enable called", enable);
+	rc = fd_functions->fd_Enable (fd_functions->device, enable);
+	fd_dbgtrace("fd_Enable returned", rc);
+	return rc;
+}
+
+T_FDRET
+SER_fd_SetComPar (T_baudrate baudrate,
+                  T_bitsPerCharacter bpc,
+                  T_stopBits sb,
+                  T_parity parity)
+{
+	T_FDRET rc;
+	char trbuf[80];
+
+	sprintf(trbuf, "SER_fd_SetComPar(%d, %d, %d, %d)",
+		baudrate, bpc, sb, parity);
+	fd_dbgtrace(trbuf, NULL_PARAM);
+	rc = (fd_functions->fd_SetComPar (
+                fd_functions->device, baudrate, bpc, sb, parity));
+	fd_dbgtrace("fd_SetComPar returned", rc);
+	return rc;
+}
+
+T_FDRET
+SER_fd_SetBuffer (SYS_UWORD16 bufSize,
+                  SYS_UWORD16 rxThreshold,
+                  SYS_UWORD16 txThreshold)
+{
+	T_FDRET rc;
+	char trbuf[80];
+
+	sprintf(trbuf, "SER_fd_SetBuffer(%u, %u, %u)",
+		bufSize, rxThreshold, txThreshold);
+	fd_dbgtrace(trbuf, NULL_PARAM);
+	rc = (fd_functions->fd_SetBuffer (
+                fd_functions->device, bufSize, rxThreshold, txThreshold));
+	fd_dbgtrace("fd_SetBuffer returned", rc);
+	return rc;
+}
+
+T_FDRET
+SER_fd_SetFlowCtrl (T_flowCtrlMode fcMode,
+                    SYS_UWORD8 XON,
+                    SYS_UWORD8 XOFF)
+{
+	T_FDRET rc;
+	char trbuf[80];
+
+	sprintf(trbuf, "SER_fd_SetFlowCtrl(%d, %02x, %02x)", fcMode, XON, XOFF);
+	fd_dbgtrace(trbuf, NULL_PARAM);
+	rc = (fd_functions->fd_SetFlowCtrl (
+                fd_functions->device, fcMode, XON, XOFF));
+	fd_dbgtrace("fd_SetFlowCtrl returned", rc);
+	return rc;
+}
+
+T_FDRET
+SER_fd_SetEscape (char escChar,
+                  SYS_UWORD16 guardPeriod)
+{
+	T_FDRET rc;
+	char trbuf[80];
+
+	sprintf(trbuf, "SER_fd_SetEscape(%02x, %u)", escChar, guardPeriod);
+	fd_dbgtrace(trbuf, NULL_PARAM);
+	rc = (fd_functions->fd_SetEscape (
+                fd_functions->device, escChar, guardPeriod));
+	fd_dbgtrace("fd_SetEscape returned", rc);
+	return rc;
+}
+
+T_FDRET
+SER_fd_InpAvail (void)
+{
+	T_FDRET rc;
+
+	fd_dbgtrace("SER_fd_InpAvail called", NULL_PARAM);
+	rc = (fd_functions->fd_InpAvail (fd_functions->device));
+	fd_dbgtrace("fd_InpAvail returned", rc);
+	return rc;
+}
+
+T_FDRET
+SER_fd_OutpAvail (void)
+{
+	T_FDRET rc;
+
+	fd_dbgtrace("SER_fd_OutpAvail called", NULL_PARAM);
+	rc = (fd_functions->fd_OutpAvail (fd_functions->device));
+	fd_dbgtrace("fd_OutpAvail returned", rc);
+	return rc;
+}
+
+T_FDRET
+SER_fd_EnterSleep (void)
+{
+    return (fd_functions->fd_EnterSleep (fd_functions->device));
+}
+
+T_FDRET
+SER_fd_WakeUp (void)
+{
+    return (fd_functions->fd_WakeUp (fd_functions->device));
+}
+
+T_FDRET
+SER_fd_ReadData (T_suspendMode suspend,
+                 void (readOutFunc (SYS_BOOL cldFromIrq,
+                                    T_reInstMode *reInstall,
+                                    SYS_UWORD8 nsource,
+                                    SYS_UWORD8 *source[],
+                                    SYS_UWORD16 size[],
+                                    SYS_UWORD32 state)))
+{
+	T_FDRET rc;
+
+	fd_dbgtrace("SER_fd_ReadData called", suspend);
+	rc = (fd_functions->fd_ReadData (
+                fd_functions->device, suspend, readOutFunc));
+	fd_dbgtrace("fd_ReadData returned", rc);
+	return rc;
+}
+
+T_FDRET
+SER_fd_WriteData (T_suspendMode suspend,
+                  void (writeInFunc (SYS_BOOL cldFromIrq,
+                                     T_reInstMode *reInstall,
+                                     SYS_UWORD8 ndest,
+                                     SYS_UWORD8 *dest[],
+                                     SYS_UWORD16 size[])))
+{
+	T_FDRET rc;
+
+	fd_dbgtrace("SER_fd_WriteData called", suspend);
+	rc = (fd_functions->fd_WriteData (
+                fd_functions->device, suspend, writeInFunc));
+	fd_dbgtrace("fd_WriteData returned", rc);
+	return rc;
+}
+
+T_FDRET
+SER_fd_StopRec (void)
+{
+	T_FDRET rc;
+
+	fd_dbgtrace("SER_fd_StopRec called", NULL_PARAM);
+	rc = (fd_functions->fd_StopRec (fd_functions->device));
+	fd_dbgtrace("fd_StopRec returned", rc);
+	return rc;
+}
+
+T_FDRET
+SER_fd_StartRec (void)
+{
+	T_FDRET rc;
+
+	fd_dbgtrace("SER_fd_StartRec called", NULL_PARAM);
+	rc = (fd_functions->fd_StartRec (fd_functions->device));
+	fd_dbgtrace("fd_StartRec returned", rc);
+	return rc;
+}
+
+T_FDRET
+SER_fd_GetLineState (SYS_UWORD32 *state)
+{
+	T_FDRET rc;
+	char trbuf[80];
+
+	fd_dbgtrace("SER_fd_GetLineState called", NULL_PARAM);
+	rc = (fd_functions->fd_GetLineState (fd_functions->device, state));
+	sprintf(trbuf, "fd_GetLineState returned %d, %x", rc, *state);
+	fd_dbgtrace(trbuf, NULL_PARAM);
+	return rc;
+}
+
+T_FDRET
+SER_fd_SetLineState (SYS_UWORD32 state,
+                     SYS_UWORD32 mask)
+{
+	T_FDRET rc;
+	char trbuf[80];
+
+	sprintf(trbuf, "SER_fd_SetLineState(%x, %x)", state, mask);
+	fd_dbgtrace(trbuf, NULL_PARAM);
+	rc = (fd_functions->fd_SetLineState (fd_functions->device, state, mask));
+	fd_dbgtrace("fd_SetLineState returned", rc);
+	return rc;
+}
+
+T_FDRET
+SER_fd_CheckXEmpty (void)
+{
+	T_FDRET rc;
+
+	fd_dbgtrace("SER_fd_CheckXEmpty called", NULL_PARAM);
+	rc = (fd_functions->fd_CheckXEmpty (fd_functions->device));
+	fd_dbgtrace("fd_CheckXEmpty returned", rc);
+	return rc;
+}
+
+#ifdef BTEMOBILE
+T_HCI_RET
+SER_bt_Init (void)
+{
+    return (bt_functions->bt_Init (bt_functions->device));
+}
+
+T_HCI_RET
+SER_bt_Start (void)
+{
+    return (bt_functions->bt_Start ());
+}
+
+T_HCI_RET
+SER_bt_Stop (void)
+{
+    return (bt_functions->bt_Stop ());
+}
+
+T_HCI_RET
+SER_bt_Kill (void)
+{
+    return (bt_functions->bt_Kill ());
+}
+
+T_HCI_RET
+SER_bt_SetBaudrate (UINT8 baudrate)
+{
+    return (bt_functions->bt_SetBaudrate (baudrate));
+}
+
+T_HCI_RET SER_bt_TransmitPacket (void *uart_tx_buffer)
+{
+    return (bt_functions->bt_TransmitPacket (uart_tx_buffer));
+}
+
+SYS_BOOL SER_bt_EnterSleep (void)
+{
+    return (bt_functions->bt_EnterSleep());
+}
+
+void SER_bt_WakeUp (void)
+{
+    bt_functions->bt_WakeUp();
+}
+#endif /* BTEMOBILE */
+
+/*******************************************************************************
+ *
+ *                          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.
+ *
+ ******************************************************************************/
+
+SYS_BOOL
+SER_UartSleepStatus (void)
+{
+    t_uart   *uart;
+    int      uart_id;
+    SYS_BOOL status;
+
+    /*
+     * Check first if the sleep timer is active or if a Dynamic Switch is
+     * being processed. A return is used to simplify the code.
+     */
+
+#if SERIAL_DYNAMIC_SWITCH
+    if (uart_sleep_timer_enabled || dynamic_switch)
+#else
+    if (uart_sleep_timer_enabled)
+#endif
+	    return (0);
+
+    /*
+     * Check if both UARTs are ready to enter Deep Sleep.
+     */
+
+    status = 1;
+    uart_id = 0;
+    while ((uart_id < NUMBER_OF_TR_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 ();
+#ifdef BTEMOBILE
+                   else
+                       if (uart->flow_type == BLUETOOTH_HCI_FLOW) 
+                           status = SER_bt_EnterSleep();
+#endif
+                       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_TR_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.
+                 * Bluetooth HCI can not yet handled Deep Sleep Mode.
+                 */
+
+                if (uart->flow_type == TRACE_FLOW)
+                    SER_tr_WakeUp (uart->flow_id);
+
+                else  
+                    if (uart->flow_type == FAX_DATA_FLOW) 
+                    	SER_fd_WakeUp ();
+#ifdef BTEMOBILE
+                    else 
+                        if (uart->flow_type == BLUETOOTH_HCI_FLOW)
+                            SER_bt_WakeUp ();
+#endif
+                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_sleep_timer_enabled)
+        start_uart_sleep_timer ();
+
+    for (uart_id = 0; uart_id < NUMBER_OF_TR_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
+                if (uart->flow_type == FAX_DATA_FLOW) 
+                	SER_fd_WakeUp ();
+#ifdef BTEMOBILE
+                else
+                    if (uart->flow_type == BLUETOOTH_HCI_FLOW)
+                        SER_bt_WakeUp ();
+#endif
+            /*
+             * The specified UART is no more set up for Deep Sleep.
+             */
+
+            uart->deep_sleep_set_up = 0;
+
+        }
+    }
+}
+
+
+/*******************************************************************************
+ *
+ *                         SER_restart_uart_sleep_timer
+ * 
+ * Purpose  : Resets and restarts the sleep timer each time some characters are
+ *            received.
+ *
+ * Arguments: In : none
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+void
+SER_restart_uart_sleep_timer (void)
+{
+    /*
+     * First disable the timer.
+     */
+
+    (void) NU_Control_Timer (&uart_sleep_timer,
+                             NU_DISABLE_TIMER);
+
+    /*
+     * Then start again this timer for a new period.
+     */
+
+    start_uart_sleep_timer ();
+}
+
+
+/*******************************************************************************
+ *
+ *                            SER_activate_timer_hisr
+ * 
+ * Purpose  : Activates the timer HISR to reset and restart the sleep timer
+ *            each time some characters are received.
+ *
+ * Arguments: In : none
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+void
+SER_activate_timer_hisr (void)
+{
+    (void) NU_Activate_HISR (&timer_hisr_ctrl_block);
+}
+
+
+#if ((CHIPSET == 2) || (CHIPSET == 3))
+
+/*******************************************************************************
+ *
+ *                                SER_uart_handler
+ * 
+ * Purpose  : UART interrupt handler.
+ *
+ * Arguments: In : none
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+void
+SER_uart_handler (void)
+{
+    SYS_UWORD8 interrupt_status;
+    t_uart     *uart;
+    int        uart_id;
+    SYS_BOOL   it_identified;
+
+    it_identified = 0;
+
+    /*
+     * Check first for a wake-up interrupt.
+     */
+
+    uart_id = 0;
+    while ((uart_id < NUMBER_OF_TR_UART) &&
+           (!it_identified)) {
+
+           uart = &(int_uart[uart_id]);
+           interrupt_status = READ_UART_REGISTER (uart, SSR);
+
+           if (interrupt_status & RX_CTS_WAKE_UP_STS) { /* Wake-up IT has occurred */
+
+               it_identified = 1;
+               uart_sleep_timer_enabled = 1;
+			   DISABLE_WAKE_UP_INTERRUPT (uart);
+           }
+
+           uart_id++;
+    }
+
+    /*
+     * If no wake-up interrupt has been detected, check then systematically
+     * both UARTs for other interrupt causes.
+     */
+
+    if (!it_identified) {
+
+        for (uart_id = 0; uart_id < NUMBER_OF_TR_UART; uart_id++) {
+
+            uart = &(int_uart[uart_id]);
+            interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED;
+
+            if (!(interrupt_status & IT_NOT_PENDING)) {
+
+                it_identified = 1;
+                (*(uart->interrupt_handler)) (uart_id, interrupt_status);
+
+            } else {
+
+                if ((uart_id == UA_UART_1) && (!it_identified))
+                uart_spurious_interrupts++;
+            }
+        }
+    }
+}
+
+#elif ((CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12))
+
+/*******************************************************************************
+ *
+ *                                SER_uart_modem_handler
+ * 
+ * Purpose  : UART MODEM interrupt handler.
+ *
+ * Arguments: In : none
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+void
+SER_uart_modem_handler (void)
+{
+    SYS_UWORD8 interrupt_status;
+    t_uart     *uart;
+    SYS_BOOL   it_wakeup_identified;
+
+    it_wakeup_identified = 0;
+    uart = &(int_uart[UA_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_sleep_timer_enabled = 1;
+#ifdef BTEMOBILE
+        if (uart->flow_type == BLUETOOTH_HCI_FLOW)
+        {
+            interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED;
+            (*(uart->interrupt_handler)) (UA_UART_1, interrupt_status);
+        }
+#endif /* BTEMOBILE */
+        DISABLE_WAKE_UP_INTERRUPT (uart);
+    }
+
+    /*
+     * If no wake-up interrupt has been detected, check UART for other
+     * interrupt causes.
+     */
+
+    if (!it_wakeup_identified) {
+
+        interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED;
+
+        if (!(interrupt_status & IT_NOT_PENDING))
+            (*(uart->interrupt_handler)) (UA_UART_1, interrupt_status);
+
+        else
+            uart_modem_spurious_interrupts++;
+    }
+}
+
+
+/*******************************************************************************
+ *
+ *                                SER_uart_irda_handler
+ * 
+ * Purpose  : UART IrDA interrupt handler.
+ *
+ * Arguments: In : none
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+void
+SER_uart_irda_handler (void)
+{
+    SYS_UWORD8 interrupt_status;
+    t_uart     *uart;
+    SYS_BOOL   it_wakeup_identified;
+
+    it_wakeup_identified = 0;
+    uart = &(int_uart[UA_UART_0]);
+
+    /*
+     * 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_sleep_timer_enabled = 1;
+#ifdef BTEMOBILE
+        if (uart->flow_type == BLUETOOTH_HCI_FLOW)
+        {
+            interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED;
+            (*(uart->interrupt_handler)) (UA_UART_0, interrupt_status);
+        }
+#endif /* BTEMOBILE */
+        DISABLE_WAKE_UP_INTERRUPT (uart);
+    }
+
+    /*
+     * If no wake-up interrupt has been detected, check UART for other
+     * interrupt causes.
+     */
+
+    if (!it_wakeup_identified) {
+
+        interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED;
+
+        if (!(interrupt_status & IT_NOT_PENDING))
+            (*(uart->interrupt_handler)) (UA_UART_0, interrupt_status);
+
+        else
+            uart_irda_spurious_interrupts++;
+    }
+}
+
+#endif
+
+#if (CHIPSET == 12)
+  /*******************************************************************************
+   *
+   *                                SER_uart_modem2_handler
+   * 
+   * Purpose  : UART IrDA interrupt handler.
+   *
+   * Arguments: In : none
+   *            Out: none
+   *
+   * Returns  : none
+   *
+   ******************************************************************************/
+
+  void
+  SER_uart_modem2_handler (void)
+  {
+      SYS_UWORD8 interrupt_status;
+      t_uart     *uart;
+      SYS_BOOL   it_wakeup_identified;
+
+      it_wakeup_identified = 0;
+      uart = &(int_uart[UA_UART_2]);
+
+      /*
+       * 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_sleep_timer_enabled = 1;
+#ifdef BTEMOBILE
+          if (uart->flow_type == BLUETOOTH_HCI_FLOW)
+          {
+              interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED;
+              (*(uart->interrupt_handler)) (UA_UART_2, interrupt_status);
+          }
+#endif /* BTEMOBILE */
+          DISABLE_WAKE_UP_INTERRUPT (uart);
+      }
+
+      /*
+       * If no wake-up interrupt has been detected, check UART for other
+       * interrupt causes.
+       */
+
+      if (!it_wakeup_identified) {
+
+          interrupt_status = READ_UART_REGISTER (uart, IIR) & IIR_BITS_USED;
+
+          if (!(interrupt_status & IT_NOT_PENDING))
+              (*(uart->interrupt_handler)) (UA_UART_2, interrupt_status);
+        
+          else
+              uart_modem2_spurious_interrupts++;
+      }
+  }
+
+#endif
+
+/*
+ * Temporary functions. 
+ *
+ * FreeCalypso note: I'll put them back in if they are actually needed.
+ */
+
+#if 0
+
+void
+UT_Init (int device_id,
+         int baudrate,
+         void (callback_function (void)))
+{
+    SER_tr_Init (SER_PROTOCOL_STACK, baudrate, callback_function);
+}
+
+SYS_UWORD32
+UT_ReadNChars (int device_id,
+               char *buffer,
+               SYS_UWORD32 chars_to_read)
+{
+    return (SER_tr_ReadNChars (SER_PROTOCOL_STACK, buffer, chars_to_read));
+}
+
+SYS_UWORD32
+UT_WriteNChars (int device_id,
+                char *buffer,
+                SYS_UWORD32 chars_to_write)
+{
+    return (SER_tr_WriteNChars (SER_PROTOCOL_STACK, buffer, chars_to_write));
+}
+
+void
+UT_WriteChar (int device_id,
+              char character)
+{
+    SER_tr_WriteChar (SER_PROTOCOL_STACK, character);
+}
+
+void
+UT_WriteString (int device_id,
+                char *buffer)
+{
+    SER_tr_WriteString (SER_PROTOCOL_STACK, buffer);
+}
+
+short
+UF_Init (SYS_UWORD8 deviceNo)
+{
+    return (SER_fd_Init ());
+}
+
+short
+UF_Enable (SYS_UWORD8 deviceNo,
+           SYS_BOOL enable)
+{
+    return (SER_fd_Enable (enable));
+}
+
+short
+UF_SetComPar (SYS_UWORD8 deviceNo,
+              T_baudrate baudrate,
+              T_bitsPerCharacter bpc,
+              T_stopBits sb,
+              T_parity parity)
+{
+    return (SER_fd_SetComPar (baudrate,
+                              bpc,
+                              sb,
+                              parity));
+}
+
+short
+UF_SetBuffer (SYS_UWORD8 deviceNo,
+              SYS_UWORD16 bufSize,
+              SYS_UWORD16 rxThreshold,
+              SYS_UWORD16 txThreshold)
+{
+    return (SER_fd_SetBuffer (bufSize, rxThreshold, txThreshold));
+}
+
+short
+UF_SetFlowCtrl (SYS_UWORD8 deviceNo,
+                T_flowCtrlMode fcMode,
+                SYS_UWORD8 XON,
+                SYS_UWORD8 XOFF)
+{
+    return (SER_fd_SetFlowCtrl (fcMode, XON, XOFF));
+}
+
+short
+UF_SetEscape (SYS_UWORD8 deviceNo,
+              SYS_UWORD8 escChar,
+              SYS_UWORD16 guardPeriod)
+{
+    return (SER_fd_SetEscape (escChar, guardPeriod));
+}
+
+short
+UF_InpAvail (SYS_UWORD8 deviceNo)
+{
+    return (SER_fd_InpAvail ());
+}
+
+short
+UF_OutpAvail (SYS_UWORD8 deviceNo)
+{
+    return (SER_fd_OutpAvail ());
+}
+
+short
+UF_ReadData (SYS_UWORD8 deviceNo,
+             T_suspendMode suspend,
+             void (readOutFunc (SYS_BOOL cldFromIrq,
+                                T_reInstMode *reInstall,
+                                SYS_UWORD8 nsource,
+                                SYS_UWORD8 *source[],
+                                SYS_UWORD16 size[],
+                                SYS_UWORD32 state)))
+{
+    return (SER_fd_ReadData (suspend, readOutFunc));
+}
+
+short
+UF_WriteData (SYS_UWORD8 deviceNo,
+              T_suspendMode suspend,
+              void (writeInFunc (SYS_BOOL cldFromIrq,
+                                 T_reInstMode *reInstall,
+                                 SYS_UWORD8 ndest,
+                                 SYS_UWORD8 *dest[],
+                                 SYS_UWORD16 size[])))
+{
+    return (SER_fd_WriteData (suspend, writeInFunc));
+}
+
+short
+UF_StopRec (SYS_UWORD8 deviceNo)
+{
+    return (SER_fd_StopRec ());
+}
+
+short
+UF_StartRec (SYS_UWORD8 deviceNo)
+{
+    return (SER_fd_StartRec ());
+}
+
+short
+UF_GetLineState (SYS_UWORD8 deviceNo,
+                 SYS_UWORD32 *state)
+{
+    return (SER_fd_GetLineState (state));
+}
+
+short
+UF_SetLineState (SYS_UWORD8 deviceNo,
+                 SYS_UWORD32 state,
+                 SYS_UWORD32 mask)
+{
+    return (SER_fd_SetLineState (state, mask));
+}
+
+short
+UF_CheckXEmpty (SYS_UWORD8 deviceNo)
+{
+    return (SER_fd_CheckXEmpty ());
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/serial/debug-chases/uartfax.c	Thu Apr 30 01:46:26 2015 +0000
@@ -0,0 +1,5161 @@
+/*******************************************************************************
+ *
+ * UARTFAX.C
+ *
+ * This driver allows to control the UARTs of chipset 1.5 for fax and data
+ * services. It performs flow control: RTS/CTS, XON/XOFF.
+ *
+ * On C & D-Sample, DCD and DTR signals are supported on UART modem only with 2
+ * I/Os.
+ *
+ * On E-Sample, DCD and DTR signals are directly handled by Calypso+.
+ *
+ * On Calypso, RTS and CTS are supported on both UARTs.
+ *
+ * On Calypso+, RTS and CTS are supported on UART Modem1 & IrDA. UART Modem2 is
+ * not available through DB9 connector on E-Sample.
+ *
+ * (C) Texas Instruments 1999 - 2003
+ *
+ ******************************************************************************/
+
+/*
+ * E-Sample
+ *
+ * UART Modem1                  UART Irda
+ *
+ *     DB9   Calypso+               DB9   Calypso+
+ *
+ * 1   DCD   DCD      output    1   1, 6 and 4 are connected together on DB9
+ * 2   RX    TX       output    2   RX    TX2       output
+ * 3   TX    RX       input     3   TX    RX2       input
+ * 4   DTR   DSR      input     4   
+ * 5   GND                      5   GND
+ * 6   NC                       6   
+ * 7   RTS   CTS      input     7   RTS   CTS2      input
+ * 8   CTS   RTS      output    8   CTS   RTS2      output
+ * 9   NC                       9   NC
+ *
+ */
+
+/*
+ * C & D-Sample
+ *
+ * UART Modem                   UART Irda
+ *
+ *     DB9   Calypso                DB9   Calypso
+ *
+ * 1   DCD   I/O 2    output    1   1, 6 and 4 are connected together on DB9
+ * 2   RX    TX       output    2   RX    TX2       output
+ * 3   TX    RX       input     3   TX    RX2       input
+ * 4   DTR   I/O 3    input     4   
+ * 5   GND                      5   GND
+ * 6   NC                       6   
+ * 7   RTS   CTS      input     7   RTS   CTS2      input
+ * 8   CTS   RTS      output    8   CTS   RTS2      output
+ * 9   NC                       9   NC
+ *
+ */
+
+/*
+ * B-Sample
+ *
+ * UART Modem                   UART Irda
+ *
+ *     DB9   Ulysse                 DB9   Ulysse
+ *
+ * 1   1, 6 and 4 are connected together on DB9 (Modem and Irda)
+ * 2   RX    TX                 2   RX    TX
+ * 3   TX    RX                 3   TX    RX
+ * 4                            4
+ * 5   GND                      5   GND
+ * 6                            6
+ * 7   RTS   CTS                7   7 and 8 are connected together on DB9
+ * 8   CTS   RTS                8
+ * 9   NC                       9   NC
+ *
+ */
+ 
+#include "../include/config.h"
+
+#include <string.h>
+
+/*
+ * rv_general.h is needed for macros Min & Min3.
+ */
+#include "../riviera/rv/rv_general.h"
+#include "../nucleus/nucleus.h"
+
+#include "../include/sys_types.h"
+#include "faxdata.h"
+#include "uartfax.h"
+
+/*
+ * Needed to reset and restart the sleep timer in case of incoming characters.
+ */
+
+#include "serialswitch.h"
+extern SYS_BOOL uart_sleep_timer_enabled;
+
+#include "../bsp/mem.h"
+
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41))
+  #include "../bsp/armio.h"
+#endif
+
+#define	HighGPIO	AI_SetBit
+#define	LowGPIO		AI_ResetBit
+
+/* 
+ * Maximal value for an unsigned 32 bits.
+ */
+
+#define MAX_UNSIGNED_32 (4294967295)
+
+#define FIFO_SIZE (64) /* In bytes. */
+
+
+/*
+ * TLR is used to program the RX FIFO trigger levels. FCR[7:4] are  not used.
+ * No trigger level used for TX FIFO. THR_IT generated on TX FIFO empty.
+ */
+ 
+#define RX_FIFO_TRIGGER_LEVEL (12 << 4)
+
+
+/*
+ * 16750 addresses. Registers accessed when LCR[7] = 0.
+ */
+
+#define RHR (0x00) /* Rx buffer register - Read access   */
+#define THR (0x00) /* Tx holding register - Write access */
+#define IER (0x01) /* Interrupt enable register          */
+
+/*
+ * 16750 addresses. Registers accessed when LCR[7] = 1.
+ */
+
+#define DLL (0x00) /* Divisor latch (LSB) */
+#define DLM (0x01) /* Divisor latch (MSB) */
+
+
+/*
+ * EFR is accessed when LCR[7:0] = 0xBF.
+ */
+
+#define EFR (0x02) /* Enhanced feature register */
+
+
+/*
+ * 16750 addresses. Bit 5 of the FCR register is accessed when LCR[7] = 1.
+ */
+
+#define IIR (0x02)  /* Interrupt ident. register - Read only */
+#define FCR (0x02)  /* FIFO control register - Write only    */
+#define LCR (0x03)  /* Line control register                 */
+#define MCR (0x04)  /* Modem control register                */
+#define LSR (0x05)  /* Line status register                  */
+#define MSR (0x06)  /* Modem status register                 */
+#define TCR  (0x06) /* Transmission control register         */
+#define TLR  (0x07) /* Trigger level register                */
+#define MDR1 (0x08) /* Mode definition register 1            */
+#define SCR  (0x10) /* Supplementary Control register        */
+#define SSR  (0x11) /* Supplementary Status register         */
+#define UASR (0x0E) /* Autobauding Status register           */
+
+/*
+ * Supplementary control register.
+ */
+
+#define TX_EMPTY_CTL_IT (0x08)
+#define RX_CTS_WAKE_UP_ENABLE_BIT (4) /* Use RESET_BIT and SET_BIT macros. */
+#define DSR_IT_BIT                (5) /* Use RESET_BIT and SET_BIT macros. */
+
+/*
+ * Enhanced feature register.
+ */
+ 
+#define ENHANCED_FEATURE_BIT (4) /* Use RESET_BIT and SET_BIT macros. */
+#define AUTO_CTS_BIT         (7) /* Transmission is halted when the CTS pin is high (inactive). */
+
+/*
+ * Mode definition register 1.
+ */
+
+#define UART_MODE             (0x00)
+#define SIR_MODE              (0x01)
+#define UART_MODE_AUTOBAUDING (0x02) /* Reserved in UART/IrDA. */
+#define RESET_DEFAULT_STATE   (0x07)
+#define IR_SLEEP_DISABLED     (0x00)
+#define IR_SLEEP_ENABLED      (0x08)
+#define SIR_TX_WITHOUT_ACREG2 (0x00) /* Reserved in UART/modem. */
+#define SIR_TX_WITH_ACREG2    (0x20) /* Reserved in UART/modem. */
+#define FRAME_LENGTH_METHOD   (0x00) /* Reserved in UART/modem. */
+#define EOT_BIT_METHOD        (0x80) /* Reserved in UART/modem. */
+
+/*
+ * Supplementary Status Register
+ */
+
+#define TX_FIFO_FULL (0x01)
+
+
+/*
+ * Interrupt enable register.
+ */
+
+#define ERBI  (0x01) /* Enable received data available interrupt            */
+#define ETBEI (0x02) /* Enable transmitter holding register empty interrupt */
+#define ELSI  (0x04) /* Enable receiver line status interrupt               */
+#define EDSSI (0x08) /* Enable modem status interrupt                       */
+#define IER_SLEEP (0x10)  /* Enable sleep mode                              */
+
+/*
+ * Modem control register.
+ */
+
+#define MDCD (0x01) /* Data Carrier Detect. */
+#define MRTS (0x02) /* Request To Send.     */
+#define TCR_TLR_BIT (6)
+
+/*
+ * Line status register.
+ */
+
+#define DR   (0x01) /* Data ready                                  */
+#define OE   (0x02) /* Overrun error                               */
+#define PE   (0x04) /* Parity error                                */
+#define FE   (0x08) /* Framing error                               */
+#define BI   (0x10) /* Break interrupt                             */
+#define THRE (0x20) /* Transmitter holding register (FIFO empty)   */
+#define TEMT (0x40) /* Transmitter empty (FIFO and TSR both empty) */
+
+#define BYTE_ERROR (OE | PE | FE | BI)
+
+/*
+ * Interrupt identification register.
+ * Bit 0 is set to 0 if an IT is pending.
+ * Bits 1 and 2 are used to identify the IT.
+ */
+
+#define IIR_BITS_USED    (0x07)
+#define IT_PENDING       (0x01)
+#define RX_DATA          (0x04)
+#define TX_EMPTY         (0x02)
+#define MODEM_STATUS     (0x00)
+
+/*
+ * Modem status register.
+ */
+
+#define DELTA_CTS (0x01)
+#define DELTA_DSR (0x02)
+#define MCTS      (0x10) /* Clear to send       */
+#define MDSR      (0x20) /* Data set ready      */
+
+/*
+ * Line control register.
+ */
+
+#define WLS_5         (0x00) /* Word length: 5 bits                    */
+#define WLS_6         (0x01) /* Word length: 6 bits                    */
+#define WLS_7         (0x02) /* Word length: 7 bits                    */
+#define WLS_8         (0x03) /* Word length: 8 bits                    */
+#define STB           (0x04) /* Number of stop bits: 0: 1, 1: 1,5 or 2 */
+#define PEN           (0x08) /* Parity enable                          */
+#define EPS           (0x10) /* Even parity select                     */
+#define BREAK_CONTROL (0x40) /* Enable a break condition               */
+#define DLAB          (0x80) /* Divisor latch access bit               */
+
+/*
+ * FIFO control register.
+ */
+
+#define FIFO_ENABLE   (0x01)
+#define RX_FIFO_RESET (0x02)
+#define TX_FIFO_RESET (0x04)
+
+/*
+ * These constants define the states of the escape sequence detection.
+ */
+
+#define INITIALIZATION       (0)
+#define NO_ESCAPE_SEQUENCE   (1)
+#define ONE_CHAR_DETECTED    (2)
+#define TWO_CHARS_DETECTED   (3)
+#define THREE_CHARS_DETECTED (4)
+
+#define CHARACTERS_IN_ESC_SEQ        (3)
+#define DEFAULT_ESC_SEQ_CHARACTER    '+'
+#define DEFAULT_GUARD_PERIOD      (1000) /* 1 second. */
+
+/*
+ * 3 HISR are used to avoid to execute operations from the LISR.
+ */
+ 
+#define RX_HISR_PRIORITY      (2)
+
+
+
+
+// NGENGE increase hisr stack otherwise overflows with multiple callbacks
+//#define RX_HISR_STACK_SIZE  (512) /* Bytes. */ 
+#define RX_HISR_STACK_SIZE  (768) /* Bytes. */ 
+
+
+
+
+#define TX_HISR_PRIORITY      (2)
+
+
+
+// NGENGE increase hisr stack otherwise overflows with multiple callbacks
+//#define TX_HISR_STACK_SIZE  (512) /* Bytes. */ 
+#define TX_HISR_STACK_SIZE  (768) /* Bytes. */ 
+
+
+
+
+#define V24_HISR_PRIORITY     (2)
+#define V24_HISR_STACK_SIZE (512) /* Bytes. */ 
+
+/*
+ * When the break interrupt indicator (BI) is set in the line status register
+ * (LSR), it indicates that the received data input was held in the low state
+ * for longer than a full-word transmission time. In the FIFO mode, when a break
+ * occurs, only one 0 character is loaded into the FIFO. The next character
+ * transfer is enabled after SIN goes to the marking state for at least two RCLK
+ * samples and then receives the next valid start bit.
+ * This constant defined a defined break length returned by the US_GetLineState
+ * function.
+ */
+
+#define MINIMAL_BREAK_LENGTH (2)
+
+#define BREAK_HISR_PRIORITY     (2)
+#define BREAK_HISR_STACK_SIZE (512) /* Bytes. */
+
+/*
+ * These macros allow to read and write a UART register.
+ */
+
+#define READ_UART_REGISTER(UART,REG)                                  \
+            *((volatile SYS_UWORD8 *) ((UART)->base_address + (REG)))
+
+#define WRITE_UART_REGISTER(UART,REG,VALUE)                                     \
+            *((volatile SYS_UWORD8 *) ((UART)->base_address + (REG))) = (VALUE)
+
+#define RESET_BIT(UART,REG,BIT)    \
+			(WRITE_UART_REGISTER ( \
+			     UART, REG, READ_UART_REGISTER (UART, REG) & ~(1 << (BIT))))
+
+#define SET_BIT(UART,REG,BIT)      \
+			(WRITE_UART_REGISTER ( \
+			     UART, REG, READ_UART_REGISTER (UART, REG) | (1 << (BIT))))
+
+
+/*
+ * These macros allow to enable or disable the wake-up interrupt.
+ */
+
+#define ENABLE_WAKEUP_INTERRUPT(UART)   \
+	SET_BIT(UART, SCR, RX_CTS_WAKE_UP_ENABLE_BIT);
+
+#define DISABLE_WAKEUP_INTERRUPT(UART)   \
+	RESET_BIT(UART, SCR, RX_CTS_WAKE_UP_ENABLE_BIT);
+
+
+/*
+ * These macros allow to enable or disable the DSR interrupt.
+ */
+
+#define ENABLE_DSR_INTERRUPT(UART)   \
+	SET_BIT(UART, SCR, DSR_IT_BIT);
+
+#define DISABLE_DSR_INTERRUPT(UART)   \
+	RESET_BIT(UART, SCR, DSR_IT_BIT);
+
+
+/*
+ * The transmitter is disabled only when the application disables the driver.
+ * To disable the driver, the receiver and the transmitter are disabled by the
+ * application. The transmitter is disabled first to test if the driver is
+ * disabled.
+ */
+
+#define DRIVER_DISABLED(UART) ((UART)->tx_stopped_by_application)
+
+#define DISABLE_DRIVER(UART)                       \
+        {                                          \
+            (UART)->tx_stopped_by_application = 1; \
+            (UART)->rx_stopped_by_application = 1; \
+        }
+
+#define ENABLE_DRIVER(UART)                        \
+        {                                          \
+            (UART)->rx_stopped_by_application = 0; \
+            (UART)->tx_stopped_by_application = 0; \
+        }
+
+/*
+ * Low and high watermarks for the RX buffer. If it is enabled, the flow
+ * control is activated or deactivated according to these values.
+ * The high watermark value allows to copy an array filled with the RX FIFO
+ * into the RX buffer. 
+ */
+
+#define RX_LOW_WATERMARK(RX_BUFFER_SIZE)  (FIFO_SIZE)
+#define RX_HIGH_WATERMARK(RX_BUFFER_SIZE) ((RX_BUFFER_SIZE) - 2 * FIFO_SIZE)
+
+/* 
+ * This macro allows to know if the RX buffer is full. It must be called only
+ * from the RX HISR. If it is called from the application, the rx_in and 
+ * rx_fifo_in pointers may be updated if a RX interrupt occurs or if the 
+ * RX HISR is activated.
+ */
+
+#define RX_BUFFER_FULL(UART)                                          \
+            (((UART)->rx_in == (UART)->rx_out - 1) ||                 \
+             ((UART)->rx_in == (UART)->rx_out + (UART)->buffer_size))
+
+/*
+ * This macro allows to know if the TX buffer is empty.
+ */
+
+#define TX_BUFFER_EMPTY(UART)                                         \
+            ((UART)->tx_in == (UART)->tx_out)
+
+/*
+ * This macro is used to convert a time (unit: ms) into a number of TDMA.
+ * 1 TDMA = 4.6 ms (23/5).
+ */
+
+#define CONVERT_TIME_IN_TDMA(TIME) (((TIME) * 5) / 23)
+
+/*
+ * This structure describes an UART compatible with the UART 16750 and
+ * contains some fields to manage this UART.
+ */
+
+typedef struct s_uart {
+
+    SYS_UWORD32 base_address;
+
+    /*
+     * HISR executed from the RX/TX interrupt handler.
+     */
+     
+    NU_HISR rx_hisr_ctrl_block;
+    NU_HISR tx_hisr_ctrl_block;
+    NU_HISR v24_hisr_ctrl_block;
+
+    char    rx_hisr_stack[RX_HISR_STACK_SIZE];
+    char    tx_hisr_stack[TX_HISR_STACK_SIZE];
+    char    v24_hisr_stack[V24_HISR_STACK_SIZE];
+    
+    /*
+     * 2 arrays are used to store bytes read in RX FIFO. A UART RX interrupt
+     * may occur while executing RX operations in RX HISR. To avoid overwriting
+     * the array in which received bytes are stored, a second array is used.
+     */
+     
+    SYS_UWORD8  *rx_buffer_used_by_rx_lisr;
+    SYS_UWORD8  *rx_buffer_used_by_rx_hisr;
+    SYS_UWORD8  rx_fifo_byte_1[FIFO_SIZE];
+    SYS_UWORD8  rx_fifo_byte_2[FIFO_SIZE];
+    SYS_UWORD16 bytes_in_rx_buffer_1;
+    SYS_UWORD16 bytes_in_rx_buffer_2;
+    
+    /*
+     * RX and TX buffers.
+     * One character is not used in each buffer to allow to know if the buffer
+     * is empty or not (See macro RX_BUFFER_FULL). If buffers are empty,
+     * rx_in = rx_out and tx_in = tx_out. It is impossible to use fields to
+     * count the number of bytes in each buffer because these fields may be
+     * updated from the application and from the interrupt handlers. That avoids
+     * to have conflicts.
+     */
+
+    SYS_UWORD16 buffer_size;
+    SYS_UWORD16 rx_threshold_level;
+    SYS_UWORD16 tx_threshold_level;
+    SYS_UWORD8  rx_buffer[FD_MAX_BUFFER_SIZE + 1];
+    SYS_UWORD8  tx_buffer[FD_MAX_BUFFER_SIZE + 1];
+    SYS_UWORD8  *rx_in;
+    SYS_UWORD8  *rx_out;
+    SYS_UWORD8  *tx_in;
+    SYS_UWORD8  *tx_out;
+
+    /*
+     * Escape sequence.
+     * the field esc_seq_modified may have 2 values:
+     *      - 0: No modification.
+     *      - 1: Parameters are in the process of modification: The detection
+     *           is stopped.
+     */
+
+    NU_TIMER      guard_period_timer_ctrl_block;
+    SYS_UWORD8    esc_seq_modified;
+    SYS_UWORD8    esc_seq_detection_state;
+    SYS_UWORD8    esc_seq_character;
+    UNSIGNED      guard_period;
+    UNSIGNED      current_time;
+    UNSIGNED      previous_time;
+
+    /*
+     * Flow control.
+     */
+
+    T_flowCtrlMode     flow_control_mode;
+    SYS_BOOL           send_xon_xoff;
+    SYS_UWORD8         xon_xoff_to_send;
+    SYS_UWORD8         xon_character;
+    SYS_UWORD8         xoff_character;
+    SYS_BOOL           rx_stopped_by_application;
+    SYS_BOOL           rx_stopped_by_driver;
+    SYS_BOOL           rx_stopped_by_lisr;
+    SYS_BOOL           tx_stopped_by_application;
+    SYS_BOOL           tx_stopped_by_driver;
+    /* SYS_BOOL           tx_stopped_by_lisr;*/
+
+    /*
+     * Break.
+     */
+
+    SYS_BOOL     break_received;
+    SYS_BOOL     break_to_send;
+    SYS_BOOL     break_in_progress;
+    NU_HISR      break_hisr_ctrl_block;
+    char         break_hisr_stack[BREAK_HISR_STACK_SIZE];
+    NU_TIMER     break_timer_ctrl_block;
+    UNSIGNED     baudrate;
+    UNSIGNED     autobauding;	
+    UNSIGNED     bits_per_char; /* Including start, stop and parity bits. */
+    UNSIGNED     break_length;  /* In bytes. */
+    UNSIGNED     time_without_character;
+
+    /*
+     * Callback (UAF_ReadData and UAF_WriteData).
+     * rd: read, wr: write.
+     */
+
+    SYS_BOOL   esc_seq_received;
+    SYS_UWORD8 rts_level; /* RTS on RS232 side, CTS on chipset side.
+                             1: The RS232 line is deactivated (low). */
+
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (CHIPSET == 12))
+    SYS_UWORD8 dtr_level; /* Controlled with an I/O on C & D-Sample and
+                             handled by Calypso+ on E-Sample.
+                             1: The RS232 line is deactivated (low). */
+    /*
+     * When the DTR interrupt is detected the user's Rx callback function must
+     * be called but if the Rx FIFO is not empty the Rx HISR must be activated
+     * to read the bytes received in the Rx FIFO and to put them into the Rx
+     * buffer before to call the user's Rx callback function.
+     * If the Rx HISR is activated due to a Rx interrupt the user's Rx callback
+     * function will be called if conditions to call it are fulfilled. If it is
+     * activated due to the DTR interrupt the user's Rx callback function must
+     * be called without any conditions.
+     * Because the Rx HISR may have been activated but not executed before the
+     * DTR interrupt we must be sure that the user's Rx callback function will
+     * be called for each Rx HISR activation. Call is done for Rx HISR activated
+     * on Rx interrupt if conditions are fulfilled.
+     * A circular buffer of 2 elements is used to memorize the source of
+     * interrupt. Before the activation of the Rx HISR, the source of interrupt
+     * is memorized into this array. When the code of the Rx HISR is executed
+     * the user's Rx callback function is called if the source of interrupt was
+     * the DTR interrupt regardless of the other conditions.
+     * The level of DTR is saved to provide the level detected on Rx interrupt
+     * or DTR interrupt in the 'state' parameter of the user's Rx callback
+     * function.
+     */                             
+
+    SYS_BOOL   dtr_change_detected[2];
+    SYS_UWORD8 dtr_level_saved[2];
+    SYS_UWORD8 index_it;
+    SYS_UWORD8 index_hisr;
+#endif /* BOARD 8 or 9 or 40 or 41 or CHIPSET 12 */                            
+    
+    SYS_BOOL         reading_suspended;
+    SYS_BOOL         writing_suspended;
+    SYS_BOOL         rd_call_from_hisr_in_progress;
+    SYS_BOOL         wr_call_from_hisr_in_progress;
+    T_reInstMode     rd_call_setup;
+    T_reInstMode     wr_call_setup;
+    SYS_UWORD8       *rd_address[2];
+    SYS_UWORD8       *wr_address[2];
+    SYS_UWORD16      rd_size_before_call[2];
+    SYS_UWORD16      rd_size_after_call[2];
+    SYS_UWORD16      wr_size_before_call[2];
+    SYS_UWORD16      wr_size_after_call[2];
+
+    void (*readOutFunc) (SYS_BOOL cldFromIrq,
+                         T_reInstMode *reInstall,
+                         SYS_UWORD8 nsource,
+                         SYS_UWORD8 *source[],
+                         SYS_UWORD16 size[],
+                         SYS_UWORD32 state);
+
+    void (*writeInFunc) (SYS_BOOL cldFromIrq,
+                         T_reInstMode *reInstall,
+                         SYS_UWORD8 ndest,
+                         SYS_UWORD8 *dest[],
+                         SYS_UWORD16 size[]);
+
+    /*
+     * These fields are used to store the state defined in UAF_GetLineState.The
+     * first field is used when UAF_GetLineState and UAF_ReadData are not called.
+     * When one of these functions is called the second field is used. That
+     * avoids to lose events when UAF_GetLineState or UAF_ReadData resets the
+     * first field.
+     */
+
+    SYS_UWORD32 state_1;
+    SYS_UWORD32 state_2;
+    SYS_UWORD32 *state;
+
+    /*
+     * Errors counters.
+     */
+
+    SYS_UWORD32 framing_error;
+    SYS_UWORD32 parity_error;
+    SYS_UWORD32 overrun_error;
+    SYS_UWORD32 spurious_interrupts;
+
+    SYS_UWORD16 max_rx_fifo_level;
+
+} t_uart;
+
+
+static t_uart uart_parameters;
+
+
+static const SYS_UWORD32 base_address[NUMBER_OF_FD_UART] =
+{
+    MEM_UART_IRDA,
+    MEM_UART_MODEM
+    #if (CHIPSET == 12)
+      , MEM_UART_MODEM2
+    #endif
+};
+
+
+/*
+ * DLL (LSB) and DLH (MSB) registers values using the 13 MHz clock.
+ */
+
+static const SYS_UWORD8 dll[] =
+{
+      0, /*   Auto baud:               */
+     81, /*     75 baud.                */
+     40, /*    150 baud.                */
+    148, /*    300 baud.                */
+     74, /*    600 baud.                */
+    165, /*   1200 baud.                */
+     83, /*   2400 baud.                */
+    169, /*   4800 baud.                */
+    113, /*   7200 baud.                */
+     84, /*   9600 baud.                */
+     56, /*  14400 baud.                */
+     42, /*  19200 baud.                */
+     28, /*  28800 baud.                */
+     24, /*  33900 baud: not supported. */
+     21, /*  38400 baud.                */
+     14, /*  57600 baud.                */
+      7, /* 115200 baud.                */
+      0, /* 203125 baud: not supported. */
+      0, /* 406250 baud: not supported. */
+      0  /* 812500 baud: not supported. */
+};
+
+static const SYS_UWORD8 dlh[] = 
+{
+    0, /*   Auto baud:               */
+   42, /*     75 baud.                */
+   21, /*    150 baud.                */
+   10, /*    300 baud.                */
+    5, /*    600 baud.                */
+    2, /*   1200 baud.                */
+    1, /*   2400 baud.                */
+    0, /*   4800 baud.                */
+    0, /*   7200 baud.                */
+    0, /*   9600 baud.                */
+    0, /*  14400 baud.                */
+    0, /*  19200 baud.                */
+    0, /*  28800 baud.                */
+    0, /*  33900 baud: not supported. */
+    0, /*  38400 baud.                */
+    0, /*  57600 baud.                */
+    0, /* 115200 baud.                */
+    0, /* 203125 baud: not supported. */
+    0, /* 406250 baud: not supported. */
+    0  /* 812500 baud: not supported. */
+};
+
+static const UNSIGNED baudrate_value[] =
+{
+         1,
+        75,
+       150,
+       300,
+       600,
+      1200,
+      2400,
+      4800,
+      7200,
+      9600,
+     14400,
+     19200,
+     28800,
+         0, /* Not supported. */
+     38400,
+     57600,
+    115200,
+         0, /* Not supported. */
+         0, /* Not supported. */
+         0  /* Not supported. */
+};
+
+
+ 
+
+/*******************************************************************************
+ *
+ *                          get_bytes_in_rx_buffer
+ * 
+ * Purpose  : Gets the number of bytes in the RX buffer.
+ *
+ * Arguments: In : uart: Pointer on the UART structure.
+ *            Out: none
+ *
+ * Returns  : The number of bytes in the RX buffer.
+ *
+ ******************************************************************************/
+
+static SYS_UWORD16
+get_bytes_in_rx_buffer (t_uart *uart)
+{
+    SYS_UWORD16 bytes_in_rx_buffer;
+    volatile SYS_UWORD8 *rx_in;
+
+    rx_in = uart->rx_in;
+
+    if (uart->rx_out <= rx_in)
+        bytes_in_rx_buffer = (SYS_UWORD16) (rx_in - uart->rx_out);
+    else
+        bytes_in_rx_buffer =
+            (SYS_UWORD16) (rx_in - uart->rx_out + uart->buffer_size + 1);
+
+    return (bytes_in_rx_buffer);
+}
+
+/*******************************************************************************
+ *
+ *                          get_bytes_in_tx_buffer
+ * 
+ * Purpose  : Gets the number of bytes in the TX buffer.
+ *
+ * Arguments: In : uart: Pointer on the UART structure.
+ *            Out: none
+ *
+ * Returns  : The number of bytes in the TX buffer.
+ *
+ ******************************************************************************/
+
+static SYS_UWORD16
+get_bytes_in_tx_buffer (t_uart *uart)
+{
+    SYS_UWORD16 bytes_in_tx_buffer;
+    volatile SYS_UWORD8 *tx_out;
+
+    tx_out = uart->tx_out;
+
+    if (tx_out <= uart->tx_in)
+        bytes_in_tx_buffer = (SYS_UWORD16) (uart->tx_in - tx_out);
+    else
+        bytes_in_tx_buffer =
+            (SYS_UWORD16) (uart->tx_in - tx_out + uart->buffer_size + 1);
+
+    return (bytes_in_tx_buffer);
+}
+
+/*******************************************************************************
+ *
+ *                              compute_break_time
+ * 
+ * Purpose  : Computes a number of TDMA from 3 parameters:
+ *              - baudrate,
+ *              - bits per character including start bit, stop bits and parity,
+ *              - number of characters.
+ *            Due to the TDMA value (4.6 ms), a minimal value is sent: 2 TDMA.
+ *
+ * Arguments: In : baudrate
+ *                 bits_per_char
+ *                 number_of_chars
+ *            Out: none
+ *
+ * Returns  : The number of TDMA.
+ *
+ ******************************************************************************/
+
+static UNSIGNED
+compute_break_time (UNSIGNED baudrate,
+                    UNSIGNED bits_per_char,
+                    UNSIGNED number_of_chars)
+{
+    UNSIGNED number_of_tdma;
+
+    number_of_tdma = CONVERT_TIME_IN_TDMA (
+                         1000 * bits_per_char * number_of_chars / baudrate);
+
+    if (number_of_tdma == 0)
+        number_of_tdma = 1;
+
+    number_of_tdma++;
+
+    return (number_of_tdma);
+}
+
+/*******************************************************************************
+ *
+ *                          update_reading_callback
+ * 
+ * Purpose  : Updates the sizes array and the addresses array and get and builds
+ *            the state parameter defined in UAF_GetLineState to call the
+ *            readOutFunc function.
+ *
+ * Arguments: In : uart       : Pointer on the UART structure.
+ *                 call_source: 0: application, 1: HISR (Rx or V24), 3: Rx HISR
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+static void
+update_reading_callback (t_uart *uart,
+                         SYS_BOOL call_source)
+{
+    SYS_UWORD32  state;
+    SYS_UWORD8  dtr_level;
+    SYS_UWORD8  fragments_number;
+    SYS_UWORD16 bytes_in_rx_buffer;
+    volatile SYS_UWORD8 *rx_in;
+
+    /*
+     * Update the sizes array and the addresses array.
+     * A copy of rx_in is used because it may be updated by the interrupt
+     * handler if this function is called from the application.
+     */
+
+    rx_in = uart->rx_in;
+    
+    if (uart->rx_out < rx_in) {
+
+        fragments_number = 1;
+
+        uart->rd_address[0] = uart->rx_out;
+        uart->rd_size_before_call[0] = (SYS_UWORD16) (rx_in - uart->rx_out);
+        uart->rd_size_after_call[0] = uart->rd_size_before_call[0];
+
+        uart->rd_size_before_call[1] = 0;
+        uart->rd_size_after_call[1] = 0;
+
+        bytes_in_rx_buffer = uart->rd_size_before_call[0];
+
+    } else if (rx_in == uart->rx_out) { /* RX buffer empty. */
+        
+        fragments_number = 1;
+
+        uart->rd_address[0] = uart->rx_out;
+        uart->rd_size_before_call[0] = 0;
+        uart->rd_size_after_call[0] = 0;
+
+        uart->rd_size_before_call[1] = 0;
+        uart->rd_size_after_call[1] = 0;
+
+        bytes_in_rx_buffer = 0;
+                    
+    } else {
+    
+        fragments_number = 2;
+
+        uart->rd_address[0] = uart->rx_out;
+        uart->rd_size_before_call[0] =
+            uart->buffer_size + 1 - (SYS_UWORD16) (uart->rx_out -
+                                               &(uart->rx_buffer[0]));
+        uart->rd_size_after_call[0] = uart->rd_size_before_call[0];
+
+        uart->rd_address[1] = &(uart->rx_buffer[0]);
+        uart->rd_size_before_call[1] = (SYS_UWORD16) (rx_in -
+                                                  &(uart->rx_buffer[0]));
+        uart->rd_size_after_call[1] = uart->rd_size_before_call[1];
+
+        bytes_in_rx_buffer =
+            uart->rd_size_before_call[0] + uart->rd_size_before_call[1];
+
+        if (!uart->rd_size_before_call[1])
+            fragments_number = 1;
+    }
+
+    /*
+     * Build the state parameter defined in UAF_GetLineState.
+     * The field state_2 is used when state_1 is set to 0 to avoid to
+     * lose events detected in the RX interrupt handler.
+     */
+
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (CHIPSET == 12))
+    if (call_source == 3) /* Call from Rx HISR */
+        dtr_level = uart->dtr_level_saved[uart->index_hisr];
+    else
+        dtr_level = uart->dtr_level;
+#endif
+
+    state = uart->state_2;
+    uart->state_2 = 0;
+    uart->state = &(uart->state_2);
+
+    state |= uart->state_1;
+    uart->state_1 = 0;
+    uart->state = &(uart->state_1);
+
+    state |= ((((SYS_UWORD32) uart->rts_level) << RTS) |
+
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (CHIPSET == 12))
+              (((SYS_UWORD32) dtr_level) << DTR) |
+#endif
+
+              (((SYS_UWORD32) (uart->tx_stopped_by_application  |
+                         uart->tx_stopped_by_driver)) << TXSTP) |
+
+              (((SYS_UWORD32) (uart->rx_stopped_by_application  |
+                         uart->rx_stopped_by_driver)) << RXSTP) |
+
+              (((SYS_UWORD32) (uart->buffer_size - bytes_in_rx_buffer)) << RXBLEV));
+
+    /*
+     * Fields SA, SB and X are set according to the flow control:
+     *
+     *       None    RTS/CTS    XON/XOFF
+     * SA    DTR     DTR        DTR
+     * SB    RTS     0          RTS
+     * X     0       RTS        XON:0 XOFF:1 (transmitter)
+     *
+     * DTR is supported on C, D & E-Sample.
+     */
+
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (CHIPSET == 12))
+    state |= (((SYS_UWORD32) uart->dtr_level) << SA);
+#endif
+
+    if (uart->flow_control_mode != fc_rts)
+        state |= (((SYS_UWORD32) uart->rts_level) << SB);
+
+    if (uart->flow_control_mode == fc_rts)
+        state |= (((SYS_UWORD32) uart->rts_level) << X);
+            
+    else if ((uart->flow_control_mode == fc_xoff) &&
+             (uart->tx_stopped_by_application ||
+              uart->tx_stopped_by_driver))
+        state |= (1 << X);
+
+    /*
+     * Call the readOutFunc function with these parameters.
+     */
+
+    uart->rd_call_setup = rm_notDefined;
+
+    (*(uart->readOutFunc)) (call_source & 0x01, /* From HISR or application */
+                            &(uart->rd_call_setup),
+                            fragments_number,
+                            &(uart->rd_address[0]),
+                            &(uart->rd_size_after_call[0]),
+                            state);
+}
+
+/*******************************************************************************
+ *
+ *                          update_writing_callback
+ * 
+ * Purpose  : Updates the sizes array and the addresses array to call the
+ *            writeInFunc function.
+ *
+ * Arguments: In : uart      : Pointer on the UART structure.
+ *                 call_source: 0: application, 1: HISR
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+static void
+update_writing_callback (t_uart *uart,
+                         SYS_BOOL call_source)
+{
+    SYS_UWORD8 fragments_number;
+    volatile SYS_UWORD8 *tx_out;
+
+    /*
+     * Update the array of sizes and the array of addresses.
+     * A copy of tx_out is used because it may be updated by the interrupt
+     * handler if this function is called from the application.
+     */
+
+    tx_out = uart->tx_out;
+    
+    if (uart->tx_in < tx_out) {
+
+        fragments_number = 1;
+
+        uart->wr_address[0] = uart->tx_in;
+        uart->wr_size_before_call[0] =
+            (SYS_UWORD16) (tx_out - uart->tx_in - 1);
+        uart->wr_size_after_call[0] = uart->wr_size_before_call[0];
+
+        uart->wr_size_before_call[1] = 0;
+        uart->wr_size_after_call[1] = 0;
+                                    
+    } else if (tx_out == &(uart->tx_buffer[0])) {
+
+        fragments_number = 1;
+        
+        uart->wr_address[0] = uart->tx_in;
+        uart->wr_size_before_call[0] =
+            uart->buffer_size - 
+            (SYS_UWORD16) (uart->tx_in - &(uart->tx_buffer[0]));
+        uart->wr_size_after_call[0] = uart->wr_size_before_call[0];
+
+        uart->wr_size_before_call[1] = 0;
+        uart->wr_size_after_call[1] = 0;
+
+    } else {
+    
+        fragments_number = 2;
+
+        uart->wr_address[0] = uart->tx_in;
+        uart->wr_size_before_call[0] =
+            uart->buffer_size + 1 - 
+            (SYS_UWORD16) (uart->tx_in - &(uart->tx_buffer[0]));
+        uart->wr_size_after_call[0] = uart->wr_size_before_call[0];
+
+        uart->wr_address[1] = &(uart->tx_buffer[0]);
+        uart->wr_size_before_call[1] =
+            (SYS_UWORD16) (tx_out - &(uart->tx_buffer[0]) - 1);
+        uart->wr_size_after_call[1] = uart->wr_size_before_call[1];
+
+        if (!uart->wr_size_before_call[1])
+            fragments_number = 1;
+    }
+
+    /*
+     * Call the writeInFunc function with these parameters;
+     */
+
+    uart->wr_call_setup = rm_notDefined;
+
+    (*(uart->writeInFunc)) (call_source,
+                            &(uart->wr_call_setup),
+                            fragments_number,
+                            &(uart->wr_address[0]),
+                            &(uart->wr_size_after_call[0]));
+}
+
+/*******************************************************************************
+ *
+ *                                  stop_break
+ * 
+ * Purpose  : The timer is activated to expire when a time corresponding to the
+ *            sending time of 2 characters at least has elapsed. After a break,
+ *            no character may be sent during this period.
+ *
+ * Arguments: In : id: parameter not used.
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+static VOID
+stop_break (UNSIGNED id)
+{
+    t_uart *uart;
+
+    uart = &uart_parameters;
+
+    uart->break_to_send = 0;
+    uart->break_in_progress = 0;
+
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+    /*
+     * Disable sleep mode.
+     */
+          
+    WRITE_UART_REGISTER (
+        uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
+#endif
+
+    /*
+     * Unmask Tx interrupt.
+     */
+
+    WRITE_UART_REGISTER (
+        uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);
+}
+
+/*******************************************************************************
+ *
+ *                          hisr_start_break
+ * 
+ * Purpose  : Enables the timer used to control the time without character.
+ *
+ * Arguments: In : none
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+static VOID
+hisr_start_break (VOID)
+{
+    t_uart *uart;
+
+    uart = &uart_parameters;
+
+    (void) NU_Control_Timer (&(uart->break_timer_ctrl_block),
+                             NU_DISABLE_TIMER);
+
+    (void) NU_Reset_Timer (&(uart->break_timer_ctrl_block),
+                           stop_break,
+                           uart->time_without_character,
+                           0, /* The timer expires once. */
+                           NU_DISABLE_TIMER);
+
+    (void) NU_Control_Timer (&(uart->break_timer_ctrl_block),
+                             NU_ENABLE_TIMER);
+}
+
+/*******************************************************************************
+ *
+ *                              stop_receiver
+ * 
+ * Purpose  : Activates DTR or RTS or sends XOFF. 
+ *
+ * Arguments: In : uart: Pointer on the UART structure.
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+static void
+stop_receiver (t_uart *uart)
+{
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+    /*
+     * Disable sleep mode.
+     */
+          
+    WRITE_UART_REGISTER (
+        uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
+#endif
+
+    switch (uart->flow_control_mode) {
+
+    case fc_rts:
+
+        /*
+         * CTS (RTS on UART side) is deactivated (high).
+         */
+
+        WRITE_UART_REGISTER (
+            uart, MCR, READ_UART_REGISTER (uart, MCR) & ~MRTS);
+        break;
+
+    case fc_xoff:
+
+        uart->xon_xoff_to_send = uart->xoff_character;
+        uart->send_xon_xoff = 1;
+
+        /*
+         * Unmask Tx interrupt.
+         */
+          
+        WRITE_UART_REGISTER (
+            uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);
+        break;
+    }
+}
+
+/*******************************************************************************
+ *
+ *                              start_receiver
+ * 
+ * Purpose  : Deactivates DTR or RTS or sends XON.
+ *
+ * Arguments: In : uart: Pointer on the UART structure.
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+static void
+start_receiver (t_uart *uart)
+{
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+    /*
+     * Disable sleep mode.
+     */
+          
+    WRITE_UART_REGISTER (
+        uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
+#endif
+
+    switch (uart->flow_control_mode) {
+
+    case fc_rts:
+
+        /*
+         * CTS (RTS on UART side) is activated (low).
+         */
+
+        WRITE_UART_REGISTER (
+            uart, MCR, READ_UART_REGISTER (uart, MCR) | MRTS);
+        break;
+
+    case fc_xoff:
+
+        uart->xon_xoff_to_send = uart->xon_character;
+        uart->send_xon_xoff = 1;
+
+        /*
+         * Unmask Tx interrupt.
+         */
+          
+        WRITE_UART_REGISTER (
+            uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);
+        break;
+    }
+}
+
+/*******************************************************************************
+ *
+ *                          add_esc_seq_char_in_rx_buffer
+ * 
+ * Purpose  : Writes one escape sequence character in the RX buffer.
+ *
+ * Arguments: In : uart: Pointer on the UART structure.
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+static void
+add_esc_seq_char_in_rx_buffer (t_uart *uart)
+{
+    /*
+     * IF the RX buffer is not full, write an escape sequence character in the
+     * RX buffer and check wrap-around.
+     */
+
+    if (!RX_BUFFER_FULL (uart)) {
+
+        *(uart->rx_in++) = uart->esc_seq_character;
+
+        if (uart->rx_in == &(uart->rx_buffer[0]) + uart->buffer_size + 1)
+            uart->rx_in = &(uart->rx_buffer[0]);
+    }
+}
+
+/*******************************************************************************
+ *
+ *                      analyze_guard_period_timer_expiration
+ * 
+ * Purpose  : According to the state of the escape sequence detection, 1 or 2
+ *            escape sequence characters may be written into the TX buffer or
+ *            the escape sequence is declared as detected.
+ *            If 1 or 2 escape sequence characters have been detected the
+ *            guard period must not expire.
+ *            If 3 characters have been detected the escape sequence must
+ *            expire.
+ *
+ * Arguments: In : id: parameter not used.
+ *            Out: none
+ *
+ * Returns  : none 
+ *
+ ******************************************************************************/
+
+static VOID
+analyze_guard_period_timer_expiration (UNSIGNED id)
+{
+    t_uart *uart;
+    SYS_UWORD16 bytes_in_rx_buffer;
+
+    uart = &uart_parameters;
+
+    switch (uart->esc_seq_detection_state) {
+    
+    case ONE_CHAR_DETECTED:
+    
+        /*
+         * 1 escape sequence character has been detected. The guard period has
+         * ellapsed. This character is written into the TX buffer.
+         */
+        
+        add_esc_seq_char_in_rx_buffer (uart);
+        break;
+        
+    case TWO_CHARS_DETECTED:
+    
+        /*
+         * 2 escape sequence characters have been detected. The guard period has
+         * ellapsed. These characters are written into the TX buffer.
+         */
+        
+        add_esc_seq_char_in_rx_buffer (uart);
+        add_esc_seq_char_in_rx_buffer (uart);
+
+        break;
+        
+    case THREE_CHARS_DETECTED:
+
+        /*
+         * 3 escape sequence characters have been detected and the guard period
+         * has ellapsed. The escape sequence is detected.
+         */    
+         
+        uart->esc_seq_received = 1;
+        *(uart->state) |= (1 << ESC);
+        
+        break;
+    }
+    
+    uart->esc_seq_detection_state = NO_ESCAPE_SEQUENCE;
+    
+    /*
+     * If the high watermark is reached, RTS is activated or XOFF is sent
+     * according to the flow control mode.
+     */
+
+    bytes_in_rx_buffer = get_bytes_in_rx_buffer (uart);
+
+    if ((uart->flow_control_mode != fc_none) &&
+        (bytes_in_rx_buffer >= RX_HIGH_WATERMARK (uart->buffer_size))) {
+
+        /*
+         * Check if receipt must be stopped.
+         */
+
+        if (!uart->rx_stopped_by_driver) {
+
+            uart->rx_stopped_by_driver = 1;
+            if (!uart->rx_stopped_by_application)
+                stop_receiver (uart);
+        }
+    }
+
+    /*
+     * If a reading was suspended or if the callback function is installed,
+     * it is called if one of these conditions is fulfiled:
+     *      - the RX threshold level is reached,
+     *      - a break has been detected,
+     *      - an escape sequence has been detected,
+     */
+
+    if ((!uart->rd_call_from_hisr_in_progress) &&
+        (uart->reading_suspended ||
+         (uart->rd_call_setup == rm_reInstall))) {
+
+        if ((bytes_in_rx_buffer >= uart->rx_threshold_level) ||
+            uart->break_received ||
+            uart->esc_seq_received) {
+
+            uart->rd_call_from_hisr_in_progress = 1;
+            update_reading_callback (uart, 1); /* 1: call from HISR. */
+
+            uart->reading_suspended = 0;
+            uart->break_received = 0;
+            uart->esc_seq_received = 0;
+        }
+    }
+}
+
+/*******************************************************************************
+ *
+ *                          stop_guard_period_timer
+ * 
+ * Purpose  : Stops the timer used to detect the guard period expiration.
+ *
+ * Arguments: In : uart: Pointer on the UART structure.
+ *            Out: none
+ *
+ * Returns  : none 
+ *
+ ******************************************************************************/
+
+static void
+stop_guard_period_timer (t_uart *uart)
+{
+    (void) NU_Control_Timer (&(uart->guard_period_timer_ctrl_block),
+                             NU_DISABLE_TIMER);
+}
+
+/*******************************************************************************
+ *
+ *                          start_guard_period_timer
+ * 
+ * Purpose  : Starts a timer which expires if the guard period has ellapsed.
+ *
+ * Arguments: In : uart: Pointer on the UART structure.
+ *            Out: none
+ *
+ * Returns  : none 
+ *
+ ******************************************************************************/
+
+static void
+start_guard_period_timer (t_uart *uart)
+{
+    (void) NU_Control_Timer (&(uart->guard_period_timer_ctrl_block),
+                             NU_DISABLE_TIMER);
+
+    (void) NU_Reset_Timer (&(uart->guard_period_timer_ctrl_block),
+                           analyze_guard_period_timer_expiration,
+                           uart->guard_period,
+                           0, /* The timer expires once. */
+                           NU_DISABLE_TIMER);
+
+    (void) NU_Control_Timer (&(uart->guard_period_timer_ctrl_block),
+                             NU_ENABLE_TIMER);
+}
+
+/*******************************************************************************
+ *
+ *                          detect_escape_sequence
+ * 
+ * Purpose  : The state machine used to detect an escape sequence is updated
+ *            according to the array of bytes to analyse. If the state machine
+ *            goes to the initial state due to a break in the sequence
+ *            detection, the previous characters are put into the RX buffer.
+ *
+ * Arguments: In : uart: Pointer on the UART structure.
+ *            Out: none
+ *
+ * Returns  : 0: Break in detection or a sequence has been detected. 
+ *            1: A sequence may be detected.
+ *
+ ******************************************************************************/
+
+static int
+detect_escape_sequence (t_uart *uart)
+{
+    int      detection_result;
+    SYS_UWORD8    *rx_fifo_byte;
+    SYS_UWORD16   bytes_in_rx_buffer;
+    UNSIGNED elapsed_time;
+
+    detection_result = 0;
+
+    rx_fifo_byte = uart->rx_buffer_used_by_rx_hisr;
+    if (rx_fifo_byte == &(uart->rx_fifo_byte_1[0]))
+        bytes_in_rx_buffer = uart->bytes_in_rx_buffer_1;
+    else
+        bytes_in_rx_buffer = uart->bytes_in_rx_buffer_2;
+
+    if (uart->current_time > uart->previous_time)
+        elapsed_time = uart->current_time - uart->previous_time;
+    else
+        elapsed_time =
+            MAX_UNSIGNED_32 - uart->previous_time + uart->current_time;
+
+    switch (uart->esc_seq_detection_state) {
+
+    case INITIALIZATION:
+
+        /*
+         * It is the first character received. It may be the first character
+         * of an escape sequence. The elapsed_time variable is set to the
+         * guard period value to consider this character as the first character
+         * of an escape sequence.
+         */
+
+        if (!uart->esc_seq_modified) {
+
+            elapsed_time = uart->guard_period;
+            uart->esc_seq_detection_state = NO_ESCAPE_SEQUENCE;
+        }
+
+        /* No break! */
+
+    case NO_ESCAPE_SEQUENCE:
+
+        /*
+         * To go to the next state (one, two or three characters detected):
+         *      - a guard period must have elapsed since the last receipt,
+         *      - the characters must belong to the escape sequence.
+         */
+
+        if ((elapsed_time >= uart->guard_period) &&
+            (!uart->esc_seq_modified)) {
+
+            switch (bytes_in_rx_buffer) {
+
+            case 1:
+
+                if (*rx_fifo_byte++ == uart->esc_seq_character) {
+                
+                    uart->esc_seq_detection_state = ONE_CHAR_DETECTED;
+                    start_guard_period_timer (uart);
+                    detection_result = 1;
+                }
+
+                break;
+
+            case 2:
+
+                if ((*rx_fifo_byte++ == uart->esc_seq_character) &&
+                    (*rx_fifo_byte++ == uart->esc_seq_character)) {
+                    
+                    uart->esc_seq_detection_state = TWO_CHARS_DETECTED;
+                    start_guard_period_timer (uart);
+                    detection_result = 1;
+                }
+                                    
+                break;
+
+            case 3:
+
+                if ((*rx_fifo_byte++ == uart->esc_seq_character) &&
+                    (*rx_fifo_byte++ == uart->esc_seq_character) &&
+                    (*rx_fifo_byte++ == uart->esc_seq_character)) {
+                        
+                    uart->esc_seq_detection_state = THREE_CHARS_DETECTED;
+                    start_guard_period_timer (uart);
+                    detection_result = 1;
+                }
+                    
+                break;
+
+            default:
+            
+                /*
+                 * No action.
+                 */
+
+                break;
+            }
+        }
+
+        uart->previous_time = uart->current_time;
+
+        break;
+
+    case ONE_CHAR_DETECTED:
+
+        /*
+         * To go to the next state (two or three characters detected):
+         *      - the difference between the current time and the previous time
+         *        must be less than the guard period,
+         *      - the characters must belong to the escape sequence.
+         * Otherwise, an escape sequence character is written in the RX buffer.
+         */
+
+        if (!uart->esc_seq_modified) {
+
+            switch (bytes_in_rx_buffer) {
+
+            case 1:
+
+                if (*rx_fifo_byte++ == uart->esc_seq_character) {
+                
+                    uart->esc_seq_detection_state = TWO_CHARS_DETECTED;
+                    detection_result = 1;                
+                }
+
+                break;
+
+            case 2:
+
+                if ((*rx_fifo_byte++ == uart->esc_seq_character) &&
+                    (*rx_fifo_byte++ == uart->esc_seq_character)) {
+                
+                    start_guard_period_timer (uart); /* Reset the timer. */
+                       
+                    uart->esc_seq_detection_state = THREE_CHARS_DETECTED;
+                    detection_result = 1;                    
+                }
+                    
+                break;
+
+            default:
+
+                /*
+                 * No action.
+                 */
+
+                break;
+            }
+        }
+
+        if (!detection_result) {
+
+            add_esc_seq_char_in_rx_buffer (uart);
+
+            uart->previous_time = uart->current_time;
+            uart->esc_seq_detection_state = NO_ESCAPE_SEQUENCE;
+        }
+
+        break;
+
+    case TWO_CHARS_DETECTED:
+
+        /*
+         * To go to the next state (three chars detected):
+         *      - the difference between the current time and the previous time
+         *        must be less than the guard period,
+         *      - the character must belong to the escape sequence.
+         * Otherwise, 2 escape sequence characters are written in the RX buffer.
+         */
+
+        if (!uart->esc_seq_modified) {
+
+            switch (bytes_in_rx_buffer) {
+
+            case 1:
+
+                if (*rx_fifo_byte++ == uart->esc_seq_character) {
+
+                    start_guard_period_timer (uart); /* Reset the timer. */
+                    
+                    uart->esc_seq_detection_state = THREE_CHARS_DETECTED;
+                    detection_result = 1;
+                }
+                
+                break;
+
+            default:
+
+                /*
+                 * No action.
+                 */
+
+                break;
+            }
+        }
+
+        if (!detection_result) {
+
+            add_esc_seq_char_in_rx_buffer (uart);
+            add_esc_seq_char_in_rx_buffer (uart);
+
+            uart->previous_time = uart->current_time;
+            uart->esc_seq_detection_state = NO_ESCAPE_SEQUENCE;
+        }
+
+        break;
+
+    case THREE_CHARS_DETECTED:
+
+        /*
+         * An escape sequence is detected if a guard period has elapsed since
+         * the last receipt. Otherwise, 3 escape sequence characters are
+         * written in the RX buffer.
+         */
+
+        stop_guard_period_timer (uart);
+
+        add_esc_seq_char_in_rx_buffer (uart);
+        add_esc_seq_char_in_rx_buffer (uart);
+        add_esc_seq_char_in_rx_buffer (uart);
+
+        uart->previous_time = uart->current_time;
+        uart->esc_seq_detection_state = NO_ESCAPE_SEQUENCE;
+
+        break;
+    }
+
+    return (detection_result);
+}
+
+/*******************************************************************************
+ *
+ *                              send_break
+ * 
+ * Purpose  : This function may only called if the TX FIFO is empty.
+ *            Null characters are written in the TX FIFO. The number of bytes to
+ *            write has been defined with UAF_SetLineState. Enables the break
+ *            condition.
+ *
+ * Arguments: In : uart: Pointer on the UART structure.
+ *            Out: none
+ *
+ * Returns  : Number of bytes sent.
+ *
+ ******************************************************************************/
+
+static SYS_UWORD16
+send_break (t_uart *uart)
+{
+    SYS_UWORD16 bytes_in_tx_fifo;
+
+    bytes_in_tx_fifo = 0;
+    uart->break_in_progress = 1;
+
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+    /*
+     * Disable sleep mode.
+     */
+
+    WRITE_UART_REGISTER (
+        uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
+#endif
+
+    WRITE_UART_REGISTER (
+        uart, LCR, READ_UART_REGISTER (uart, LCR) | BREAK_CONTROL);
+      
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+    /*
+     * Re-enable sleep mode.
+     */
+
+/* BELOW LINES WERE COMMENTED TO DISABLE SLEEP MODE IN DRIVER */
+/*
+    WRITE_UART_REGISTER (
+        uart, IER, READ_UART_REGISTER (uart, IER) | IER_SLEEP);
+
+        */
+#endif
+
+    while (uart->break_length) {
+
+        WRITE_UART_REGISTER (uart, THR, 0x00);
+        uart->break_length--;
+        bytes_in_tx_fifo++;
+    }
+
+    return (bytes_in_tx_fifo);
+}
+
+/*******************************************************************************
+ *
+ *                              build_rx_fifo_array
+ * 
+ * Purpose  : Reads the RX FIFO to build an array with bytes read.
+ *            A byte is written in this array if no error is detected. 
+ *
+ * Arguments: In : uart: Pointer on the UART structure.
+ *            Out: none
+ *
+ * Returns  : The number of bytes in RX FIFO.
+ *
+ ******************************************************************************/
+
+static SYS_UWORD16
+build_rx_fifo_array (t_uart *uart)
+{
+    SYS_UWORD8  status;
+    SYS_UWORD8  *first_byte;
+    SYS_UWORD8  *current_byte;
+    SYS_UWORD16 *bytes_in_rx_buffer;
+    SYS_UWORD16 bytes_received;
+    SYS_UWORD8 cbyte;
+
+    volatile int x;
+
+    x = 1;
+
+    bytes_received = 0;
+    
+    
+    /*
+     * Switch to the other buffer.
+     */
+     
+    first_byte = uart->rx_buffer_used_by_rx_lisr;
+    if (first_byte == &(uart->rx_fifo_byte_1[0])) {
+    
+        first_byte = &(uart->rx_fifo_byte_2[0]);
+        bytes_in_rx_buffer = &(uart->bytes_in_rx_buffer_2);
+    
+    } else {
+    
+        first_byte = &(uart->rx_fifo_byte_1[0]);
+        bytes_in_rx_buffer = &(uart->bytes_in_rx_buffer_1);
+    }
+
+    current_byte = first_byte;
+
+    if (*bytes_in_rx_buffer) {
+ 
+
+    	/* The Rx buffer is not empty and is being used by HISR ! */
+    	/* Hence stop the flow control */
+	stop_receiver (uart); 
+
+     /*
+       * Reset LCR[7] (DLAB) to have access to the RBR, THR and IER registers.
+       */
+       WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) & ~DLAB);
+     
+       /* Mask The Rx  and interrupt */
+       
+       WRITE_UART_REGISTER (
+            uart, IER, READ_UART_REGISTER (uart, IER) &
+                       ~(ERBI | EDSSI));
+       
+       uart->rx_stopped_by_lisr = 1;
+      	return (bytes_received);
+      	
+      	}
+
+    uart->rx_buffer_used_by_rx_lisr = first_byte;
+    
+    status = READ_UART_REGISTER (uart, LSR);
+
+    /*
+     * Build an array with the bytes contained in the RX FIFO.
+     */
+
+    while (status & DR) { /* While RX FIFO is not empty... */
+
+        *current_byte = READ_UART_REGISTER (uart, RHR);
+
+        /*
+         * Check if a parity error or a framing error is associated with the
+         * received data. If there is an error the byte is not copied into the
+         * bytes array.
+         */
+
+        if (status & BYTE_ERROR) {
+
+            if (status & OE)
+                uart->overrun_error++;
+
+            if (status & PE)
+                uart->parity_error++;
+
+            if (status & FE)
+                uart->framing_error++;
+
+            /*
+             * Check break detection.
+             */
+
+            if (status & BI) {
+            
+                uart->break_received = 1;
+                *(uart->state) |=
+                    ((1 << BRK) | (MINIMAL_BREAK_LENGTH << BRKLEN));
+            }
+
+        } else /* No error */ 
+            current_byte++;
+
+        status = READ_UART_REGISTER (uart, LSR);
+    }
+
+    bytes_received = (SYS_UWORD16) (current_byte - first_byte);
+    *bytes_in_rx_buffer = bytes_received;
+
+    /*
+     * Re-switch to the other buffer if no valid character has been received.
+     */
+
+    if (!bytes_received) {
+         
+        if (uart->rx_buffer_used_by_rx_lisr == &(uart->rx_fifo_byte_1[0]))
+            uart->rx_buffer_used_by_rx_lisr = &(uart->rx_fifo_byte_2[0]);
+        
+        else
+            uart->rx_buffer_used_by_rx_lisr = &(uart->rx_fifo_byte_1[0]);
+    }
+
+    if (bytes_received > uart->max_rx_fifo_level)
+        uart->max_rx_fifo_level = bytes_received;
+        
+    return (bytes_received);
+}
+
+/*******************************************************************************
+ *
+ *                              empty_rx_fifo
+ * 
+ * Purpose  : Read the RX FIFO.
+ *
+ * Arguments: In : uart: Pointer on the UART structure.
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+static void
+empty_rx_fifo (t_uart *uart)
+{
+    SYS_UWORD16 bytes_in_rx_fifo;
+    volatile SYS_UWORD8 dummy_byte;
+
+    bytes_in_rx_fifo = 0;
+
+    while (READ_UART_REGISTER (uart, LSR) & DR) {
+
+        dummy_byte = READ_UART_REGISTER (uart, RHR);
+        bytes_in_rx_fifo++;
+    }
+
+    if (bytes_in_rx_fifo > uart->max_rx_fifo_level)
+        uart->max_rx_fifo_level = bytes_in_rx_fifo;
+}
+
+/*******************************************************************************
+ *
+ *                          hisr_execute_rx_operations
+ * 
+ * Purpose  : If an escape sequence is detected or if a break in the detection
+ *            has occured RX FIFO bytes are written in the RX buffer. 
+ *            If the software flow control is used bytes are analyzed to know
+ *            if a XON or a XOFF character is received to stop or start the
+ *            transmitter. 
+ *            If a flow control is used and if the high watermark of the RX
+ *            buffer is reached the receiver is stopped.
+ *            If the RX threshold level is reached the callback mechanism is
+ *            activated.
+ *
+ * Arguments: In : none
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+static VOID
+hisr_execute_rx_operations (VOID)
+{
+    SYS_UWORD16 bytes_free_in_rx_buffer;
+    SYS_UWORD16 wrap_around_counter;
+    SYS_UWORD16 bytes_in_rx_buffer;
+    SYS_UWORD16 bytes_read;
+    SYS_UWORD16 bytes_to_copy;
+    SYS_UWORD8  *current_byte;
+    SYS_UWORD8  xon_xoff_detected;
+    t_uart *uart;
+
+    uart = &uart_parameters;
+    
+    /*
+     * Since new characters have been received, the sleep timer is reset then
+     * restarted preventing the system to enter deep-sleep for a new period of
+     * time.
+     */
+
+    SER_restart_uart_sleep_timer ();
+    uart_sleep_timer_enabled = 1;
+
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (CHIPSET == 12))
+    uart->index_hisr = (uart->index_hisr + 1) & 0x01; /* 0 or 1 */
+#endif
+
+    xon_xoff_detected = 0;
+    
+    /*
+     * Switch to the other buffer.
+     */
+     
+    current_byte = uart->rx_buffer_used_by_rx_hisr;
+    if (current_byte == &(uart->rx_fifo_byte_1[0])) {
+    
+        current_byte = &(uart->rx_fifo_byte_2[0]);
+        bytes_read = uart->bytes_in_rx_buffer_2;
+    
+    } else {
+    
+        current_byte = &(uart->rx_fifo_byte_1[0]);
+        bytes_read = uart->bytes_in_rx_buffer_1;
+    }
+
+    uart->rx_buffer_used_by_rx_hisr = current_byte;
+
+    /*
+     * All bytes are copied into the RX buffer only if an escape sequence has
+     * been detected or a break in the detection has occured.
+     */
+
+    if (!detect_escape_sequence (uart)) {
+
+        if (uart->rx_out > uart->rx_in)
+            bytes_free_in_rx_buffer = (SYS_UWORD16) (uart->rx_out - uart->rx_in - 1);
+        else
+            bytes_free_in_rx_buffer =
+                (SYS_UWORD16) (uart->buffer_size + uart->rx_out - uart->rx_in);
+
+        wrap_around_counter = uart->buffer_size + 1 -
+                              (SYS_UWORD16) (uart->rx_in - &(uart->rx_buffer[0]));
+        
+        if (uart->flow_control_mode == fc_xoff) {
+        
+            /*
+             * For SW Flow Control, need to further investigate the processing
+             * in order to improve the performance of the driver, and in order
+             * to avoid managing the wrap around of the circular buffer each
+             * time a character is copied.
+             */
+        
+            while (bytes_read && bytes_free_in_rx_buffer) {
+
+                /*
+                 * If the data received is XON or XOFF, the transmitter is
+                 * enabled (XON) or disabled (XOFF).
+                 */
+
+                if (*current_byte == uart->xoff_character) {
+
+                    uart->tx_stopped_by_driver = 1;
+                    xon_xoff_detected = 1;
+
+                } else if (*current_byte == uart->xon_character) {
+
+                    uart->tx_stopped_by_driver = 0;
+                    xon_xoff_detected = 1;
+
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+                    /*
+                     * Disable sleep mode.
+                     */
+          
+                    WRITE_UART_REGISTER (
+                        uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
+#endif
+
+                    /*
+                     * Unmask Tx interrupt.
+                     */
+          
+                    WRITE_UART_REGISTER (
+                        uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);
+
+                } else {
+    
+                    *(uart->rx_in++) = *current_byte;
+
+                    wrap_around_counter--;
+                    if (!wrap_around_counter) {
+                    
+                        uart->rx_in = &(uart->rx_buffer[0]);
+                        wrap_around_counter = uart->buffer_size + 1;
+                    }
+                    
+                    bytes_free_in_rx_buffer--;
+                }
+
+                current_byte++;
+                bytes_read--;
+            }
+        } else { /* No Flow Control or HW Flow Control */
+                
+            /*
+             * Figure out the most restricting condition.
+             */
+
+            bytes_to_copy =
+                Min3 (bytes_free_in_rx_buffer, wrap_around_counter, bytes_read);
+                          
+            /*
+             * Copy characters into the circular Rx buffer.
+             */
+        
+            memcpy (uart->rx_in, current_byte, bytes_to_copy);
+
+            /*
+             * Update first the variables associated to blocking conditions:
+             * if (bytes_read = 0) OR
+             *    (bytes_free_in_rx_buffer = 0) => No more characters to copy.
+             */
+                
+            bytes_free_in_rx_buffer	-= bytes_to_copy;
+            bytes_read -= bytes_to_copy;
+                
+            wrap_around_counter -= bytes_to_copy;
+            if (!wrap_around_counter)
+                    uart->rx_in = &(uart->rx_buffer[0]);
+            else
+                uart->rx_in += bytes_to_copy;
+
+            /*
+             * Check if there are still some characters to copy.
+             */
+
+            if (bytes_read && bytes_free_in_rx_buffer) {
+
+                /*
+                 * Update the remaining variables and figure out again the
+                 * most restricting condition. Since (bytes_read = 0) and
+                 * (bytes_free_in_rx_buffer = 0) are blocking conditions, if
+                 * we reach that point it means that the wrap around condition
+                 * has just occurred and it is not needed to manage it again.
+                 */
+
+                current_byte += bytes_to_copy;
+                bytes_to_copy = Min (bytes_read, bytes_free_in_rx_buffer);
+
+                /*
+                 * Copy characters into the circular Rx buffer and update
+                 * current pointer.
+                 */
+
+                memcpy (uart->rx_in, current_byte, bytes_to_copy);
+
+                uart->rx_in += bytes_to_copy;
+                
+                /*
+                 * bytes_free_in_rx_buffer not updated since not used anymore.
+                 */
+                   bytes_read -= bytes_to_copy;
+              
+            }
+            else {
+            	     bytes_read = 0;
+            }
+        } /* end if (uart->flow_control_mode == fc_xoff) */
+
+
+        /*
+         * If the high watermark is reached, RTS is activated or XOFF is
+         * sent according to the flow control mode.
+         */
+
+        bytes_in_rx_buffer = get_bytes_in_rx_buffer (uart);
+
+        if ((uart->flow_control_mode != fc_none) &&
+            (bytes_in_rx_buffer >= RX_HIGH_WATERMARK (uart->buffer_size))) {
+
+            /*
+             * Check if receipt must be stopped.
+             */
+
+            if (!uart->rx_stopped_by_driver) {
+
+                uart->rx_stopped_by_driver = 1;
+                if (!uart->rx_stopped_by_application)
+                    stop_receiver (uart);
+            }
+        }
+
+        /*
+         * If a reading was suspended or if the callback function is installed,
+         * it is called if one of these conditions is fulfiled:
+         *      - the RX threshold level is reached,
+         *      - a break has been detected,
+         */
+
+        if ((!uart->rd_call_from_hisr_in_progress) &&
+            (uart->reading_suspended ||
+             (uart->rd_call_setup == rm_reInstall))) {
+
+            if ((bytes_in_rx_buffer >= uart->rx_threshold_level) ||
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (CHIPSET == 12))
+                uart->dtr_change_detected[uart->index_hisr] ||
+#endif
+                uart->break_received ||
+                xon_xoff_detected) {
+
+
+                uart->rd_call_from_hisr_in_progress = 1;
+                update_reading_callback (uart, 3); /* 3: call from Rx HISR. */
+
+                uart->reading_suspended = 0;
+                uart->break_received = 0;
+                uart->esc_seq_received = 0;
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (CHIPSET == 12))
+                uart->dtr_change_detected[uart->index_hisr] = 0;
+#endif
+            }
+        }
+
+    }
+
+
+
+    WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) & ~DLAB);
+              
+    /* Mask The Rx and Modem status interrupt */
+    WRITE_UART_REGISTER (
+               uart, IER, READ_UART_REGISTER (uart, IER) &
+                       ~(ERBI | EDSSI));
+              
+       if ((uart->rx_buffer_used_by_rx_hisr) == &(uart->rx_fifo_byte_1[0])) {
+       	 
+  	      	 uart->bytes_in_rx_buffer_1 = 0;
+           	 
+    	    } else {
+    	                
+               uart->bytes_in_rx_buffer_2 = 0;
+        }
+
+       
+       WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) & ~DLAB);
+              
+        /* Unmask The Rx and Modem status interrupt*/
+       WRITE_UART_REGISTER (
+               uart, IER, READ_UART_REGISTER (uart, IER) |
+                       (ERBI | EDSSI));
+
+        if(uart->rx_stopped_by_lisr  ) {
+       	if (!uart->rx_stopped_by_driver) {
+   		 
+
+              uart->rx_stopped_by_lisr = 0;
+        
+              /*
+                * Reset LCR[7] (DLAB) to have access to the RBR, THR and IER registers.
+                */
+              WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) & ~DLAB);
+         
+
+              /* UnMask The Rx interrupt */
+              WRITE_UART_REGISTER (
+               uart, IER, READ_UART_REGISTER (uart, IER) |
+                       (ERBI | EDSSI));
+             
+              start_receiver (uart);
+             
+       	}
+    }
+
+}
+
+/*******************************************************************************
+ *
+ *                          hisr_execute_v24_operations
+ * 
+ * Purpose  : The user's function is called if all conditions to call it are
+ *            fulfiled.
+ *
+ * Arguments: In : none
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+static VOID
+hisr_execute_v24_operations (VOID)
+{
+    t_uart *uart;
+
+    uart = &uart_parameters;
+
+    /*
+     * If a reading was suspended or if the callback function is installed,
+     * it is called.
+     */
+
+    if ((!DRIVER_DISABLED (uart)) &&
+        (!uart->rd_call_from_hisr_in_progress) &&
+        (uart->reading_suspended || (uart->rd_call_setup == rm_reInstall))) {
+
+        uart->rd_call_from_hisr_in_progress = 1;
+        update_reading_callback (uart, 1); /* 1: call from HISR. */
+        uart->reading_suspended = 0;
+        uart->break_received = 0;
+        uart->esc_seq_received = 0;
+    }
+
+}
+
+/*******************************************************************************
+ *
+ *                          hisr_execute_tx_operations
+ * 
+ * Purpose  : Writes bytes from the TX buffer to the TX FIFO.
+ *            The user's function is called if all conditions to call it are
+ *            fulfiled.
+ *
+ * Arguments: In : none
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+static VOID
+hisr_execute_tx_operations (VOID)
+{
+    SYS_UWORD16 bytes_in_tx_buffer;
+    SYS_UWORD16 bytes_in_tx_fifo;
+    SYS_UWORD16 wrap_around_counter;
+    SYS_UWORD16 bytes_to_write;
+    t_uart *uart;
+    int counter;
+
+
+    uart = &uart_parameters;
+
+    /*
+     * A TX interrupt may have occured during the previous TX HISR. This case
+     * may appear when a HISR having a higher priority has been activated when
+     * the TX HISR was activated. When the next TX HISR is activated, the TX
+     * FIFO may not be empty. Nothing is done until a TX interrupt will occur.
+     * The RX HISR will be activated again and the TX FIFO will be empty.
+     */
+
+    if (READ_UART_REGISTER (uart, LSR) & THRE) {
+
+        bytes_in_tx_fifo = 0;
+    
+        /*
+         * A request to send a XON/XOFF character may have been done by the 
+         * RX interrupt handler. The byte can be written because we are sure
+         * that the TX FIFO is not full.
+         */
+
+        if (uart->send_xon_xoff) {
+
+            WRITE_UART_REGISTER (uart, THR, uart->xon_xoff_to_send);
+            uart->send_xon_xoff = 0;
+            bytes_in_tx_fifo++;
+        }
+
+        if ((!uart->tx_stopped_by_application) &&
+            (!uart->tx_stopped_by_driver)) {
+
+            bytes_in_tx_buffer = get_bytes_in_tx_buffer (uart);
+            wrap_around_counter =
+                uart->buffer_size + 1 - (SYS_UWORD16) (uart->tx_out -
+                                                  &(uart->tx_buffer[0]));
+
+            /*
+             * Figure out the most restricting condition.
+             */
+
+#if ((CHIPSET == 3) || (CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6))
+            /*
+             * Loading of only (FIFO_SIZE - 1) characters in the Tx FIFO to
+             * avoid the generation of a spurious Tx FIFO almost empty
+             * interrupt (Ulysse bug report #35).
+             */
+
+            bytes_to_write =
+                Min3 (bytes_in_tx_buffer, wrap_around_counter,
+                      (FIFO_SIZE - 1 - bytes_in_tx_fifo));
+#elif ((CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12))
+            /*
+             * Bug corrected on Calypso rev. A, rev. B, C035, Ulysse C035,
+             * Calypso Lite & Calypso+.
+             */
+
+            bytes_to_write =
+                Min3 (bytes_in_tx_buffer, wrap_around_counter,
+                (FIFO_SIZE - bytes_in_tx_fifo));
+#endif
+
+            /*
+             * Write characters into the Tx FIFO.
+             */
+
+            for (counter = 0; counter < bytes_to_write; counter++)
+                WRITE_UART_REGISTER (uart, THR, *(uart->tx_out++));
+
+            /*
+             * Update the variables associated to blocking conditions:
+             * if (bytes_in_tx_buffer = 0) OR
+             *    (bytes_in_tx_fifo = FIFO_SIZE) => No more characters to copy.
+             */
+
+            bytes_in_tx_buffer -= bytes_to_write;
+            bytes_in_tx_fifo += bytes_to_write;
+
+            wrap_around_counter -= bytes_to_write;
+            if (!wrap_around_counter)
+                uart->tx_out = &(uart->tx_buffer[0]);
+
+            /*
+             * Check if there are still some characters to write.
+             */
+
+            if (bytes_in_tx_buffer &&
+#if ((CHIPSET == 3) || (CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6))
+                (bytes_in_tx_fifo < (FIFO_SIZE - 1))) {
+#elif ((CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12))
+                (bytes_in_tx_fifo < FIFO_SIZE)) {
+#endif
+
+                /*
+                 * Figure out again the most restricting condition. Since
+                 * (bytes_in_tx_buffer = 0) and	(bytes_in_tx_fifo = FIFO_SIZE)
+                 * are blocking conditions, if we reach that point it means
+                 * that the wrap around condition has just occurred and it is
+                 * not needed to manage it again.
+                 */
+
+#if ((CHIPSET == 3) || (CHIPSET == 4) || (CHIPSET == 5) || (CHIPSET == 6))
+                bytes_to_write =
+                    Min (bytes_in_tx_buffer,
+                         (FIFO_SIZE - 1 - bytes_in_tx_fifo));
+#elif ((CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 9) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12))
+                bytes_to_write =
+                    Min (bytes_in_tx_buffer,
+                         (FIFO_SIZE - bytes_in_tx_fifo));
+#endif
+
+                /*
+                 * Write characters into the Tx FIFO and update associated
+                 * variables.
+                 */
+
+                for (counter = 0; counter < bytes_to_write; counter++)
+                    WRITE_UART_REGISTER (uart, THR, *(uart->tx_out++));
+
+                bytes_in_tx_buffer += bytes_to_write;
+                bytes_in_tx_fifo += bytes_to_write;
+            }
+
+            /*
+             * If a writing was suspended or if the callback function is
+             * installed, it is called if the TX threshold level is reached.
+             */
+
+            if ((!DRIVER_DISABLED (uart)) &&
+                (!uart->wr_call_from_hisr_in_progress) &&
+                (bytes_in_tx_buffer <= uart->tx_threshold_level) &&
+                ((uart->wr_call_setup == rm_reInstall) ||
+                 uart->writing_suspended)) {
+
+                uart->writing_suspended = 0;
+
+                uart->wr_call_from_hisr_in_progress = 1;
+                update_writing_callback (uart, 1); /* 1: call from HISR. */
+            }
+        } /* end if ((!uart->tx_stopped_by_application) && */
+          /*         (!uart->tx_stopped_by_driver))        */
+
+        if (bytes_in_tx_fifo)
+
+            /*
+             * Unmask Tx interrupt.
+             */
+          
+            WRITE_UART_REGISTER (
+                uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);
+
+        else {
+
+            if ((!bytes_in_tx_fifo) && (uart->break_to_send))
+                bytes_in_tx_fifo = send_break (uart);
+        }
+
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+        /*
+         * Re-enable the sleep mode.
+         */
+
+/* BELOW LINES WERE COMMENTED TO DISABLE SLEEP MODE IN DRIVER */
+/*
+        WRITE_UART_REGISTER (
+            uart, IER, READ_UART_REGISTER (uart, IER) | IER_SLEEP);
+
+            */
+#endif
+    }
+}
+
+/*******************************************************************************
+ *
+ *                              read_rx_fifo
+ * 
+ * Purpose  : Reads the RX FIFO. If the driver is enabled bytes are written in
+ *            an array to be analyzed by the RX HISR.
+ *
+ * Arguments: In : uart: Pointer on the UART structure.
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+static void
+read_rx_fifo (t_uart *uart)
+{
+
+    /*
+     * If the driver is disabled the RX FIFO is read to acknoledge the
+     * interrupt else bytes received are written into an array which will be
+     * analyzed from the RX HISR.
+     */
+     
+    if (DRIVER_DISABLED (uart))
+        empty_rx_fifo (uart);
+
+    else if (build_rx_fifo_array (uart)){
+        (void) NU_Activate_HISR (&(uart->rx_hisr_ctrl_block));
+        
+    	}
+    
+
+}
+
+/*******************************************************************************
+ *
+ *                          check_v24_input_lines
+ * 
+ * Purpose  : Check the V.24 input lines. According to the states of the input
+ *            lines and to the flow control mode selected, the transmitter is
+ *            enabled or disabled. The reading callback function is called if
+ *            it is installed and if all conditions are fulfiled.
+ *
+ * Arguments: In : uart: Pointer on the UART structure.
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+static void
+check_v24_input_lines (t_uart *uart)
+{
+    SYS_BOOL v24_input_line_changed;
+    volatile SYS_UWORD8 modem_status;
+
+    modem_status = READ_UART_REGISTER (uart, MSR);
+    v24_input_line_changed = 0;
+
+    if (modem_status & DELTA_CTS) {
+
+        v24_input_line_changed = 1;
+
+        if (modem_status & MCTS)
+            uart->rts_level = 0;
+        else
+            uart->rts_level = 1;
+    }
+
+#if (CHIPSET == 12)
+    else if (modem_status & DELTA_DSR) {
+	 v24_input_line_changed = 1;
+
+        if (modem_status & MDSR)
+        {
+            uart->dtr_level = 0;
+	     if (uart->flow_control_mode != fc_dtr  && uart->baudrate == baudrate_value[FD_BAUD_AUTO])
+            UAF_SetComPar (UAF_UART_1, FD_BAUD_AUTO, bpc_8, sb_1, pa_none); /* switch back to autobaud */
+        }
+        else
+            uart->dtr_level = 1;
+
+        /*
+         * The reading callback function has to be called. But bytes received before
+         * the change of state of DTR must be copied into the RX buffer before to
+         * call it.
+         */
+         
+        if (READ_UART_REGISTER (uart, LSR) & DR) { /* If Rx FIFO is not empty */
+    
+            /*
+             * The Rx FIFO will be read to fill one of the two buffers and the Rx
+             * HISR will be activated.
+             */
+           
+            uart->index_it = (uart->index_it + 1) & 0x01; /* 0 or 1 */
+            uart->dtr_change_detected[uart->index_it] = 1;
+            uart->dtr_level_saved[uart->index_it] = uart->dtr_level;
+            read_rx_fifo (uart);
+            
+        } else
+            v24_input_line_changed = 1;
+    }
+#endif
+
+    /*
+     * When the hardware flow control is selected, if the RS 232 input signal is
+     * deactivated (low), the transmitter is stopped.
+     */
+
+    if (uart->flow_control_mode == fc_rts) {
+        
+        if (uart->rts_level) {
+            uart->tx_stopped_by_driver = 1;
+        }    
+
+        else {
+            
+            uart->tx_stopped_by_driver = 0;
+            LowGPIO(1);
+
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+            /*
+             * Disable sleep mode.
+             */
+          
+            WRITE_UART_REGISTER (
+                uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
+#endif
+
+            /*
+             * Unmask Tx interrupt.
+             */
+
+            WRITE_UART_REGISTER (
+                uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);
+
+        }
+    }
+
+    if (v24_input_line_changed)
+        (void) NU_Activate_HISR (&(uart->v24_hisr_ctrl_block));
+}
+
+/*******************************************************************************
+ *
+ *                              fill_tx_fifo
+ * 
+ * Purpose  : If the TX buffer is not empty, and if there is no break in
+ *            progress, bytes are written into the TX FIFO until the TX FIFO is
+ *            full or the TX buffer is empty. Else, if there is a break to send
+ *            an all 0s character is written into the TX FIFO and a break is
+ *            declared in progress to avoid to fill the TX FIFO on the next
+ *            interrupt.
+ *            When the TX FIFO is empty and if a break is in progress, the break
+ *            length is programmed: all 0s characters are written into the TX
+ *            FIFO. The number of bytes has been defined previously with the
+ *            UAF_SetLineState function. The break condition is enabled.
+ *            When the TX FIFO and the transmitter shift register (TSR) are both
+ *            empty and if a break is in progress, the break condition is 
+ *            disabled.
+ *            When bytes are written from the TX buffer to the TX FIFO, the
+ *            writing callback function is called if it is installed and if all
+ *            conditions are fulfiled.
+ *
+ * Arguments: In : uart: Pointer on the UART structure.
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+static void
+fill_tx_fifo (t_uart *uart)
+{
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+    /*
+     * Disable sleep mode.
+     */
+
+    WRITE_UART_REGISTER (
+        uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
+#endif
+
+    /*
+     * Mask Tx interrupt.
+     */
+
+    WRITE_UART_REGISTER (
+        uart, IER, READ_UART_REGISTER (uart, IER) & ~ETBEI);
+
+    /*
+     * If a break is in progress, bytes of the TX buffer are not written into
+     * the TX FIFO.
+     */
+
+    if (!uart->break_in_progress)
+        (void) NU_Activate_HISR (&(uart->tx_hisr_ctrl_block));    
+
+    else {
+
+        /*
+         * The break HISR is activated and the break condition is cleared.
+         */
+
+        WRITE_UART_REGISTER (
+            uart, LCR, READ_UART_REGISTER (uart, LCR) & ~BREAK_CONTROL);
+
+        (void) NU_Activate_HISR (&(uart->break_hisr_ctrl_block));
+    }
+}
+
+/*******************************************************************************
+ *
+ *                                UAF_Init
+ * 
+ * Purpose  : Initializes the UART hardware and installs interrupt handlers.
+ *            The parameters are set to the default values:
+ *               - 19200 baud,
+ *               - 8 bits / character,
+ *               - no parity,
+ *               - 1 stop bit,
+ *               - no flow control.
+ *            All functionalities of the UART driver are disabled.
+ *
+ * Arguments: In : uartNo: Used UART.
+ *            Out: none
+ *
+ * Returns  : FD_OK           : Successful operation.
+ *            FD_NOT_SUPPORTED: Wrong UART number.
+ *            FD_INTERNAL_ERR : Internal problem.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_Init (T_fd_UartId uartNo)
+{
+    t_uart *uart;
+    volatile SYS_UWORD8 status;
+
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    uart = &uart_parameters;
+
+    /*
+     * Create the 3 HISR actived in the RX/TX and V24 interrupt handlers.
+     * A return is used to simplify the code if an error occurs.
+     * All stacks are entirely filled with the pattern 0xFE.
+     */
+     
+    memset (&(uart->rx_hisr_stack[0]), 0xFE, RX_HISR_STACK_SIZE);
+
+    if (NU_Create_HISR (&(uart->rx_hisr_ctrl_block),
+                        "UAF_Rx",
+                        hisr_execute_rx_operations,
+                        RX_HISR_PRIORITY,
+                        &(uart->rx_hisr_stack[0]),
+                        RX_HISR_STACK_SIZE) != NU_SUCCESS)
+
+        return (FD_INTERNAL_ERR);
+
+    memset (&(uart->tx_hisr_stack[0]), 0xFE, TX_HISR_STACK_SIZE);
+
+    if (NU_Create_HISR (&(uart->tx_hisr_ctrl_block),
+                        "UAF_Tx",
+                        hisr_execute_tx_operations,
+                        TX_HISR_PRIORITY,
+                        &(uart->tx_hisr_stack[0]),
+                        TX_HISR_STACK_SIZE) != NU_SUCCESS)
+
+        return (FD_INTERNAL_ERR);
+
+    memset (&(uart->v24_hisr_stack[0]), 0xFE, V24_HISR_STACK_SIZE);
+
+    if (NU_Create_HISR (&(uart->v24_hisr_ctrl_block),
+                        "UAF_V24",
+                        hisr_execute_v24_operations,
+                        V24_HISR_PRIORITY,
+                        &(uart->v24_hisr_stack[0]),
+                        V24_HISR_STACK_SIZE) != NU_SUCCESS)
+
+        return (FD_INTERNAL_ERR);
+
+    /*
+     * Create the HISR used to send a break.
+     * A return is used to simplify the code if an error occurs.
+     * The stack is entirely filled with the pattern 0xFE.
+     */
+
+    memset (&(uart->break_hisr_stack[0]), 0xFE, BREAK_HISR_STACK_SIZE);
+
+    if (NU_Create_HISR (&(uart->break_hisr_ctrl_block),
+                        "UAF_Brk",
+                        hisr_start_break,
+                        BREAK_HISR_PRIORITY,
+                        &(uart->break_hisr_stack[0]),
+                        BREAK_HISR_STACK_SIZE) != NU_SUCCESS)
+
+        return (FD_INTERNAL_ERR);
+
+    /*
+     * Create a timer used in the break HISR.
+     * A return is used to simplify the code if an error occurs.
+     */
+
+    if (NU_Create_Timer (&(uart->break_timer_ctrl_block),
+                         "Break",
+                         stop_break,
+                         0, /* Parameter supplied to the routine: not used. */
+                         0, /* This parameter is set when the timer is reset. */
+                         0, /* The timer expires once. */
+                         NU_DISABLE_TIMER) != NU_SUCCESS)
+
+        return (FD_INTERNAL_ERR);
+
+    /*
+     * Create a timer used in the detection of the escape sequence.
+     * A return is used to simplify the code if an error occurs.
+     */
+
+    if (NU_Create_Timer (&(uart->guard_period_timer_ctrl_block),
+                         "Esc seq",
+                         analyze_guard_period_timer_expiration,
+                         0, /* Parameter supplied to the routine: not used. */
+                         0, /* This parameter is set when the timer is reset. */
+                         0, /* The timer expires once. */
+                         NU_DISABLE_TIMER) != NU_SUCCESS)
+
+        return (FD_INTERNAL_ERR);
+
+    /*
+     * These data are used to send a break.
+     * A character has: 8 data bits + 1 start bit + 1 stop bit = 10 bits.
+     */
+
+    uart->baudrate = baudrate_value[FD_BAUD_19200];
+    uart->autobauding = 0;	
+    uart->bits_per_char = 10;
+
+    /*
+     * UART base address.
+     */
+
+    uart->base_address = base_address[uartNo];
+
+    /*
+     * Select the current array used to store received bytes.
+     */
+     
+    uart->rx_buffer_used_by_rx_lisr = &(uart->rx_fifo_byte_2[0]);
+    uart->rx_buffer_used_by_rx_hisr = &(uart->rx_fifo_byte_2[0]);
+    
+    /*
+     * RX and TX buffers.
+     */
+
+    uart->buffer_size        = FD_MAX_BUFFER_SIZE;
+    uart->rx_threshold_level = 1;
+    uart->tx_threshold_level = 0;
+    uart->rx_in              = &(uart->rx_buffer[0]);
+    uart->rx_out             = &(uart->rx_buffer[0]);
+    uart->tx_in              = &(uart->tx_buffer[0]);
+    uart->tx_out             = &(uart->tx_buffer[0]);
+
+    /*
+     * Escape sequence.
+     */
+
+    uart->esc_seq_modified        = 0;
+    uart->esc_seq_detection_state = INITIALIZATION;
+    uart->esc_seq_character       = DEFAULT_ESC_SEQ_CHARACTER;
+    uart->guard_period            = CONVERT_TIME_IN_TDMA (
+                                         DEFAULT_GUARD_PERIOD);
+
+    /*
+     * Flow control.
+     */
+
+    uart->flow_control_mode         = fc_none;
+    uart->send_xon_xoff             = 0;
+    uart->rx_stopped_by_application = 1;
+    uart->rx_stopped_by_driver      = 0;
+    uart->rx_stopped_by_lisr      = 0;
+    uart->tx_stopped_by_application = 1;
+    uart->tx_stopped_by_driver      = 0;
+
+    /*
+     * Break.
+     */
+
+    uart->break_received    = 0;
+    uart->break_to_send     = 0;
+    uart->break_in_progress = 0;
+
+    /*
+     * Callback (UAF_ReadData and UAF_WriteData).
+     */
+
+    uart->esc_seq_received  = 0;
+
+    uart->reading_suspended             = 0;
+    uart->writing_suspended             = 0;
+    uart->rd_call_from_hisr_in_progress = 0;
+    uart->wr_call_from_hisr_in_progress = 0;
+    uart->rd_call_setup                 = rm_noInstall;
+    uart->wr_call_setup                 = rm_noInstall;
+
+    /*
+     * State defined in UAF_GetLineState.
+     */
+
+    uart->state_1 = 0;
+    uart->state_2 = 0;
+    uart->state   = &(uart->state_1);
+
+    /*
+     * Errors counters.
+     */
+
+    uart->framing_error       = 0;
+    uart->parity_error        = 0;
+    uart->overrun_error       = 0;
+    uart->spurious_interrupts = 0;
+
+    uart->max_rx_fifo_level   = 0;
+
+    /*
+     * Mask all interrupts causes and disable sleep mode and low power mode.
+     */
+
+    WRITE_UART_REGISTER (uart, IER, 0x00);
+
+    /*
+     * Reset UART mode configuration.
+     */
+     
+    WRITE_UART_REGISTER (uart, MDR1, RESET_DEFAULT_STATE   |
+                                     IR_SLEEP_DISABLED     |
+                                     SIR_TX_WITHOUT_ACREG2 |
+                                     FRAME_LENGTH_METHOD);
+
+    /*
+     * FIFO configuration.
+     * EFR[4] = 1 to allow to program FCR[5:4] and MCR[7:5].
+     */
+     
+    WRITE_UART_REGISTER (uart, LCR, 0xBF);
+    SET_BIT (uart, EFR, ENHANCED_FEATURE_BIT);
+
+    /*
+     * Select the word length, the number of stop bits , the parity and set
+     * LCR[7] (DLAB) to allow to program FCR, DLL and DLM.
+     */
+
+    WRITE_UART_REGISTER (uart, LCR, WLS_8 | DLAB);
+
+    /*
+     * Program the trigger levels.
+     * MCR[6] must be set to 1.
+     */
+     
+    SET_BIT (uart, MCR, TCR_TLR_BIT);
+    WRITE_UART_REGISTER (uart, TCR, 0x0F);
+    WRITE_UART_REGISTER (uart, TLR, RX_FIFO_TRIGGER_LEVEL);
+    RESET_BIT (uart, MCR, TCR_TLR_BIT);
+
+    /*
+     * Force the generation of THR_IT on TX FIFO empty: SCR[3] = 1.
+     */
+
+    WRITE_UART_REGISTER (
+        uart, SCR, READ_UART_REGISTER (uart, SCR) | TX_EMPTY_CTL_IT);
+    
+    /*
+     * Program the FIFO control register. Bit 0 must be set when other FCR bits
+     * are written to or they are not programmed.
+     * FCR is a write-only register. It will not be modified.
+     */
+
+    WRITE_UART_REGISTER (uart, FCR, FIFO_ENABLE   |
+                                    RX_FIFO_RESET | /* self cleared */
+                                    TX_FIFO_RESET); /* self cleared */
+
+    /*
+     * Program the baud generator.
+     */
+
+    WRITE_UART_REGISTER (uart, DLL, dll[FD_BAUD_19200]);
+    WRITE_UART_REGISTER (uart, DLM, dlh[FD_BAUD_19200]);
+
+    /*
+     * Reset LCR[7] (DLAB) to have access to the RBR, THR and IER registers.
+     */
+
+    WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) & ~DLAB);
+
+    /*
+     * Select UART mode.
+     */
+     
+    WRITE_UART_REGISTER (uart, MDR1, UART_MODE             |
+                                     IR_SLEEP_DISABLED     |
+                                     SIR_TX_WITHOUT_ACREG2 |
+                                     FRAME_LENGTH_METHOD);
+
+    /*
+     * Read the state of RTS (RTS on RS232, CTS on chipset).
+     */
+
+    status = READ_UART_REGISTER (uart, MSR);
+
+    if (status & MCTS)
+        uart->rts_level = 0;
+    else
+        uart->rts_level = 1;
+
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41))
+    /*
+     * On C & D-Sample, 2 I/O are used to control DCD and DTR on UART Modem.
+     * DCD: I/O 2 (output)
+     * DTR: I/O 3 (input)
+     */
+     
+    #define EXTENDED_MCU_REG (0xFFFEF006) /* Extended MCU register       */
+    #define ASIC_CONFIG_REG  (0xFFFEF008) /* Asic Configuration register */
+
+    #define IO_DTR (10) /* I/O 3; bit 10 of Asic Configuration register */
+    #define IO_DCD ( 6) /* I/O 2; bit 6 of Extended MCU register        */
+
+    /*
+     * Select I/O for DCD and configure it as output.
+     * DCD should start HIGH (not asserted).
+     */
+
+    *((volatile SYS_UWORD16 *) EXTENDED_MCU_REG) &= ~(1 << IO_DCD);
+    AI_ConfigBitAsOutput (ARMIO_DCD);
+    AI_SetBit (ARMIO_DCD);
+
+    /*
+     * Select I/O for DTR and configure it as input.
+     * An interrupt is used to detect a change of state of DTR. Falling edge
+     * or rising edge is selected according to the state of DTR.
+     */
+    
+    *((volatile SYS_UWORD16 *) ASIC_CONFIG_REG) &= ~(1 << IO_DTR);
+    AI_ConfigBitAsInput (ARMIO_DTR);
+    uart->dtr_level = AI_ReadBit (ARMIO_DTR);
+
+    if (uart->dtr_level)
+        AI_SelectIOForIT (ARMIO_DTR, ARMIO_FALLING_EDGE);
+    else
+        AI_SelectIOForIT (ARMIO_DTR, ARMIO_RISING_EDGE);
+        
+    AI_UnmaskIT (ARMIO_MASKIT_GPIO);
+
+    /*
+     * Reset the 2 indexes of the circular buffer of 2 elements.
+     * The circular buffer does not need to be initialized.
+     */
+     
+    uart->index_it = 0;
+    uart->index_hisr = 0;
+#elif (CHIPSET == 12)
+    /*
+     * DCD and DTR are directly handled by Calypso+.
+     * Force DCD pin to HIGH
+     */
+
+    WRITE_UART_REGISTER (uart, MCR, READ_UART_REGISTER(uart, MCR) & ~MDCD);
+
+    /*
+     * Read the state of DTR (DTR on RS232, DSR on chipset).
+     */
+
+    status = READ_UART_REGISTER (uart, MSR);
+
+    if (status & MDSR)
+        uart->dtr_level = 0;
+    else
+        uart->dtr_level = 1;
+
+    /*
+     * Reset the 2 indexes of the circular buffer of 2 elements.
+     * The circular buffer does not need to be initialized.
+     */
+     
+    uart->index_it = 0;
+    uart->index_hisr = 0;
+#endif /* BOARD == 8, 9, 40 or 41, CHIPSET == 12 */
+    
+    /*
+     * Unmask RX interrupt and the modem status interrupt.
+     */
+
+    WRITE_UART_REGISTER (uart, IER, ERBI | EDSSI);
+
+#if (CHIPSET == 12)
+    /*
+     * Unmask DSR interrupt in order to detect a change of state of DTR.
+     */
+
+	ENABLE_DSR_INTERRUPT (uart);
+#endif
+
+    return (FD_OK);
+}
+
+/*******************************************************************************
+ *
+ *                               UAF_Enable
+ * 
+ * Purpose  : The functionalities of the UART driver are disabled or enabled.
+ *            In the deactivated state, all information about the communication
+ *            parameters should be stored and recalled if the driver is again
+ *            enabled. When the driver is enabled the RX and TX buffers are
+ *            cleared.
+ *
+ * Arguments: In : uartNo: Used UART.
+ *               : enable: 1: enable the driver
+ *                         0: disable the driver
+ *            Out: none
+ *
+ * Returns  : FD_OK           : Successful operation.
+ *            FD_NOT_SUPPORTED: Wrong UART number.
+ *            FD_INTERNAL_ERR : Internal problem with the hardware.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_Enable (T_fd_UartId uartNo,
+            SYS_BOOL enable)
+{
+    t_uart  *uart;
+
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    /*
+     * There is no case where FD_INTERNAL_ERR may be returned.
+     */
+     
+    uart = &uart_parameters;
+
+    if (enable) {
+
+        uart->rx_stopped_by_driver = 0;
+            
+        ENABLE_DRIVER (uart);
+        start_receiver (uart);
+
+    } else {
+
+        DISABLE_DRIVER (uart);
+        stop_receiver (uart);
+
+        uart->tx_in = &(uart->tx_buffer[0]);
+        uart->rx_in = &(uart->rx_buffer[0]);
+        uart->tx_out = uart->tx_in;
+        uart->rx_out = uart->rx_in;
+    }
+
+    return (FD_OK);
+}
+
+/*******************************************************************************
+ *
+ *                            UAF_SetComPar
+ * 
+ * Purpose  : Sets up the communication parameters: baud rate, bits per
+ *            character, number of stop bits, parity.
+ *
+ * Arguments: In : uartNo  : Used UART.
+ *                 baudrate: Used baud rate.
+ *                 bpc     : Used bits per character.
+ *                 sb      : Used stop bits.
+ *                 parity  : Used parity.
+ *            Out: none
+ *
+ * Returns  : FD_OK           : Successful operation.
+ *            FD_NOT_SUPPORTED: The specified parameters don't fit to the
+ *                              capabilities of the UART or wrong UART number.
+ *            FD_INTERNAL_ERR : Internal problem with the hardware.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_SetComPar (T_fd_UartId uartNo,
+               T_baudrate baudrate,
+               T_bitsPerCharacter bpc,
+               T_stopBits sb,
+               T_parity parity)
+{
+    t_uart *uart;
+    volatile SYS_UWORD8 mcr_value;
+    volatile SYS_UWORD8 status;
+
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    /*
+     * There is no case where FD_INTERNAL_ERR may be returned.
+     * pa_space is not supported. Some baudrates are not supported too.
+     * A return is used to simplify the code.
+     */
+
+    if ((!baudrate_value[baudrate]) ||
+        (parity == pa_space))
+
+        return (FD_NOT_SUPPORTED);
+
+    uart = &uart_parameters;
+
+    /*
+     * Mask all interrupts causes and disable sleep mode and low power mode.
+     */
+
+    WRITE_UART_REGISTER (uart, IER, 0x00);
+
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41))
+    AI_MaskIT (ARMIO_MASKIT_GPIO);
+#elif (CHIPSET == 12)
+    DISABLE_DSR_INTERRUPT (uart);
+#endif
+
+    /*
+     * Reset UART mode configuration.
+     */
+     
+    WRITE_UART_REGISTER (uart, MDR1, RESET_DEFAULT_STATE   |
+                                     IR_SLEEP_DISABLED     |
+                                     SIR_TX_WITHOUT_ACREG2 |
+                                     FRAME_LENGTH_METHOD);
+
+    /*
+     * FIFO configuration.
+     * EFR[4] = 1 to allow to program FCR[5:4] and MCR[7:5].
+     */
+     
+    WRITE_UART_REGISTER (uart, LCR, 0xBF);
+    SET_BIT (uart, EFR, ENHANCED_FEATURE_BIT);
+
+    /*
+     * Select the word length, the number of stop bits , the parity and set
+     * LCR[7] (DLAB) to allow to program FCR, DLL and DLM.
+     */
+
+    uart->baudrate = baudrate_value[baudrate];
+    uart->autobauding = (baudrate == FD_BAUD_AUTO);  /* if autobauding enable trigger */
+    uart->bits_per_char = 1; /* Start bit. */
+    mcr_value = DLAB;
+
+    if (bpc == bpc_7) {
+    
+        mcr_value |= WLS_7;
+        uart->bits_per_char += 7;
+
+    } else {
+
+        mcr_value |= WLS_8;
+        uart->bits_per_char += 8;
+    }
+
+    if (sb == sb_2) {
+
+        mcr_value |= STB;
+        uart->bits_per_char += 2;
+
+    } else
+        uart->bits_per_char += 1;
+
+    switch (parity) {
+
+    case pa_even:
+
+        mcr_value |= (PEN | EPS);
+        uart->bits_per_char += 1;
+
+        break;
+
+    case pa_odd:
+
+        mcr_value |= PEN;
+        uart->bits_per_char += 1;
+
+        break;
+
+    default:
+
+        /*
+         * There is nothing to do.
+         */
+
+        break;
+    }
+
+    WRITE_UART_REGISTER (uart, LCR, mcr_value);
+
+    /*
+     * Program the trigger levels.
+     * MCR[6] must be set to 1.
+     */
+     
+    SET_BIT (uart, MCR, TCR_TLR_BIT);
+    WRITE_UART_REGISTER (uart, TCR, 0x0F);
+    WRITE_UART_REGISTER (uart, TLR, RX_FIFO_TRIGGER_LEVEL);
+    RESET_BIT (uart, MCR, TCR_TLR_BIT);
+
+    /*
+     * Force the generation of THR_IT on TX FIFO empty: SCR[3] = 1.
+     */
+
+    WRITE_UART_REGISTER (
+        uart, SCR, READ_UART_REGISTER (uart, SCR) | TX_EMPTY_CTL_IT);
+    
+    /*
+     * Program the FIFO control register. Bit 0 must be set when other FCR bits
+     * are written to or they are not programmed.
+     * FCR is a write-only register. It will not be modified.
+     */
+
+    WRITE_UART_REGISTER (uart, FCR, FIFO_ENABLE   |
+                                    RX_FIFO_RESET | /* self cleared */
+                                    TX_FIFO_RESET); /* self cleared */
+
+    /*
+     * Program the baud generator.
+     */
+
+    WRITE_UART_REGISTER (uart, DLL, dll[baudrate]);
+    WRITE_UART_REGISTER (uart, DLM, dlh[baudrate]);
+
+    /*
+     * Reset LCR[7] (DLAB) to have access to the RBR, THR and IER registers.
+     */
+
+    WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) & ~DLAB);
+
+    /*
+     * Select UART mode.
+     */
+     
+    WRITE_UART_REGISTER (uart, MDR1,  ((baudrate==FD_BAUD_AUTO)?
+                                         UART_MODE_AUTOBAUDING:
+                                         UART_MODE)             |
+                                     IR_SLEEP_DISABLED     |
+                                     SIR_TX_WITHOUT_ACREG2 |
+                                     FRAME_LENGTH_METHOD);
+
+    /*
+     * Read the state of RTS (RTS on RS232, CTS on chipset).
+     */
+
+    status = READ_UART_REGISTER (uart, MSR);
+
+    if (status & MCTS)
+        uart->rts_level = 0;
+    else
+        uart->rts_level = 1;
+
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41))
+    /*
+     * Read the state of DTR and select the edge.
+     */
+         
+    uart->dtr_level = AI_ReadBit (ARMIO_DTR);
+    
+    if (uart->dtr_level)
+        AI_SelectIOForIT (ARMIO_DTR, ARMIO_FALLING_EDGE);
+    else
+        AI_SelectIOForIT (ARMIO_DTR, ARMIO_RISING_EDGE);
+        
+    AI_UnmaskIT (ARMIO_MASKIT_GPIO);
+#elif (CHIPSET == 12)
+    /*
+     * Read the state of DTR - No need to reload MSR register since its value
+     * is still stored in the "status" local variable.
+     */
+
+    if (status & MDSR)
+        uart->dtr_level = 0;
+    else
+        uart->dtr_level = 1;
+#endif
+
+#if ((CHIPSET == 5) || (CHIPSET == 6))
+    /*
+     * Unmask RX and TX interrupts and the modem status interrupt. 
+     */
+
+    WRITE_UART_REGISTER (uart, IER, ERBI | ETBEI | EDSSI);
+#elif (CHIPSET == 12)
+    /*
+     * Unmask RX and TX interrupts and the modem status interrupt... 
+     */
+
+    WRITE_UART_REGISTER (uart, IER, ERBI | ETBEI | EDSSI);
+
+    /*
+     * ... Then, unmask DSR interrupt...
+     */
+
+	ENABLE_DSR_INTERRUPT (uart);  
+
+    /*
+     * ... And finally allow sleep mode.
+     */
+
+   /* BELOW LINES WERE COMMENTED TO DISABLE SLEEP MODE IN DRIVER */
+    /*
+    WRITE_UART_REGISTER (uart, IER, READ_UART_REGISTER (uart, IER) | IER_SLEEP);
+    */
+#else
+    /*
+     * Unmask RX and TX interrupts and the modem status interrupt 
+     * and allow sleep mode.
+     */
+    /* BELOW LINES WERE COMMENTED TO DISABLE SLEEP MODE IN DRIVER */
+
+    /* WRITE_UART_REGISTER (uart, IER, ERBI | ETBEI | EDSSI | IER_SLEEP);*/
+
+    WRITE_UART_REGISTER (uart, IER, ERBI | ETBEI | EDSSI);
+#endif
+
+
+    return (FD_OK);
+}
+
+/*******************************************************************************
+ *
+ *                            UAF_SetBuffer
+ * 
+ * Purpose  : Sets up the size of the circular buffers to be used in the UART
+ *            driver. This function may be called only if the UART is disabled
+ *            with UAF_Enable.
+ *
+ * Arguments: In : uartNo     : Used UART.
+ *                 bufSize    : Specifies the size of the circular buffer.
+ *                 rxThreshold: Amount of received bytes that leads to a call
+ *                              to suspended read-out function which is passed
+ *                              to the function UAF_ReadData.
+ *                 txThreshold: Amount of bytes in the TX buffer to call the
+ *                              suspended write-in function which is passed to
+ *                              the function UAF_WriteData
+ *            Out: none
+ *
+ * Returns  : FD_OK           : Successful operation.
+ *            FD_NOT_SUPPORTED: bufSize exceeds the maximal possible
+ *                              capabilities of the driver or the threshold
+ *                              values don't correspond to the bufSize or
+ *                              wrong UART number.
+ *            FD_INTERNAL_ERR : Internal problem with the hardware or the
+ *                              function has been called while the UART is
+ *                              enabled.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_SetBuffer (T_fd_UartId uartNo,
+               SYS_UWORD16 bufSize,
+               SYS_UWORD16 rxThreshold,
+               SYS_UWORD16 txThreshold)
+{
+    T_FDRET result;
+    t_uart *uart;
+
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    if ((bufSize > FD_MAX_BUFFER_SIZE) ||
+        (rxThreshold > FD_MAX_BUFFER_SIZE) ||
+        (txThreshold > FD_MAX_BUFFER_SIZE))
+
+        result = FD_NOT_SUPPORTED;
+
+    else {
+    
+        uart = &uart_parameters;
+        
+        if (!DRIVER_DISABLED (uart))
+            result = FD_INTERNAL_ERR;
+
+        else if (RX_HIGH_WATERMARK (bufSize) < RX_LOW_WATERMARK (bufSize))
+            result = FD_NOT_SUPPORTED;
+
+        else {
+        
+            uart->buffer_size = bufSize;
+            uart->rx_threshold_level = rxThreshold;
+            uart->tx_threshold_level = txThreshold;
+
+            result = FD_OK;
+        }
+    }
+
+    return (result);
+}
+
+/*******************************************************************************
+ *
+ *                             UAF_SetFlowCtrl
+ * 
+ * Purpose  : Changes the flow control mode of the UART driver.
+ *            If a flow control is activated, DTR is activated or XOFF is sent
+ *            if the RX buffer is not able to store the received characters else
+ *            DTR is deactivated or XON is sent.
+ *
+ * Arguments: In : uartNo: Used UART.
+ *                 fcMode: flow control mode (none, DTR/DSR, RTS/CTS, XON/XOFF).
+ *                 XON   : ASCII code of the XON character.
+ *                 XOFF  : ASCII code of the XOFF character.
+ *            Out: none
+ *
+ * Returns  : FD_OK           : Successful operation.
+ *            FD_NOT_SUPPORTED: The flow control mode is not supported or wrong
+ *                              UART number.
+ *            FD_INTERNAL_ERR : Internal problem with the hardware.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_SetFlowCtrl (T_fd_UartId uartNo,
+                 T_flowCtrlMode fcMode,
+                 SYS_UWORD8 XON,
+                 SYS_UWORD8 XOFF)
+{
+    T_FDRET result;
+    t_uart  *uart;
+
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    /*
+     * There is no case where FD_INTERNAL_ERR may be returned.
+     * The DTR/DSR protocol is not supported.
+     */
+
+    if (fcMode == fc_dtr)
+        result = FD_NOT_SUPPORTED;
+
+    else {
+    
+        uart = &uart_parameters;
+
+        uart->tx_stopped_by_driver = 0;
+
+        
+        uart->xon_character = XON;
+        uart->xoff_character = XOFF;
+        uart->flow_control_mode = fcMode;
+
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+        /*
+         * Disable sleep mode.
+         */
+
+        WRITE_UART_REGISTER (
+            uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
+#endif
+
+        WRITE_UART_REGISTER (
+            uart, MCR, READ_UART_REGISTER (uart, MCR) | MRTS);
+          
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+        /*
+         * Re-enable sleep mode.
+         */
+         /* BELOW LINES WERE COMMENTED TO DISABLE SLEEP MODE IN DRIVER */
+         /*
+        WRITE_UART_REGISTER (
+            uart, IER, READ_UART_REGISTER (uart, IER) | IER_SLEEP);
+            */
+#endif
+        
+        if (fcMode == fc_rts) {
+#if 1 // Dmitriy: enable hardware assisted CTS 
+            volatile SYS_UWORD8 oldValue;
+
+            oldValue = READ_UART_REGISTER (uart, LCR);
+            
+            // LCR value to allow acces to EFR
+     
+            WRITE_UART_REGISTER (uart, LCR, 0xBF);
+            
+            // enable hardware assisted CTS
+            
+            SET_BIT (uart, EFR, AUTO_CTS_BIT);
+            
+            WRITE_UART_REGISTER (uart, LCR, oldValue);    
+#endif
+            if (uart->rts_level)
+                uart->tx_stopped_by_driver = 1;
+        }
+
+        /*
+         * If the high watermark is reached, RTS is activated or XOFF is sent
+         * according to the flow control mode. Else, RTS is deactivated or XON
+         * is sent.
+         */
+
+        if (fcMode != fc_none) {
+
+            if (get_bytes_in_rx_buffer (uart) >= RX_HIGH_WATERMARK (
+                                                     uart->buffer_size)) {
+
+                uart->rx_stopped_by_driver = 1;
+                stop_receiver (uart);
+
+            } else if (!DRIVER_DISABLED (uart)) {
+
+                uart->rx_stopped_by_driver = 0;
+                start_receiver (uart);
+            }
+            
+        } else {
+        
+            uart->rx_stopped_by_driver = 0;
+            uart->tx_stopped_by_driver = 0;
+        }
+
+        result = FD_OK;
+    }
+
+    return (result);
+}
+
+/*******************************************************************************
+ *
+ *                               UAF_SetEscape
+ * 
+ * Purpose  : To return to the command mode at the ACI while a data connection
+ *            is established, an escape sequence has to be detected.
+ *            To distinguish between user data and the escape sequence a
+ *            defined guard period is necessary before and after this sequence.
+ *
+ * Arguments: In:  uartNo     : Used UART.
+ *                 escChar    : ASCII character which could appear three times
+ *                              as an escape sequence.
+ *                 guardPeriod: Denotes the minimal duration of the rest before
+ *                              the first and after the last character of the
+ *                              escape sequence, and the maximal receiving
+ *                              duration of the whole escape string. This value
+ *                              is expressed in ms.
+ *            Out: none
+ *
+ * Returns  : FD_OK           : Successful operation.
+ *            FD_NOT_SUPPORTED: Wrong UART number.
+ *            FD_INTERNAL_ERR : Internal problem with the hardware.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_SetEscape (T_fd_UartId uartNo,
+               SYS_UWORD8 escChar,
+               SYS_UWORD16 guardPeriod)
+{
+    t_uart  *uart;
+
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    /*
+     * There is no case where FD_INTERNAL_ERR may be returned.
+     */
+
+    uart = &uart_parameters;
+
+    uart->esc_seq_modified = 1;
+    uart->esc_seq_character = escChar;
+    uart->guard_period = CONVERT_TIME_IN_TDMA ((UNSIGNED) guardPeriod);
+    uart->esc_seq_modified = 0; /* Set to 0 by the RX interrupt handler. */
+
+    return (FD_OK);
+}
+
+/*******************************************************************************
+ *
+ *                              UAF_InpAvail
+ * 
+ * Purpose  : Returns the number of characters available in the RX buffer of the
+ *            driver. If the driver is disabled the function returns 0.
+ *
+ * Arguments: In : uartNo: Used UART.
+ *            Out: none
+ *
+ * Returns  : >= 0            : The returned value is the amount of data in the
+ *                              RX buffer.
+ *            FD_NOT_SUPPORTED: Wrong UART number.
+ *            FD_NOT_READY    : The function is called while the callback of the
+ *                              readOutFunc function is activated and still not
+ *                              terminated.
+ *            FD_INTERNAL_ERR : Internal problem with the hardware.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_InpAvail (T_fd_UartId uartNo)
+{
+    T_FDRET result;
+    t_uart  *uart;
+    SYS_UWORD16  bytes_read;
+    SYS_UWORD16  bytes_in_rx_buffer;
+
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    /*
+     * There is no case where FD_INTERNAL_ERR may be returned.
+     */
+
+    uart = &uart_parameters;
+
+    if (uart->rd_call_setup == rm_notDefined)
+        result = FD_NOT_READY;
+
+    else if (DRIVER_DISABLED (uart))
+        result = 0;
+
+    else {
+
+        bytes_in_rx_buffer = get_bytes_in_rx_buffer (uart);
+
+        /*
+         * Update reading pointer of the RX buffer if a callback from LISR
+         * has been done.
+         */
+
+        if (uart->rd_call_from_hisr_in_progress) {
+
+            bytes_read = uart->rd_size_before_call[0] -
+                         uart->rd_size_after_call[0] +
+                         uart->rd_size_before_call[1] -
+                         uart->rd_size_after_call[1];
+
+            uart->rx_out += bytes_read;
+
+            if (uart->rx_out >= &(uart->rx_buffer[0]) + uart->buffer_size + 1)
+                uart->rx_out = uart->rx_out - uart->buffer_size - 1;
+
+            /*
+             * Check if the low watermark is reached to enable the receiver.
+             */
+
+            bytes_in_rx_buffer = get_bytes_in_rx_buffer (uart);
+
+            if ((uart->flow_control_mode != fc_none) &&
+                (bytes_in_rx_buffer <= RX_LOW_WATERMARK (uart->buffer_size))) {
+
+                if ((!uart->rx_stopped_by_application) &&
+                    uart->rx_stopped_by_driver)
+                    start_receiver (uart);
+
+                uart->rx_stopped_by_driver = 0;
+            }
+
+            uart->rd_call_from_hisr_in_progress = 0;
+        }
+
+        result = (T_FDRET) bytes_in_rx_buffer;
+    }
+
+    return (result);
+}
+
+/*******************************************************************************
+ *
+ *                             UAF_OutpAvail
+ * 
+ * Purpose  : Returns the number of free characters in TX buffer of the driver.
+ *            If the driver is disabled the function returns 0.
+ *
+ * Arguments: In : uartNo: Used UART.
+ *            Out: none
+ *
+ * Returns  : >= 0            : The returned value is the amount of data in the
+ *                              TX buffer.
+ *            FD_NOT_SUPPORTED: Wrong UART number.
+ *            FD_NOT_READY    : The function is called while the callback of the
+ *                              writeInFunc function is activated and still not
+ *                              terminated.
+ *            FD_INTERNAL_ERR : Internal problem with the hardware.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_OutpAvail (T_fd_UartId uartNo)
+{
+    T_FDRET result;
+    t_uart  *uart;
+    SYS_UWORD16  bytes_written;
+
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    /*
+     * There is no case where FD_INTERNAL_ERR may be returned.
+     */
+
+    uart = &uart_parameters;
+
+    if (uart->wr_call_setup == rm_notDefined)
+        result = FD_NOT_READY;
+
+    else if (DRIVER_DISABLED (uart))
+        result = 0;
+
+    else {
+
+        /*
+         * Update reading pointer of the TX buffer if a callback from LISR
+         * has been done.
+         */
+
+        if (uart->wr_call_from_hisr_in_progress) {
+
+            bytes_written = uart->wr_size_before_call[0] -
+                            uart->wr_size_after_call[0] +
+                            uart->wr_size_before_call[1] -
+                            uart->wr_size_after_call[1];
+
+            uart->tx_in += bytes_written;
+
+            if (uart->tx_in >= &(uart->tx_buffer[0]) + uart->buffer_size + 1)
+                uart->tx_in = uart->tx_in - uart->buffer_size - 1;
+
+            uart->wr_call_from_hisr_in_progress = 0;
+
+            /*
+             * if the TX FIFO is empty, unmask TX empty interrupt.
+             */
+
+            if (!uart->tx_stopped_by_driver &&
+                (READ_UART_REGISTER (uart, LSR) & THRE))
+            {
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+                /*
+                 * Disable sleep mode.
+                 */
+          
+                WRITE_UART_REGISTER (
+                   uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
+#endif
+
+                /*
+                 * Unmask Tx interrupt.
+                 */
+          
+                WRITE_UART_REGISTER (
+                    uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);
+            }
+        }
+
+        result = (T_FDRET) (uart->buffer_size - get_bytes_in_tx_buffer (uart));
+    }
+
+    return (result);
+}
+
+/*******************************************************************************
+ *
+ *                             UAF_EnterSleep
+ * 
+ * Purpose  : Checks if UART is ready to enter Deep Sleep. If ready, enables
+ *            wake-up interrupt.
+ *
+ * Arguments: In : uartNo: Used UART.
+ *            Out: none
+ *
+ * Returns  : 0	              : Deep Sleep is not possible.
+ *            >= 1            : Deep Sleep is possible.
+ *            FD_NOT_SUPPORTED: Wrong UART number.
+ *
+ * Warning: Parameters are not verified.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_EnterSleep (T_fd_UartId uartNo)
+{
+    t_uart              *uart;
+    SYS_BOOL            deep_sleep;
+    volatile SYS_UWORD8 status;
+    
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    uart = &uart_parameters;
+    deep_sleep = 0;
+
+    /*
+	 * Check if RX & TX FIFOs are both empty
+	 */
+
+    status = READ_UART_REGISTER (uart, LSR);
+
+    if (!(status & DR) &&
+        (status & TEMT)) {
+
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+        /*
+         * Disable sleep mode.
+         */
+              
+        WRITE_UART_REGISTER (
+            uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
+#endif
+
+#if (CHIPSET == 12)
+        /*
+         * Mask DSR interrupt.
+         */
+
+        DISABLE_DSR_INTERRUPT (uart);
+#endif
+
+        /*
+         * Mask RX, TX and the modem status interrupts.
+         */
+
+        WRITE_UART_REGISTER (
+            uart, IER, READ_UART_REGISTER (uart, IER) &
+                       ~(ERBI | ETBEI | EDSSI));
+
+        /*
+         * Enable the wake-up interrupt.
+         */
+
+        ENABLE_WAKEUP_INTERRUPT (uart);
+
+        deep_sleep = 1;
+    }
+
+    return (deep_sleep);
+}
+
+/*******************************************************************************
+ *
+ *                              UAF_WakeUp
+ * 
+ * Purpose  : Wakes up UART after Deep Sleep.
+ *
+ * Arguments: In : uartNo: Used UART.
+ *            Out: none
+ *
+ * Returns  : FD_OK           : Successful operation.
+ *            FD_NOT_SUPPORTED: Wrong UART number.
+ *
+ * Warning: Parameters are not verified.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_WakeUp (T_fd_UartId uartNo)
+{
+    t_uart *uart;
+   
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    uart = &uart_parameters;
+
+    /*
+     * Disable the wake-up interrupt.
+     */
+
+    DISABLE_WAKEUP_INTERRUPT (uart);
+
+    /*
+     * Unmask RX and modem status interrupts.
+     */
+
+    WRITE_UART_REGISTER (
+        uart, IER, READ_UART_REGISTER (uart, IER) | (ERBI | EDSSI));
+
+#if (CHIPSET == 12)
+    /*
+     * Unmask DSR interrupt.
+     */
+
+    ENABLE_DSR_INTERRUPT (uart);
+#endif
+
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+    /*
+     * Allow sleep mode.
+     */
+  /* BELOW LINES WERE COMMENTED TO DISABLE SLEEP MODE IN DRIVER */  
+  /*
+    WRITE_UART_REGISTER ( 
+        uart, IER, READ_UART_REGISTER (uart, IER) | IER_SLEEP);
+        */
+#endif
+
+    return (FD_OK);
+}
+
+/*******************************************************************************
+ *
+ *                              UAF_ReadData
+ * 
+ * Purpose  : To read the received characters out of the RX buffer the address
+ *            of a function is passed. If characters are available, the driver
+ *            calls this function and pass the address and the amount of
+ *            readable characters. Because the RX buffer is circular, the
+ *            callback function may be called with more than one address of
+ *            buffer fragment.
+ *            The readOutFunc function modifies the contents  of the size array
+ *            to return the driver the number of processed characters. Each
+ *            array entry is decremented by the number of bytes read in the
+ *            fragment.
+ *            If the UAF_ReadData is called while the RX buffer is empty, it
+ *            depends on the suspend parameter to suspend the call-back or to
+ *            leave without any operation. In the case of suspension, the
+ *            return value of UAF_ReadData is UAF_SUSPENDED. A delayed call-back
+ *            will be performed if:
+ *              - the RX buffer reachs the adjusted threshold (rxThreshold of
+ *                UAF_SetBuffer),
+ *              - the state of a V.24 input line has changed,
+ *              - a break is detected,
+ *              - an escape sequence is detected.
+ *            If no suspension is necessary the function returns the number of
+ *            processed bytes.
+ *
+ * Arguments: In : uartNo     : Used UART.
+ *                 suspend    : mode of suspension in case of RX buffer empty.
+ *                 readOutFunc: Callback function.
+ *                              cldFromIrq: The driver sets this parameter to 1
+ *                                          if the callback function is called
+ *                                          from an interrupt service routine.
+ *                              reInstall : The call-back function sets this
+ *                                          parameter to rm_reInstall if the
+ *                                          driver must call again the callback
+ *                                          function when the RX threshold level
+ *                                          is reached. Else it will be set to
+ *                                          rm_noInstall. Before to call the
+ *                                          readOutFunc function this parameter
+ *                                          is set to rm_notDefined.
+ *                              nsource   : Informed the callback function about
+ *                                          the number of fragments which are
+ *                                          ready to copy from the circular RX
+ *                                          buffer.
+ *                              source    : Array which contains the addresses
+ *                                          of the fragments.
+ *                              size      : Array which contains the sizes of
+ *                                          each fragments.
+ *                              state     : The state parameter is the status
+ *                                          of the V.24 lines and the break / 
+ *                                          escape detection. The state
+ *                                          parameter is described in the
+ *                                          specification of UAF_GetLineState.
+ *            Out: none
+ *
+ * Returns  : >= 0            : Succesful operation. Amount of processed bytes.
+ *            FD_NOT_SUPPORTED: Wrong UART number.
+ *            FD_SUSPENDED    : The callback is suspended until the buffer or
+ *                              state condition changed.
+ *            FD_NOT_READY    : The function is called while the callback is
+ *                              activated and still not terminated.
+ *            FD_INTERNAL_ERR : Internal problems with the hardware.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_ReadData (T_fd_UartId uartNo,
+              T_suspendMode suspend,
+              void (readOutFunc (SYS_BOOL cldFromIrq,
+                                 T_reInstMode *reInstall,
+                                 SYS_UWORD8 nsource,
+                                 SYS_UWORD8 *source[],
+                                 SYS_UWORD16 size[],
+                                 SYS_UWORD32 state)))
+{
+    T_FDRET result;
+    t_uart *uart;
+    SYS_UWORD16  bytes_read;
+    SYS_UWORD16  bytes_in_rx_buffer;
+
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    /*
+     * There is no case where FD_INTERNAL_ERR may be returned.
+     */
+
+    uart = &uart_parameters;
+
+    if (uart->rd_call_setup == rm_notDefined)
+        result = FD_NOT_READY;
+
+    else if (get_bytes_in_rx_buffer (uart) || uart->esc_seq_received) {
+
+        uart->readOutFunc = readOutFunc;
+        update_reading_callback (uart, 0); /* 0: call from application. */
+
+        bytes_read = uart->rd_size_before_call[0] -
+                     uart->rd_size_after_call[0] +
+                     uart->rd_size_before_call[1] -
+                     uart->rd_size_after_call[1];
+
+        uart->rx_out += bytes_read;
+
+        if (uart->rx_out >= &(uart->rx_buffer[0]) + uart->buffer_size + 1)
+            uart->rx_out = uart->rx_out - uart->buffer_size - 1;
+
+        /*
+         * Check if the low watermark is reached to enable the receiver.
+         */
+
+        if ((uart->flow_control_mode != fc_none) &&
+            (get_bytes_in_rx_buffer (uart) <= RX_LOW_WATERMARK (
+                                                  uart->buffer_size))) {
+
+            if ((!uart->rx_stopped_by_application) &&
+                uart->rx_stopped_by_driver && (!uart->rx_stopped_by_lisr))
+                start_receiver (uart);
+
+            uart->rx_stopped_by_driver = 0;
+        }
+
+        uart->esc_seq_received = 0;
+        result = (T_FDRET) bytes_read;
+
+    } else  if (suspend == sm_suspend) {
+
+        uart->readOutFunc = readOutFunc;
+        uart->reading_suspended = 1;
+        result = FD_SUSPENDED;
+
+    } else {
+        
+        /*
+         * The previous callback function is deinstalled.
+         */
+             
+        uart->rd_call_setup = rm_noInstall;
+        uart->reading_suspended = 0;
+        result = 0; /* 0 byte read. */
+    }
+
+    return (result);
+}
+
+/*******************************************************************************
+ *
+ *                              UAF_WriteData
+ * 
+ * Purpose  : To write characters into the TX buffer the address of a function
+ *            is passed. If free space is available in the buffer, the driver
+ *            calls this function and passes the destination address and the
+ *            amount of space. Because the TX buffer is circular, the callback
+ *            function may be called with more than one address of buffer
+ *            fragment.
+ *            The writeInFunc function modifies the contents of the size array
+ *            to return the driver the number of processed bytes. Each array
+ *            entry is decremented  by the number of bytes written in this
+ *            fragment.
+ *            If the UAF_WriteData function is called while the TX buffer is
+ *            full, it depends on the suspend parameter to suspend the
+ *            call-back or to leave this function without any operation. In the
+ *            case of suspension the returned value of the UAF_WriteData is
+ *            UAF_SUSPENDED. A delayed call-back will be performed if the TX
+ *            buffer reaches the adjusted threshold (txThreshold of
+ *            UAF_SetBuffer). If no suspension is necessary the function returns
+ *            the number of processed bytes.
+ *
+ * Arguments: In : uartNo     : Used UART.
+ *                 suspend    : mode of suspension in case of TX buffer empty.
+ *                 writeInFunc: Callback function. 
+ *                              cldFromIrq: The driver sets this parameter to 1
+ *                                          if the call-back function is called
+ *                                          from an interrupt service routine.
+ *                              reInstall : The callback function sets this
+ *                                          parameter to rm_reInstall if the
+ *                                          driver must call again the callback
+ *                                          function when the TX threshold level
+ *                                          is reached. Else it will be set to
+ *                                          rm_noInstall. Before to call the
+ *                                          writeInFunc function this parameter
+ *                                          is set to rm_notDefined.
+ *                              ndest     : Informed the callback function about
+ *                                          the number of fragments which are
+ *                                          available in the TX buffer.
+ *                              dest      : Array which contains the addresses
+ *                                          of the fragments.
+ *                              size      : Array which contains the sizes of
+ *                                          each fragments.
+ *            Out: none
+ *
+ * Returns  : >= 0            : Succesful operation. Amount of processed bytes.
+ *            FD_NOT_SUPPORTED: Wrong UART number.
+ *            FD_SUSPENDED    : The callback is suspended until the buffer
+ *                              condition changed.
+ *            FD_NOT_READY    : The function is called while the callback is
+ *                              activated and still not terminated.
+ *            FD_INTERNAL_ERR : Internal problems with the hardware.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_WriteData (T_fd_UartId uartNo,
+               T_suspendMode suspend,
+               void (writeInFunc (SYS_BOOL cldFromIrq,
+                                  T_reInstMode *reInstall,
+                                  SYS_UWORD8 ndest,
+                                  SYS_UWORD8 *dest[],
+                                  SYS_UWORD16 size[])))
+{
+    T_FDRET result;
+    t_uart *uart;
+    SYS_UWORD16  bytes_written;
+
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    /*
+     * There is no case where FD_INTERNAL_ERR may be returned.
+     */
+
+    uart = &uart_parameters;
+
+    if (uart->wr_call_setup == rm_notDefined)
+        result = FD_NOT_READY;
+
+    else if ((!DRIVER_DISABLED (uart)) &&
+             (get_bytes_in_tx_buffer (uart) < uart->buffer_size)) {
+
+        uart->writeInFunc = writeInFunc;
+        update_writing_callback (uart, 0); /* 0: call from application. */
+
+        bytes_written = uart->wr_size_before_call[0] -
+                        uart->wr_size_after_call[0] +
+                        uart->wr_size_before_call[1] -
+                        uart->wr_size_after_call[1];
+
+        uart->tx_in += bytes_written;
+
+        if (uart->tx_in >= &(uart->tx_buffer[0]) + uart->buffer_size + 1)
+            uart->tx_in = uart->tx_in - uart->buffer_size - 1;
+
+	/* If we have been stopped due to high RTS, we have to
+	 * wake up application processor by IRQ via IO1 -HW */
+	if (uart->tx_stopped_by_driver)
+            HighGPIO(1);
+
+        /*
+         * If:
+         *      - there is no break to send,
+         *      - the flow control is not activated,
+         * unmask the TX empty interrupt to be able to send characters.
+         */
+        if (!uart->break_to_send &&
+            !uart->tx_stopped_by_driver)
+        {    
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+            /*
+             * Disable sleep mode.
+             */
+          
+            WRITE_UART_REGISTER (
+                uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
+#endif
+
+            /*
+             * Unmask Tx interrupt.
+             */
+          
+            WRITE_UART_REGISTER (
+                uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);
+        }
+
+        result = (T_FDRET) bytes_written;
+
+    } else  if (suspend == sm_suspend) {
+
+        uart->writeInFunc = writeInFunc;
+        uart->writing_suspended = 1;
+        result = FD_SUSPENDED;
+
+    } else {
+        
+        /*
+         * The previous callback function is deinstalled.
+         */
+             
+        uart->wr_call_setup = rm_noInstall;
+        uart->writing_suspended = 0;
+        result = 0;
+    }
+
+    return (result);
+}
+
+/*******************************************************************************
+ *
+ *                              UAF_StopRec
+ * 
+ * Purpose  : If a flow control mode is set, this function tells the terminal
+ *            equipment that no more data can be received.
+ *            XON/XOFF: XOFF is sent.
+ *            DTR/DSR : DTR is desactivated.
+ *            RTS/CTS : RTS is deactivated.
+ *
+ * Arguments: In : uartNo: Used UART.
+ *            Out: none
+ *
+ * Returns  : FD_OK           : Successful operation.
+ *            FD_NOT_SUPPORTED: Wrong UART number.
+ *            FD_INTERNAL_ERR : Internal problem with the hardware.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_StopRec (T_fd_UartId uartNo)
+{
+    t_uart *uart;
+
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    /*
+     * There is no case where FD_INTERNAL_ERR may be returned.
+     */
+
+    uart = &uart_parameters;
+
+    if (uart->flow_control_mode != fc_none)
+        stop_receiver (uart);
+
+    uart->rx_stopped_by_application = 1;
+
+    return (FD_OK);
+}
+
+/*******************************************************************************
+ *
+ *                              UAF_StartRec
+ * 
+ * Purpose  : If a flow control mode is set, this function tells the terminal
+ *            equipment that the receiver is again able to receive more data.
+ *            If the buffer has already reached the high water mark the driver
+ *            sends the signal only if the buffer drains to a low water mark.
+ *            XON/XOFF: XON is sent.
+ *            DTR/DSR : DTR is activated.
+ *            RTS/CTS : RTS is activated.
+ *
+ * Arguments: In : uartNo: Used UART.
+ *            Out: none
+ *
+ * Returns  : FD_OK           : Successful operation.
+ *            FD_NOT_SUPPORTED: Wrong UART number.
+ *            FD_INTERNAL_ERR : Internal problem with the hardware.
+ *
+ ******************************************************************************/
+
+T_FDRET 
+UAF_StartRec (T_fd_UartId uartNo)
+{
+    t_uart *uart;
+
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    /*
+     * There is no case where FD_INTERNAL_ERR may be returned.
+     */
+
+    uart = &uart_parameters;
+
+    if ((uart->flow_control_mode != fc_none) && (!uart->rx_stopped_by_driver))
+        start_receiver (uart);
+
+    uart->rx_stopped_by_application = 0;
+
+    return (FD_OK);
+}
+
+/*******************************************************************************
+ *
+ *                            UAF_GetLineState
+ * 
+ * Purpose  : Returns the state of the V.24 lines, the flow control state and
+ *            the result of the break/escape detection process as a bit field.
+ *
+ * Arguments: In : uartNo: Used UART.
+ *            Out: state : State of the V.24 lines, the flow control state and
+ *                         the result of the break/escape sequence detection
+ *                         process as a bit field.
+ *
+ * Returns  : FD_OK           : Successful operation.
+ *            FD_NOT_SUPPORTED: Wrong UART number.
+ *            FD_NOT_READY    : The function is called while the callback of 
+ *                              the readOutFunc function is activated and still
+ *                              not terminated.
+ *            FD_INTERNAL_ERR : Internal problem with the hardware.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_GetLineState (T_fd_UartId uartNo,
+                  SYS_UWORD32 *state)
+{
+    T_FDRET result;
+    t_uart *uart;
+
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    /*
+     * There is no case where FD_INTERNAL_ERR may be returned.
+     * Signals not supported are reported as 0.
+     */
+
+    uart = &uart_parameters;
+
+    if (uart->rd_call_setup == rm_notDefined)
+        result = FD_NOT_READY;
+
+    else {
+
+        /*
+         * The field state_2 is used when state_1 is set to 0 to avoid to
+         * lose events detected in the RX interrupt handler.
+         * Fields BRK and BRKLEN are set when a break is detected.
+         * The field ESC is set when an escape sequence is detected. 
+         */
+
+        *state = uart->state_2;
+        uart->state_2 = 0;
+        uart->state = &(uart->state_2);
+
+        *state |= uart->state_1;
+        uart->state_1 = 0;
+        uart->state = &(uart->state_1);
+
+        *state |= ((((SYS_UWORD32) uart->rts_level) << RTS) |
+        
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (CHIPSET == 12))
+                   (((SYS_UWORD32) uart->dtr_level) << DTR) |
+#endif
+
+                   (((SYS_UWORD32) (uart->tx_stopped_by_application  |
+                              uart->tx_stopped_by_driver)) << TXSTP) |
+
+                   (((SYS_UWORD32) (uart->rx_stopped_by_application  |
+                              uart->rx_stopped_by_driver)) << RXSTP) |
+
+                   (((SYS_UWORD32) (uart->buffer_size - 
+                              get_bytes_in_rx_buffer (uart))) << RXBLEV));
+                                 
+        /*
+         * Fields SA, SB and X are set according to the flow control:
+         *
+         *       None    RTS/CTS    XON/XOFF
+         * SA    DTR     DTR        DTR
+         * SB    RTS     0          RTS
+         * X     0       RTS        XON:0 XOFF:1 (transmitter)
+         *
+         * DTR is supported on C, D & E-Sample.
+         */
+
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (CHIPSET == 12))
+        *state |= (((SYS_UWORD32) uart->dtr_level) << SA);
+#endif
+
+        if (uart->flow_control_mode != fc_rts)
+            *state |= (((SYS_UWORD32) uart->rts_level) << SB);
+
+        if (uart->flow_control_mode == fc_rts)
+            *state |= (((SYS_UWORD32) uart->rts_level) << X);
+            
+        else if ((uart->flow_control_mode == fc_xoff) &&
+                 (uart->tx_stopped_by_application ||
+                  uart->tx_stopped_by_driver))
+            *state |= (1 << X);
+
+        result = FD_OK;
+    }
+
+    return (result);
+}
+
+/*******************************************************************************
+ *
+ *                            UAF_SetLineState
+ * 
+ * Purpose  : Sets the states of the V.24 status lines according to the bit
+ *            field of the parameter state.
+ *
+ * Arguments: In : uartNo: Used UART.
+ *                 state : Bit field. Only the signals which are marked with
+ *                         the 'set' access can be used to change the state of
+ *                         the signal.
+ *                 mask  : Bit field with the same structure as state. Each bit
+ *                         in state corresponds to a bit in mask. Settabled
+ *                         bits marked by a 1 are manipulated by the driver.
+ *            Out: none
+ *
+ * Returns  : FD_OK           : Successful operation.
+ *            FD_NOT_SUPPORTED: Wrong UART number.
+ *            FD_INTERNAL_ERR : Internal problem with the hardware.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_SetLineState (T_fd_UartId uartNo,
+                  SYS_UWORD32 state,
+                  SYS_UWORD32 mask)
+{
+    t_uart  *uart;
+    UNSIGNED break_length;
+
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    uart = &uart_parameters;
+
+    /*
+     * There is no case where FD_INTERNAL_ERR may be returned.
+     * DCD is supported on C, D & E-Sample. The SA field is not supported because
+     * DSR is not supported on all platforms.
+     */
+
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (CHIPSET == 12))
+    if (mask & (1 << SA))
+#else
+    if ((mask & (1 << SA)) || (mask & (1 << DCD)))
+#endif
+        return (FD_NOT_SUPPORTED); /* Return used to simplify the code */
+        
+    /*
+     * Check if a break has to be sent.
+     */
+
+    uart->break_length = (UNSIGNED) ((state >> BRKLEN) & 0xFF);
+
+    if (state & (1 << BRK) && (mask & (1 << BRK))) {
+
+        if (uart->break_length > FIFO_SIZE)
+            return (FD_NOT_SUPPORTED); /* Return used to simplify the code */
+
+        else {
+
+            uart->time_without_character =
+                compute_break_time (uart->baudrate, uart->bits_per_char, 3);
+
+            uart->break_to_send = 1;
+
+            /*
+             * If the TX FIFO is empty the break is send from this function
+             * else the interrupt handler will send the break.
+             */
+
+            if (READ_UART_REGISTER (uart, LSR) & TEMT)
+                send_break(uart);
+        }
+    }
+
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+    /*
+     * Disable sleep mode.
+     */
+
+    WRITE_UART_REGISTER (
+        uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
+#endif
+
+    /*
+     * The CTS field is ignored if the X bit in the mask is set. In this case
+     * the X bit controls CTS.
+     */
+
+    if (mask & (1 << CTS)) {
+    
+        if (uart->flow_control_mode != fc_rts) {
+        
+            /*
+             * As the RTS/CTS flow control is not selected, the X bit does not
+             * control CTS. CTS needs only to be activated or deactivated
+             * according to the value of the CTS field.
+             */
+
+            if (state & (1 << CTS))
+                WRITE_UART_REGISTER (
+                    uart, MCR, READ_UART_REGISTER (uart, MCR) | MRTS);
+
+            else
+                WRITE_UART_REGISTER (
+                    uart, MCR, READ_UART_REGISTER (uart, MCR) & ~MRTS);
+
+        } else if (!(mask & (1 << X))) {
+
+            /*
+             * The RTS/CTS flow control is selected but the X bit in the mask
+             * is null. Then the CTS bit controls CTS and the receiver must be
+             * stopped or started according to the state of the CTS bit.
+             * The receiver is started only if it was not stopped by the driver
+             * and if it was stopped by the application.
+             */
+             
+            if (state & (1 << CTS)) {
+
+                if (!uart->rx_stopped_by_application) {
+                
+                    if (!uart->rx_stopped_by_driver)
+                        stop_receiver (uart);
+
+                    uart->rx_stopped_by_application = 1;
+                }
+                
+            } else {
+                
+                if ((!uart->rx_stopped_by_driver) &&
+                    uart->rx_stopped_by_application)
+                    start_receiver (uart);
+
+                uart->rx_stopped_by_application = 0;
+            }
+        }
+    }
+
+    /*
+     * The DCD field is ignored if the SB bit of the mask is set.
+     */
+
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (CHIPSET == 12))
+
+    if (!(mask & (1 << SB)) && (mask & (1 << DCD))) {
+
+        if (state & (1 << DCD)) {
+            /* Turn on DCD */
+            #if (CHIPSET == 12)
+                WRITE_UART_REGISTER (uart, MCR, READ_UART_REGISTER(uart, MCR) | MDCD);
+            #else
+                AI_ResetBit (ARMIO_DCD);
+            #endif
+        } else {
+            /* Turn off DCD */
+            #if (CHIPSET == 12)
+                WRITE_UART_REGISTER (uart, MCR, READ_UART_REGISTER(uart, MCR) & ~MDCD);
+            #else
+                AI_SetBit (ARMIO_DCD);
+            #endif
+        }
+    }
+
+#endif /* BOARD 8 or 9 or 40 or 41 or CHIPSET 12 */
+
+    /*
+     * Signals are set according to fields SA, SB and X states and flow
+     * control:
+     *
+     *       None    RTS/CTS    XON/XOFF
+     * SA    0 (ns)  0 (ns)     0 (ns)
+     * SB    DCD     DCD        DCD
+     * X     ignore  CTS        XON:0 XOFF:1 (receiver)
+     *
+     * ns: signal not supported.
+     * DCD is supported on C, D & E-Sample.
+     */
+
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (CHIPSET == 12))
+
+    if (mask & (1 << SB)) {
+
+        if (state & (1 << SB)) {
+            /* Turn on DCD */
+            #if (CHIPSET == 12)
+                WRITE_UART_REGISTER (uart, MCR, READ_UART_REGISTER(uart, MCR) | MDCD);
+            #else
+                AI_ResetBit (ARMIO_DCD);
+            #endif
+        } else {
+            /* Turn off DCD */
+            #if (CHIPSET == 12)
+                WRITE_UART_REGISTER (uart, MCR, READ_UART_REGISTER(uart, MCR) & ~MDCD);
+            #else
+                AI_SetBit (ARMIO_DCD);
+            #endif
+        }
+    }
+
+#endif /* BOARD 8 or 9 or 40 or 41 or CHIPSET 12 */
+        
+    if ((mask & (1 << X)) &&
+        (uart->flow_control_mode != fc_none)) {
+
+        if (state & (1 << X)) {
+                
+            if (!uart->rx_stopped_by_application) {
+                
+                if (!uart->rx_stopped_by_driver)
+                    stop_receiver (uart);
+
+                uart->rx_stopped_by_application = 1;
+            }
+                
+        } else {
+                
+            /*
+             * The receiver is started only if it is not stopped by the driver
+             * and if it is stopped by the application.
+             */
+
+            if ((!uart->rx_stopped_by_driver) &&
+                uart->rx_stopped_by_application)
+                start_receiver (uart);
+
+            uart->rx_stopped_by_application = 0;
+        }
+    }
+
+#if ((CHIPSET != 5) && (CHIPSET != 6))
+    /*
+     * Re-enable sleep mode.
+     */
+    /* BELOW LINES WERE COMMENTED TO DISABLE SLEEP MODE IN DRIVER */ 
+    /*
+    WRITE_UART_REGISTER (
+        uart, IER, READ_UART_REGISTER (uart, IER) | IER_SLEEP);
+        */
+#endif
+
+    return (FD_OK);
+}
+
+/*******************************************************************************
+ *
+ *                           UAF_InterruptHandler
+ * 
+ * Purpose  : Interrupt handler.
+ *
+ * Arguments: In : uart_id         : origin of interrupt
+ *                 interrupt_status: source of interrupt
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+void
+UAF_InterruptHandler (T_fd_UartId uart_id,
+                      SYS_UWORD8 interrupt_status)
+{
+
+    t_uart *uart;
+
+    /*
+     * uart_id is not used.
+     */
+
+    uart = &uart_parameters;
+
+    uart->current_time = NU_Retrieve_Clock ();
+
+    /*
+     * Causes of interrupt:
+     *      - trigger level reached,
+     *      - character time-out indication,
+     *      - transmitter holding register empty,
+     *      - modem status.
+     */
+
+    switch (interrupt_status) {
+
+    case RX_DATA:
+
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (CHIPSET == 12))
+        uart->index_it = (uart->index_it + 1) & 0x01; /* 0 or 1 */
+        uart->dtr_change_detected[uart->index_it] = 0;
+        uart->dtr_level_saved[uart->index_it] = uart->dtr_level;
+#endif
+        read_rx_fifo (uart);
+
+        // Disable Autobaud and lock baudrate upon first received character
+        if (uart->autobauding != 0)
+        {
+          /* MSMSMSMS */
+          SYS_UWORD8 uasr;
+          T_baudrate baudrate;
+          T_bitsPerCharacter bpc;
+          T_parity parity;
+
+          WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) | DLAB);
+
+
+          uasr = READ_UART_REGISTER (uart, UASR);
+
+          switch (uasr & 0x1F)
+          {
+            case 0x01: baudrate = FD_BAUD_115200; break;
+            case 0x02: baudrate = FD_BAUD_57600; break;
+            case 0x03: baudrate = FD_BAUD_38400; break;
+            case 0x04: baudrate = FD_BAUD_28800; break;
+            case 0x05: baudrate = FD_BAUD_19200; break;
+            case 0x06: baudrate = FD_BAUD_14400; break;
+            case 0x07: baudrate = FD_BAUD_9600; break;
+            case 0x08: baudrate = FD_BAUD_4800; break;
+            case 0x09: baudrate = FD_BAUD_2400; break;
+            case 0x0A: baudrate = FD_BAUD_1200; break;
+            default: /* no baudrate detected, abort for now */
+              return;
+          }
+
+          switch (uasr>>5 & 0x01)
+          {
+            case 0x00: bpc = bpc_7; break;
+            case 0x01: bpc = bpc_8; break;
+          }
+
+          switch (uasr>>6 & 0x03)
+          {
+            case 0x00: parity = pa_none; break;
+            case 0x01: parity = pa_space; break;
+            case 0x02: parity = pa_even; break;
+            case 0x03: parity = pa_odd; break;
+          }
+
+          UAF_SetComPar (UAF_UART_1,
+                         baudrate,
+                         bpc,
+                         sb_1,
+                         parity);
+
+          uart->baudrate = baudrate_value[FD_BAUD_AUTO]; /* remember autobauding */
+        }
+
+        break;
+
+    case TX_EMPTY:
+
+        fill_tx_fifo (uart);
+        break;
+
+    case MODEM_STATUS:
+
+        check_v24_input_lines (uart);
+        break;
+    }
+}
+
+/*******************************************************************************
+ *
+ *                              UAF_CheckXEmpty
+ * 
+ * Purpose  : Checks the empty condition of the Transmitter.
+ *
+ * Arguments: In : uartNo: Used UART.
+ *            Out: none
+ *
+ * Returns  : FD_OK           : Empty condition OK.
+ *            FD_NOT_SUPPORTED: Wrong UART number.
+ *            FD_NOT_READY    : Empty condition not OK.
+ *            FD_INTERNAL_ERR : Internal problem with the hardware.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_CheckXEmpty (T_fd_UartId uartNo)
+{
+    T_FDRET result;
+    t_uart *uart;
+    SYS_UWORD8 status;
+
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    /*
+     * There is no case where FD_INTERNAL_ERR may be returned.
+	 */
+
+    result = FD_OK;
+    
+    uart = &uart_parameters;
+    status = READ_UART_REGISTER (uart, LSR);
+
+    /*
+     * Checks if:
+     *     - the TX SW Buffer is empty,
+     *     - the TX HW FIFO is empty (THRE),
+     *     - the Transmitter Shift Register is empty (TEMT).
+     */
+
+    if (!(TX_BUFFER_EMPTY (uart)) ||
+        !(status & THRE) ||
+        !(status & TEMT))
+
+        result = FD_NOT_READY;
+
+    return (result);
+}
+
+#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41))
+/*******************************************************************************
+ *
+ *                              UAF_DTRInterruptHandler
+ *
+ * Purpose  : This function is only used on C & D-Sample. On this platform, the
+ *            DTR signal is controlled with an I/O. A change of state of this
+ *            signal is detected with an interrupt. This function is called when
+ *            this interrupt occurs.
+ *
+ * Arguments: In : none
+ *            Out: none
+ *
+ * Returns  : none
+ *
+ ******************************************************************************/
+
+void
+UAF_DTRInterruptHandler (void)
+{
+    t_uart *uart;
+    
+    uart = &uart_parameters;
+    
+    /*
+     * Read the state of DTR and change the edge to detect the next change
+     * of DTR.
+     */
+     
+    uart->dtr_level = AI_ReadBit (ARMIO_DTR);
+    
+    if (uart->dtr_level)
+    	{
+        AI_SelectIOForIT (ARMIO_DTR, ARMIO_FALLING_EDGE);
+	 if (uart->flow_control_mode != fc_dtr  && uart->baudrate == baudrate_value[FD_BAUD_AUTO])
+        UAF_SetComPar (UAF_UART_1, FD_BAUD_AUTO, bpc_8, sb_1, pa_none);
+       }
+    else
+        AI_SelectIOForIT (ARMIO_DTR, ARMIO_RISING_EDGE);
+        
+    /*
+     * The reading callback function has to be called. But bytes received before
+     * the change of state of DTR must be copied into the RX buffer before to
+     * call it.
+     */
+     
+    if (READ_UART_REGISTER (uart, LSR) & DR) { /* If Rx FIFO is not empty */
+    
+        /*
+         * The Rx FIFO will be read to fill one of the two buffers and the Rx
+         * HISR will be activated.
+         */
+       
+        uart->index_it = (uart->index_it + 1) & 0x01; /* 0 or 1 */
+        uart->dtr_change_detected[uart->index_it] = 1;
+        uart->dtr_level_saved[uart->index_it] = uart->dtr_level;
+        read_rx_fifo (uart);
+        
+    } else
+        (void) NU_Activate_HISR (&(uart->v24_hisr_ctrl_block));
+    
+}
+#endif /* BOARD 8 or 9 or 40 or 41 */
+
+#if (defined BTEMOBILE && (CHIPSET != 12))
+/*******************************************************************************
+ *
+ *                                UAF_Exit
+ * 
+ * Purpose  : 
+ *
+ * Arguments: In : uartNo: Used UART.
+ *            Out: none
+ *
+ * Returns  : FD_OK           : Successful operation.
+ *            FD_NOT_SUPPORTED: Wrong UART number.
+ *            FD_INTERNAL_ERR : Internal problem.
+ *
+ ******************************************************************************/
+
+T_FDRET
+UAF_Exit (T_fd_UartId uartNo)
+{
+    t_uart *uart;
+
+    /*
+     * Check UART number.
+     * A return is used to simplify the code.
+     * UART IrDA (UAF_UART_0) can't be used for F&D on Ulysse because hardware
+     * flow control is not supported.
+     * DCD and DTR are not supported on UART Irda on C & D-Sample.
+     * DCD and DTR are not supported on UART Irda & Modem2 on E-Sample.
+     */
+
+    if (uartNo != UAF_UART_1)
+        return (FD_NOT_SUPPORTED);
+
+    uart = &uart_parameters;
+
+    /*
+     * Delete the 3 HISR actived in the RX/TX and V24 interrupt handlers.
+     * A return is used to simplify the code if an error occurs.
+     */
+
+    if (NU_Delete_HISR (&(uart->rx_hisr_ctrl_block)) != NU_SUCCESS)
+        return (FD_INTERNAL_ERR);
+
+    if (NU_Delete_HISR (&(uart->tx_hisr_ctrl_block)) != NU_SUCCESS)
+        return (FD_INTERNAL_ERR);
+
+    if (NU_Delete_HISR (&(uart->v24_hisr_ctrl_block)) != NU_SUCCESS)
+        return (FD_INTERNAL_ERR);
+
+    /*
+     * Delete the HISR used to send a break.
+     * A return is used to simplify the code if an error occurs.
+     */
+
+    if (NU_Delete_HISR (&(uart->break_hisr_ctrl_block)) != NU_SUCCESS)
+        return (FD_INTERNAL_ERR);
+
+    /*
+     * Disable and then delete the timer used in the break HISR
+     * A return is used to simplify the code if an error occurs.
+     */
+
+    (void) NU_Control_Timer (&(uart->break_timer_ctrl_block),
+                             NU_DISABLE_TIMER);
+
+    if (NU_Delete_Timer (&(uart->break_timer_ctrl_block)) != NU_SUCCESS)
+        return (FD_INTERNAL_ERR);
+
+    /*
+     * Disable and then delete the timer used in the detection of the escape
+     * sequence. A return is used to simplify the code if an error occurs.
+     */
+
+    (void) NU_Control_Timer (&(uart->guard_period_timer_ctrl_block),
+                             NU_DISABLE_TIMER);
+
+    if (NU_Delete_Timer (&(uart->guard_period_timer_ctrl_block)) != NU_SUCCESS)
+        return (FD_INTERNAL_ERR);
+
+    /*
+     * At that point, all HISRs and Timers have been successfully deleted.
+     */
+
+    return (FD_OK);
+}
+#endif /* (defined BTEMOBILE && (CHIPSET != 12)) */
+
+
--- a/gsm-fw/serial/uartfax.c	Sun Apr 26 03:06:32 2015 +0000
+++ b/gsm-fw/serial/uartfax.c	Thu Apr 30 01:46:26 2015 +0000
@@ -331,7 +331,7 @@
 #define READ_UART_REGISTER(UART,REG)                                  \
             *((volatile SYS_UWORD8 *) ((UART)->base_address + (REG)))
 
-#define WRITE_UART_REGISTER(UART,REG,VALUE)                                     \
+#define WRITE_UART_REGISTER(UART,REG,VALUE)                           \
             *((volatile SYS_UWORD8 *) ((UART)->base_address + (REG))) = (VALUE)
 
 #define RESET_BIT(UART,REG,BIT)    \
@@ -2173,26 +2173,21 @@
                uart, IER, READ_UART_REGISTER (uart, IER) &
                        ~(ERBI | EDSSI));
               
-       if ((uart->rx_buffer_used_by_rx_hisr) == &(uart->rx_fifo_byte_1[0])) {
-       	 
-  	      	 uart->bytes_in_rx_buffer_1 = 0;
-           	 
-    	    } else {
-    	                
-               uart->bytes_in_rx_buffer_2 = 0;
-        }
+    if ((uart->rx_buffer_used_by_rx_hisr) == &(uart->rx_fifo_byte_1[0]))
+	uart->bytes_in_rx_buffer_1 = 0;
+    else
+	uart->bytes_in_rx_buffer_2 = 0;
 
        
-       WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) & ~DLAB);
+    WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) & ~DLAB);
               
-        /* Unmask The Rx and Modem status interrupt*/
-       WRITE_UART_REGISTER (
+    /* Unmask The Rx and Modem status interrupt*/
+    WRITE_UART_REGISTER (
                uart, IER, READ_UART_REGISTER (uart, IER) |
                        (ERBI | EDSSI));
 
-        if(uart->rx_stopped_by_lisr  ) {
+    if(uart->rx_stopped_by_lisr  ) {
        	if (!uart->rx_stopped_by_driver) {
-   		 
 
               uart->rx_stopped_by_lisr = 0;
         
@@ -2769,7 +2764,7 @@
                          "Break",
                          stop_break,
                          0, /* Parameter supplied to the routine: not used. */
-                         0, /* This parameter is set when the timer is reset. */
+                         1, /* This parameter is set when the timer is reset. */
                          0, /* The timer expires once. */
                          NU_DISABLE_TIMER) != NU_SUCCESS)
 
@@ -2784,7 +2779,7 @@
                          "Esc seq",
                          analyze_guard_period_timer_expiration,
                          0, /* Parameter supplied to the routine: not used. */
-                         0, /* This parameter is set when the timer is reset. */
+                         1, /* This parameter is set when the timer is reset. */
                          0, /* The timer expires once. */
                          NU_DISABLE_TIMER) != NU_SUCCESS)