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

📄 usartavr.c

📁 avr上的RTOS
💻 C
📖 第 1 页 / 共 3 页
字号:
         * Enabling or disabling the receiver means to behave like         * having sent a XON or XOFF character resp.         */        if (flags & UART_RXENABLED) {            flow_control &= ~XOFF_SENT;        } else if (flags & UART_RXDISABLED) {            flow_control |= XOFF_SENT;        }        /*         * Enabling or disabling the transmitter means to behave like         * having received a XON or XOFF character resp.         */        if (flags & UART_TXENABLED) {            flow_control &= ~XOFF_RCVD;        } else if (flags & UART_TXDISABLED) {            flow_control |= XOFF_RCVD;        }        NutExitCritical();    }#ifdef UART_RTS_BIT    /*     * Process hardware handshake control.     */    if (rts_control) {        if (flags & UART_RXDISABLED) {            sbi(UART_RTS_PORT, UART_RTS_BIT);        }        if (flags & UART_RXENABLED) {            cbi(UART_RTS_PORT, UART_RTS_BIT);        }    }    if (flags & UART_RTSDISABLED) {        sbi(UART_RTS_PORT, UART_RTS_BIT);    }    if (flags & UART_RTSENABLED) {        cbi(UART_RTS_PORT, UART_RTS_BIT);    }#endif    /*     * Process multidrop setting.     */    if (flags & UART_TXADDRFRAME) {        tx_aframe = 1;    }    if (flags & UART_TXNORMFRAME) {        tx_aframe = 0;    }#ifdef __AVR_ENHANCED__    if (flags & UART_RXADDRFRAME) {        sbi(UCSRnA, MPCM);    }    if (flags & UART_RXNORMFRAME) {        cbi(UCSRnA, MPCM);    }#endif    /*     * Clear UART receive errors.     */    if (flags & UART_FRAMINGERROR) {        rx_errors &= ~_BV(FE);    }    if (flags & UART_OVERRUNERROR) {        rx_errors &= ~_BV(DOR);    }#ifdef __AVR_ENHANCED__    if (flags & UART_PARITYERROR) {        rx_errors &= ~_BV(UPE);    }#endif    /*     * Verify the result.     */    if ((AvrUsartGetStatus() & ~UART_ERRORS) != flags) {        return -1;    }    return 0;}/*! * \brief Query the USART hardware for synchronous mode. * * This function is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \return Or-ed combination of \ref UART_SYNC, \ref UART_MASTER, *         \ref UART_NCLOCK and \ref UART_HIGHSPEED. */static u_char AvrUsartGetClockMode(void){    u_char rc = 0;#ifdef __AVR_ENHANCED__    if (bit_is_set(UCSRnC, UMSEL)) {        rc |= UART_SYNC;        if (bit_is_set(DDRE, 2)) {            rc |= UART_MASTER;        }        if (bit_is_set(UCSRnC, UCPOL)) {            rc |= UART_NCLOCK;        }    } else if (bit_is_set(UCSRnA, U2X)) {        rc |= UART_HIGHSPEED;    }#endif    return rc;}/*! * \brief Set asynchronous or synchronous mode. * * This function is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \param mode Must be an or-ed combination of USART_SYNC, USART_MASTER, *             USART_NCLOCK and USART_HIGHSPEED. * * \return 0 on success, -1 otherwise. */static int AvrUsartSetClockMode(u_char mode){#ifdef __AVR_ENHANCED__    AvrUsartDisable();    /*     * Handle synchronous mode.     */    if (mode & UART_SYNC) {        if (mode & UART_MASTER) {            /* Enable master mode. */            sbi(DDRE, 2);        } else {            /* Disable master mode. */            cbi(DDRE, 2);        }        if (mode & UART_NCLOCK) {            /* Enable negated clock. */            sbi(UCSRnC, UCPOL);        } else {            /* Disable negated clock. */            cbi(UCSRnC, UCPOL);        }        /* Disable high speed. */        cbi(UCSRnA, U2X);        /* Enable synchronous mode. */        sbi(UCSRnA, UMSEL);    }    /*     * Handle asynchronous mode.     */    else {        if (mode & UART_HIGHSPEED) {            /* Enable high speed. */            sbi(UCSRnA, U2X);        } else {            /* Disable high speed. */            cbi(UCSRnA, U2X);        }        /* Disable negated clock. */        cbi(UCSRnC, UCPOL);        /* Disable synchronous mode. */        cbi(UCSRnC, UMSEL);    }    AvrUsartEnable();#endif    /*     * Verify the result.     */    if (AvrUsartGetClockMode() != mode) {        return -1;    }    return 0;}/*! * \brief Query flow control mode. * * This routine is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \return See UsartIOCtl(). */static u_long AvrUsartGetFlowControl(void){    u_long rc = 0;    if (flow_control) {        rc |= USART_MF_XONXOFF;    } else {        rc &= ~USART_MF_XONXOFF;    }#ifdef UART_RTS_BIT    if (rts_control) {        rc |= USART_MF_RTSCONTROL;    } else {        rc &= ~USART_MF_RTSCONTROL;    }#endif#ifdef UART_CTS_BIT    if (cts_sense) {        rc |= USART_MF_CTSSENSE;    } else {        rc &= ~USART_MF_CTSSENSE;    }#endif#ifdef UART_HDX_BIT    if (hdx_control) {        rc |= USART_MF_HALFDUPLEX;    } else {        rc &= ~USART_MF_HALFDUPLEX;    }#endif    return rc;}/*! * \brief Set flow control mode. * * This function is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \param flags See UsartIOCtl(). * * \return 0 on success, -1 otherwise. */static int AvrUsartSetFlowControl(u_long flags){    /*     * Set software handshake mode.     */    if (flags & USART_MF_XONXOFF) {        if(flow_control == 0) {            NutEnterCritical();            flow_control = 1 | XOFF_SENT;  /* force XON to be sent on next read */            NutExitCritical();        }    } else {        NutEnterCritical();        flow_control = 0;        NutExitCritical();    }#ifdef UART_RTS_BIT    /*     * Set RTS control mode.     */    if (flags & USART_MF_RTSCONTROL) {        sbi(UART_RTS_PORT, UART_RTS_BIT);        sbi(UART_RTS_DDR, UART_RTS_BIT);        rts_control = 1;    } else if (rts_control) {        rts_control = 0;        cbi(UART_RTS_DDR, UART_RTS_BIT);    }#endif#ifdef UART_CTS_BIT    /*     * Set CTS sense mode.     */    if (flags & USART_MF_CTSSENSE) {        /* Register CTS sense interrupt. */        if (NutRegisterIrqHandler(&UART_CTS_SIGNAL, AvrUsartCts, 0)) {            return -1;        }        sbi(UART_CTS_PORT, UART_CTS_BIT);        cbi(UART_CTS_DDR, UART_CTS_BIT);        cts_sense = 1;    } else if (cts_sense) {        cts_sense = 0;        /* Deregister CTS sense interrupt. */        NutRegisterIrqHandler(&UART_CTS_SIGNAL, 0, 0);        cbi(UART_CTS_DDR, UART_CTS_BIT);    }#endif#ifdef UART_HDX_BIT    /*     * Set half duplex mode.     */    if (flags & USART_MF_HALFDUPLEX) {        /* Register transmit complete interrupt. */        if (NutRegisterIrqHandler(&sig_UART_TRANS, AvrUsartTxComplete, &dcb_usart.dcb_rx_rbf)) {            return -1;        }        /* Initially enable the receiver. */        UART_HDX_RX(UART_HDX_PORT, UART_HDX_BIT);        sbi(UART_HDX_DDR, UART_HDX_BIT);        hdx_control = 1;        /* Enable transmit complete interrupt. */        sbi(UCSRnB, TXCIE);    } else if (hdx_control) {        hdx_control = 0;        /* disable transmit complete interrupt */        cbi(UCSRnB, TXCIE);        /* Deregister transmit complete interrupt. */        NutRegisterIrqHandler(&sig_UART_TRANS, 0, 0);        cbi(UART_HDX_DDR, UART_HDX_BIT);    }#endif    /*     * Verify the result.     */    if (AvrUsartGetFlowControl() != flags) {        return -1;    }    return 0;}/*! * \brief Start the USART transmitter hardware. * * The upper level USART driver will call this function through the * USARTDCB jump table each time it added one or more bytes to the * transmit buffer. */static void AvrUsartTxStart(void){#ifdef UART_HDX_BIT    if (hdx_control) {        /* Enable half duplex transmitter. */	UART_HDX_TX(UART_HDX_PORT, UART_HDX_BIT);    }#endif    /* Enable transmit interrupts. */    sbi(UCSRnB, UDRIE);}/*! * \brief Start the USART receiver hardware. * * The upper level USART driver will call this function through the * USARTDCB jump table each time it removed enough bytes from the * receive buffer. Enough means, that the number of bytes left in * the buffer is below the low watermark. */static void AvrUsartRxStart(void){    /*     * Do any required software flow control.     */    if (flow_control && (flow_control & XOFF_SENT) != 0) {        NutEnterCritical();        if (inb(UCSRnA) & _BV(UDRE)) {            outb(UDRn, ASCII_XON);            flow_control &= ~XON_PENDING;        } else {            flow_control |= XON_PENDING;        }        flow_control &= ~(XOFF_SENT | XOFF_PENDING);        NutExitCritical();    }#ifdef UART_RTS_BIT    if (rts_control) {        /* Enable RTS. */        cbi(UART_RTS_PORT, UART_RTS_BIT);    }#endif}/* * \brief Initialize the USART hardware driver. * * This function is called during device registration by the upper level * USART driver through the USARTDCB jump table. * * \return 0 on success, -1 otherwise. */static int AvrUsartInit(void){#ifndef USE_USART    /*     * Register receive and transmit interrupts.     */    if (NutRegisterIrqHandler(&sig_UART_RECV, AvrUsartRxComplete, &dcb_usart.dcb_rx_rbf))        return -1;    if (NutRegisterIrqHandler(&sig_UART_DATA, AvrUsartTxEmpty, &dcb_usart.dcb_tx_rbf)) {        NutRegisterIrqHandler(&sig_UART_RECV, 0, 0);        return -1;    }#endif    return 0;}/* * \brief Deinitialize the USART hardware driver. * * This function is called during device deregistration by the upper * level USART driver through the USARTDCB jump table. * * \return 0 on success, -1 otherwise. */static int AvrUsartDeinit(void){#ifndef USE_USART    /* Deregister receive and transmit interrupts. */    NutRegisterIrqHandler(&sig_UART_RECV, 0, 0);    NutRegisterIrqHandler(&sig_UART_DATA, 0, 0);#endif    /*     * Disabling flow control shouldn't be required here, because it's up     * to the upper level to do this on the last close or during     * deregistration.     */#ifdef UART_HDX_BIT    /* Deregister transmit complete interrupt. */    if (hdx_control) {        hdx_control = 0;        NutRegisterIrqHandler(&sig_UART_TRANS, 0, 0);    }#endif#ifdef UART_CTS_BIT    if (cts_sense) {        cts_sense = 0;        cbi(UART_CTS_DDR, UART_CTS_BIT);        /* Deregister CTS sense interrupt. */        NutRegisterIrqHandler(&UART_CTS_SIGNAL, 0, 0);    }#endif#ifdef UART_RTS_BIT    if (rts_control) {        rts_control = 0;        cbi(UART_RTS_DDR, UART_RTS_BIT);    }#endif    return 0;}/*@}*/

⌨️ 快捷键说明

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