⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ibmcom3.c

📁 IBMCOM_C serial port library
💻 C
📖 第 1 页 / 共 2 页
字号:
        disable();                              /* Interrupts off */

        outportb(uart_lcr,                      /* Set up to load baud rate */

                 inportb(uart_lcr) | 0x80);     /*  divisor into UART */

        outport(uart_data, divisor);            /* Do so */

        outportb(uart_lcr,                      /* Back to normal UART ops */

                 inportb(uart_lcr) & ~0x80);

        enable();                               /* Interrupts back on */

        }                                       /* End "comm installed" */

    }                                           /* End com_set_speed() */



/*****************************************************************************

 *                             com_set_parity()                              *

 *****************************************************************************

 * DESCRIPTION: Sets the parity and stop bits.                               *

 *                                                                           *

 * SYNOPSIS:    void com_set_parity(enum par_code parity, int stop_bits);    *

 *              int     code;           COM_NONE = 8 data bits, no parity    *

 *                                      COM_EVEN = 7 data, even parity       *

 *                                      COM_ODD  = 7 data, odd parity        *

 *                                      COM_ZERO = 7 data, parity bit = zero *

 *                                      COM_ONE  = 7 data, parity bit = one  *

 *              int     stop_bits;      Must be 1 or 2                       *

 *                                                                           *

 * REVISIONS:   18 OCT 89 - RAC - Translated from the Pascal                 *

 *****************************************************************************/



const char      lcr_vals[] = {

                    DATA8 + NOPAR,

                    DATA7 + EVNPAR,

                    DATA7 + ODDPAR,

                    DATA7 + STKPAR,

                    DATA7 + ZROPAR

                    } ;



void com_set_parity(enum par_code parity, int stop_bits) {

    disable();

    outportb(uart_lcr, lcr_vals[parity] | ((stop_bits == 2) ? STOP2 : STOP1));

    enable();

    }                                           /* End com_set_parity() */



/*****************************************************************************

 *                              com_raise_dtr()                              *

 *                              com_lower_dtr()                              *

 *****************************************************************************

 * DESCRIPTION: These routines raise and lower the DTR line.  Lowering DTR   *

 *              causes most modems to hang up.                               *

 *                                                                           *

 * REVISIONS:   18 OCT 89 - RAC - Transltated from the Pascal.               *

 *****************************************************************************/



void com_lower_dtr(void) {

    if (com_installed) {

        disable();

        outportb(uart_mcr, inportb(uart_mcr) & ~DTR);

        enable();

        }                                       /* End 'comm installed' */

    }                                           /* End com_raise_dtr() */



void com_raise_dtr(void) {

    if (com_installed) {

        disable();

        outportb(uart_mcr, inportb(uart_mcr) | DTR);

        enable();

        }                                       /* End 'comm installed' */

    }                                           /* End com_lower_dtr() */



/*****************************************************************************

 *                                 com_tx()                                  *

 *                              com_tx_string()                              *

 *****************************************************************************

 * DESCRIPTION: Transmit routines.  com_tx() sends a single character by     *

 *              waiting until the transmit buffer isn't full, then putting   *

 *              the character into it.  The interrupt driver will then send  *

 *              the character once it is at the head of the transmit queue   *

 *              and a transmit interrupt occurs.  com_tx_string() sends a    *

 *              string by repeatedly calling com_tx().                       *

 *                                                                           *

 * SYNOPSES:    void    com_tx(char c);         Send the character c         *

 *              void    com_tx_string(char *s); Send the string s            *

 *                                                                           *

 * REVISIONS:   18 OCT 89 - RAC - Translated from the Pascal                 *

 *****************************************************************************/



void com_tx(char c) {

    if (com_installed) {

        while (!com_tx_ready()) ;               /* Wait for non-full buffer */

        disable();                              /* Interrupts off */

        tx_queue[tx_in++] = c;                  /* Stuff character in queue */

        if (tx_in == TX_QUEUE_SIZE) tx_in = 0;  /* Wrap index if needed */

        tx_chars++;                             /* Number of char's in queue */

        outportb(uart_ier,                      /* Enable UART tx interrupt */

                 inportb(uart_ier) | THRE);

        enable();                               /* Interrupts back on */

        }                                       /* End 'comm installed' */

    }                                           /* End com_tx() */



void com_tx_string(char *s) {

    while (*s) com_tx(*s++);                    /* Send the string! */

    }                                           /* End com_tx_string() */



/*****************************************************************************

 *                                 com_rx()                                  *

 *****************************************************************************

 * DESCRIPTION: Returns the next character from the receive buffer, or a     *

 *              NULL character ('\0') if the buffer is empty.                *

 *                                                                           *

 * SYNOPSIS:    c = com_rx();                                                *

 *              char    c;                      The returned character       *

 *                                                                           *

 * REVISIONS:   18 OCT 89 - RAC - Translated from the Pascal.                *

 *****************************************************************************/



char    com_rx(void) {



    char        rv;                             /* Local temp */



    if (!rx_chars || !com_installed)            /* Return NULL if receive */

	return '\0';                            /*  buffer is empty */

    disable();                                  /* Interrupts off */

    rv = rx_queue[rx_out++];                    /* Grab char from queue */

    if (rx_out == RX_QUEUE_SIZE)                /* Wrap index if needed */

	rx_out = 0;

    rx_chars--;                                 /* One less char in queue */

    enable();                                   /* Interrupts back on */

    return rv;                                  /* The answer! */

    }                                           /* End com_rx() */



