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

📄 usartat91.c

📁 含有完整TCP/IP PPP协议的嵌入式操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
 * * \param mode 0 (disabled), 1 (odd) or 2 (even) * * \return 0 on success, -1 otherwise. */static int At91UsartSetParity(u_char mode){    ureg_t val = inr(USARTn_BASE + US_MR_OFF) & ~US_PAR;    switch (mode) {    case 0:        val |= US_PAR_NO;        break;    case 1:        val |= US_PAR_ODD;        break;    case 2:        val |= US_PAR_EVEN;        break;    }    At91UsartDisable();    outr(USARTn_BASE + US_MR_OFF, val);    At91UsartEnable();    /*     * Verify the result.     */    if (At91UsartGetParity() != mode) {        return -1;    }    return 0;}/*! * \brief Query the USART hardware for the number of stop bits. * * This routine is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \return The number of stop bits set, either 1, 2 or 3 (1.5 bits). */static u_char At91UsartGetStopBits(void){    ureg_t val = inr(USARTn_BASE + US_MR_OFF) & US_NBSTOP;    if (val == US_NBSTOP_1) {        val = 1;    }    else if (val == US_NBSTOP_2) {        val = 2;    }    else {        val = 3;    }    return (u_char)val;}/*! * \brief Set the USART hardware to the number of stop bits. * * This routine is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \return 0 on success, -1 otherwise. */static int At91UsartSetStopBits(u_char bits){    ureg_t val = inr(USARTn_BASE + US_MR_OFF) & ~US_NBSTOP;    switch(bits) {    case 1:        val |= US_NBSTOP_1;        break;    case 2:        val |= US_NBSTOP_2;        break;    case 3:        val |= US_NBSTOP_1_5;        break;    }    At91UsartDisable();    outr(USARTn_BASE + US_MR_OFF, val);    At91UsartEnable();    /*     * Verify the result.     */    if (At91UsartGetStopBits() != bits) {        return -1;    }    return 0;}/*! * \brief Query the USART hardware status. * * \return Status flags. */static u_long At91UsartGetStatus(void){    u_long rc = 0;    /*     * Set receiver error flags.     */    if ((rx_errors & US_FRAME) != 0) {        rc |= UART_FRAMINGERROR;    }    if ((rx_errors & US_OVRE) != 0) {        rc |= UART_OVERRUNERROR;    }    if ((rx_errors & US_PARE) != 0) {        rc |= UART_PARITYERROR;    }    /*     * Determine software handshake status. The flow control status may     * change during interrupt, but this doesn't really hurt us.     */    if (flow_control) {        if (flow_control & XOFF_SENT) {            rc |= UART_RXDISABLED;        }        if (flow_control & XOFF_RCVD) {            rc |= UART_TXDISABLED;        }    }#ifdef UART_RTS_BIT    /*     * Determine hardware handshake control status.     */    if (bit_is_set(UART_RTS_PORT, UART_RTS_BIT)) {        rc |= UART_RTSDISABLED;        if (rts_control) {            rc |= UART_RXDISABLED;        }    } else {        rc |= UART_RTSENABLED;    }#endif#ifdef UART_CTS_BIT    /*     * Determine hardware handshake sense status.     */    if (bit_is_set(UART_CTS_PIN, UART_CTS_BIT)) {        rc |= UART_CTSDISABLED;        if (cts_sense) {            rc |= UART_RXDISABLED;        }    } else {        rc |= UART_CTSENABLED;    }#endif    /*     * If transmitter and receiver haven't been detected disabled by any     * of the checks above, then they are probably enabled.     */    if ((rc & UART_RXDISABLED) == 0) {        rc |= UART_RXENABLED;    }    if ((rc & UART_TXDISABLED) == 0) {        rc |= UART_TXENABLED;    }    /*     * Process multidrop setting.     */    if (tx_aframe) {        rc |= UART_TXADDRFRAME;    } else {        rc |= UART_TXNORMFRAME;    }    return rc;}/*! * \brief Set the USART hardware status. * * \param flags Status flags. * * \return 0 on success, -1 otherwise. */static int At91UsartSetStatus(u_long flags){    /*     * Process software handshake control.     */    if (flow_control) {        /* Access to the flow control status must be atomic. */        NutEnterCritical();        /*         * 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;    }    /*     * Clear UART receive errors.     */    if (flags & UART_ERRORS) {        outr(USARTn_BASE + US_CR_OFF, US_RSTSTA);    }    /*     * Verify the result.     */    if ((At91UsartGetStatus() & ~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 At91UsartGetClockMode(void){    u_char rc = 0;    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 At91UsartSetClockMode(u_char mode){    /*     * Verify the result.     */    if (At91UsartGetClockMode() != 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 At91UsartGetFlowControl(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 At91UsartSetFlowControl(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, At91UsartCts, 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, At91UsartTxComplete, &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 (At91UsartGetFlowControl() != 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 At91UsartTxStart(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. */    outr(USARTn_BASE + US_IER_OFF, US_TXRDY);}/*! * \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 At91UsartRxStart(void){    /*     * Do any required software flow control.     */    if (flow_control && (flow_control & XOFF_SENT) != 0) {        NutEnterCritical();        if ((inr(USARTn_BASE + US_CSR_OFF) & US_TXRDY)) {            outr(USARTn_BASE + US_THR_OFF, 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 At91UsartInit(void){    /*     * Register receive and transmit interrupts.     */    if (NutRegisterIrqHandler(&SIG_UART, At91UsartInterrupt, &dcb_usart)) {        return -1;    }    /* Enable UART clock. */    outr(PS_PCER, _BV(US_ID));    /* Disable GPIO on UART tx/rx pins. */    outr(PIO_PDR, US_GPIO_PINS);    /* Reset UART. */    outr(USARTn_BASE + US_CR_OFF, US_RSTRX | US_RSTTX | US_RXDIS | US_TXDIS);    /* Disable all UART interrupts. */    outr(USARTn_BASE + US_IDR_OFF, 0xFFFFFFFF);    /* Clear UART counter registers. */    outr(USARTn_BASE + US_RCR_OFF, 0);    outr(USARTn_BASE + US_TCR_OFF, 0);    /* Set UART baud rate generator register. */    outr(USARTn_BASE + US_BRGR_OFF, AT91_US_BAUD(115200));    /* Set UART mode to 8 data bits, no parity and 1 stop bit. */    outr(USARTn_BASE + US_MR_OFF, US_CHMODE_NORMAL | US_CHRL_8 | US_PAR_NO | US_NBSTOP_1);    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 At91UsartDeinit(void){    /* Deregister receive and transmit interrupts. */    NutRegisterIrqHandler(&SIG_UART, 0, 0);    /* Reset UART. */    outr(USARTn_BASE + US_CR_OFF, US_RSTRX | US_RSTTX | US_RXDIS | US_TXDIS);    /* Disable all UART interrupts. */    outr(USARTn_BASE + US_IDR_OFF, 0xFFFFFFFF);    /* Disable UART clock. */    outr(PS_PCDR, _BV(US_ID));    /* Enable GPIO on UART tx/rx pins. */    outr(PIO_PER, US_GPIO_PINS);    /*     * 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 + -