Listing 5 (uartmacs.c) Macro Routines Used by Both uartlow.c and uartapi.c

/* The following two variables are required for the
   IO_DELAY macro. They will automatically be
   defined as global to the including source file.
   They are not system-wide global since the
   interrupt driver and API functions could be
   utilizing them at the same time. */
static unsigned char g_delay_char;
static unsigned char g_shift_char;

/*****************************************************
Chew up CPU cycles while I/O port catches up
*****************************************************/
#define IO_DELAY(delay_loops) {                       \
   for ( g_delay_char = 0 ;                          \
        g_delay_char < delay_loops ;                \
        g_delay_char++)                             \
      g_shift_char &= g_delay_char;                 \
}


/*****************************************************
  These macros all assume that a local variable
  p_cur_port_info points to the port info structure
  of the port to be acted on. They also assume the
  availability of a local register variable
  value_from_port to use as scratch space.

  Also note the terminating \ on each line of the
  macros (except for the closing brace) - it is
  required because Microsoft C requires that a macro
  be only one line long (the \ is the line
  continuation character).
*****************************************************/


/*****************************************************
Turn the Data Terminal Ready signal on
*****************************************************/
#define RAISE_DTR {                                   \
   /* Read Modem Control Register */                  \
   value_from_port = inp(p_cur_port_info->            \
       base_address + MODEM_CONTROL_REGISTER);       \
                                              \
   /* Delay for port to catch up */                   \
   IO_DELAY (2);                                      \
                                               \
   /* Output the Modem Control Register Value with */ \
   /* the DTR bit activated */                        \
   outp(p_cur_port_info->base_address +              \
       MODEM_CONTROL_REGISTER,                       \
       (value_from_port | 0x01) );                   \
}

/*****************************************************
Turn the Data Terminal Ready signal off
*****************************************************/
#define DROP_DTR {                                    \
   /* Read Modem Control Register */                 \
   value_from_port = inp(p_cur_port_info->           \
       base_address + MODEM_CONTROL_REGISTER);      \
                                              \
   /* Delay for port to catch up */                  \
   IO_DELAY (2);                                     \
                                              \
   /* Output the Modem Control Register Value with */\
   /* the DTR bit deactivated */                     \
   outp(p_cur_port_info->base_address +             \
       MODEM_CONTROL_REGISTER,                      \
       (value_from_port & 0xFE));                   \
}

/****************************************************
Turn the Request To Send signal on
****************************************************/
#define RAISE_RTS {                                  \
   /* Read Modem Control Register */                \
   value_from_port = inp(p_cur_port_info->          \
       base_address + MODEM_CONTROL_REGISTER);     \
                                            \
   /* Delay for port to catch up */                 \
   IO_DELAY (2);                                    \
                                             \
   /* Output the Modem Control Register Value with */\
   /* the RTS bit activated */                       \
   outp(p_cur_port_info->base_address +              \
       MODEM_CONTROL_REGISTER,                      \
       (value_from_port | 0x02)                     \
}


/****************************************************
Turn the Request To Send signal off
****************************************************/
#define DROP_RTS {                                   \
   /* Read Modem Control Register */                 \
   value_from_port = inp(p_cur_port_info->           \
   base_address + MODEM_CONTROL_REGISTER);           \
                                             \
   /* Delay for port to catch up */                  \
   IO_DELAY (2);                                     \
                                              \
   /* Output the Modem Control Register Value with */\
   /* the RTS bit deactivated */                     \
   outp(p_cur_port_info->base_address +              \
       MODEM_CONTROL_REGISTER,                      \
       (value_from_port & 0xFD));                   \
}


/***************************************************
Force a Transmit Holding Register Emtpy interrupt to
be generated now if the transmitter is empty.
***************************************************/
#define BOUNCE_THRE {                               \
   /* Disable THRE interrupt */                    \
   outp(p_cur_port_info->base_address +            \
       INTERRUPT_ENABLE_REGISTER,0x0D);           \
                                            \
   /* Delay for port to catch up */                \
   IO_DELAY (3);                                   \
                                            \
   /* Re-enable THRE interrupt */                  \
   outp(p_cur_port_info->base_address +            \
       INTERRUPT_ENABLE_REGISTER,0x0F);           \
                                            \
   /* Delay for port to catch up */                \
   IO_DELAY (2);                                   \
}
/* End of File */