char    com_rx2(void) {



    char        rv;                             /* Local temp */



    do {



    } while (!rx_chars || !com_installed);            /* Return NULL if receive */

				    /*  buffer is empty */



    disable();                                  /* Interrupts off */

    rv = rx_queue[rx_out++];                    /* Grab char from queue */

    if (rx_out == RX_QUEUE_SIZE)                /* Wrap index if needed */

	rx_out = 0;

    rx_chars--;                                 /* One less char in queue */

    enable();                                   /* Interrupts back on */

    return rv;                                  /* The answer! */

    }                                           /* End com_rx() */



/*****************************************************************************

 *                           Queue Status Routines                           *

 *****************************************************************************

 * DESCRIPTION: Small routines to return status of the transmit and receive  *

 *              queues.                                                      *

 *                                                                           *

 * REVISIONS:   18 OCT 89 - RAC - Translated from the Pascal.                *

 *****************************************************************************/



int com_tx_ready(void) {                        /* Return TRUE if the */

    return ((tx_chars < TX_QUEUE_SIZE) ||       /*  transmit queue can */

            (!com_installed));                  /*  accept a character */

    }                                           /* End com_tx_ready() */



int com_tx_empty(void) {                        /* Return TRUE if the */

    return (!tx_chars || (!com_installed));     /*  transmit queue is empty */

    }                                           /* End com_tx_empty() */



int com_rx_empty(void) {                        /* Return TRUE if the */

    return (!rx_chars || (!com_installed));     /*  receive queue is empty */

    }                                           /* End com_tx_empty() */



/*****************************************************************************

 *                              com_flush_tx()                               *

 *                              com_flush_rx()                               *

 *****************************************************************************

 * DESCRIPTION: Buffer flushers!  These guys just initialize the transmit    *

 *              and receive queues (respectively) to their empty state.      *

 *                                                                           *

 * REVISIONS:   18 OCT 89 - RAC - Translated from the Pascal                 *

 *****************************************************************************/



void com_flush_tx() { disable(); tx_chars = tx_in = tx_out = 0; enable(); }

void com_flush_rx() { disable(); rx_chars = rx_in = rx_out = 0; enable(); }



/*****************************************************************************

 *                               com_carrier()                               *

 *****************************************************************************

 * DESCRIPTION: Returns TRUE if a carrier is present.                        *

 *                                                                           *

 * REVISIONS:   18 OCT 89 - RAC - Translated from the Pascal.                *

 *****************************************************************************/



int com_carrier(void) {

    return com_installed && (inportb(uart_msr) & RLSD);

    }                                           /* End com_carrier() */



/*****************************************************************************

 *                          com_interrupt_driver()                           *

 *****************************************************************************

 * DESCRIPTION: Handles communications interrupts.  The UART will interrupt  *

 *              whenever a character has been received or when it is ready   *

 *              to transmit another character.  This routine responds by     *

 *              sticking received characters into the receive queue and      *

 *              yanking characters to be transmitted from the transmit queue *

 *                                                                           *

 * REVISIOSN:   18 OCT 89 - RAC - Translated from the Pascal.                *

 *****************************************************************************/



void interrupt com_interrupt_driver() {



    char        iir;                            /* Local copy if IIR */

    char        c;                              /* Local character variable */



/*  While bit 0 of the IIR is 0, there remains an interrupt to process  */



    while (!((iir = inportb(uart_iir)) & 1)) {  /* While there is an int ... */

        switch (iir) {                          /* Branch on interrupt type */



            case 0:                             /* Modem status interrupt */

                inportb(uart_msr);              /* Just clear the interrupt */

                break;



            case 2:                             /* Transmit register empty */



/*****************************************************************************

 *  NOTE:  The test of the line status register is to see if the transmit    *

 *         holding register is truly empty.  Some UARTS seem to cause        *

 *         transmit interrupts when the holding register isn't empty,        *

 *         causing transmitted characters to be lost.                        *

 *****************************************************************************/



                if (tx_chars <= 0)              /* If tx buffer empty, turn */

                    outportb(uart_ier,          /*  off transmit interrupts */

                             inportb(uart_ier) & ~2);

                else {                          /* Tx buffer not empty */

                    if (inportb(uart_lsr) & TXR) {

                        outportb(uart_data, tx_queue[tx_out++]);

                        if (tx_out == TX_QUEUE_SIZE)

                            tx_out = 0;

                        tx_chars--;

                        }

                    }                           /* End 'tx buffer not empty */

                break;



            case 4:                             /* Received data interrupt */

                c = inportb(uart_data);         /* Grab received character */

                if (rx_chars < RX_QUEUE_SIZE) { /* If queue not full, save */

                    rx_queue[rx_in++] = c;      /*  the new character */

                    if (rx_in == RX_QUEUE_SIZE) /* Wrap index if needed */

                        rx_in = 0;

                    rx_chars++;                 /* Count the new character */

                    }                           /* End queue not full */

                break;



            case 6:                             /* Line status interrupt */

                inportb(uart_lsr);              /* Just clear the interrupt */

                break;



            }                                   /* End switch */

        }                                       /* End 'is an interrupt' */

    outportb(0x20, 0x20);                       /* Send EOI to 8259 */

    }                                           /* End com_interrupt_driver() */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -