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