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

📄 usartavr.c

📁 avr上的RTOS
💻 C
📖 第 1 页 / 共 3 页
字号:
        /*         * Store the character and increment and the ring buffer pointer.         */        *rbf->rbf_head++ = ch;        if (rbf->rbf_head == rbf->rbf_last) {            rbf->rbf_head = rbf->rbf_start;        }        /* Update the ring buffer counter. */        rbf->rbf_cnt = cnt;#ifdef NUTTRACER        TRACE_ADD_ITEM(TRACE_TAG_INTERRUPT_EXIT,TRACE_INT_UART_RXCOMPL);#endif#ifdef UART_READMULTIBYTE    } while ( inb(UCSRnA) & _BV(RXC) ); // byte in buffer?    // Eventually post event to wake thread    if (postEvent)        NutEventPostFromIrq(&rbf->rbf_que);#endif}/*! * \brief Carefully enable USART hardware functions. * * Always enabale transmitter and receiver, even on read-only or * write-only mode. So we can support software flow control. */static void AvrUsartEnable(void){    NutEnterCritical();    outb(UCSRnB, _BV(RXCIE) | _BV(UDRIE) | _BV(RXEN) | _BV(TXEN));#ifdef UART_HDX_BIT    if (hdx_control) {        /* Enable transmit complete interrupt. */        sbi(UCSRnB, TXCIE);    }#endif    NutExitCritical();}/*! * \brief Carefully disable USART hardware functions. */static void AvrUsartDisable(void){    /*     * Disable USART interrupts.     */    NutEnterCritical();    cbi(UCSRnB, RXCIE);    cbi(UCSRnB, TXCIE);    cbi(UCSRnB, UDRIE);    NutExitCritical();    /*     * Allow incoming or outgoing character to finish.     */    NutDelay(10);    /*     * Disable USART transmit and receive.     */    cbi(UCSRnB, RXEN);    cbi(UCSRnB, TXEN);}/*! * \brief Query the USART hardware for the selected speed. * * This function is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \return The currently selected baudrate. */static u_long AvrUsartGetSpeed(void){    u_long fct;    u_short sv = (u_short) inb(UBRRnL);#ifdef __AVR_ENHANCED__    sv |= ((u_short) inb(UBRRnH) << 8);    /* Synchronous mode. */    if (bit_is_set(UCSRnC, UMSEL)) {        fct = 2UL;    }    /* Double rate mode. */    else if (bit_is_set(UCSRnA, U2X)) {        fct = 8UL;    }    /* Normal mode. */    else {        fct = 16UL;    }#else    fct = 16UL;#endif    return NutGetCpuClock() / (fct * ((u_long) sv + 1UL));}/*! * \brief Set the USART hardware bit rate. * * This function is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \param rate Number of bits per second. * * \return 0 on success, -1 otherwise. */static int AvrUsartSetSpeed(u_long rate){    u_short sv;    AvrUsartDisable();    /*     * Modified Robert Hildebrand's refined calculation.     */#ifdef __AVR_ENHANCED__    if (bit_is_clear(UCSRnC, UMSEL)) {        if (bit_is_set(UCSRnA, U2X)) {            rate <<= 2;        } else {            rate <<= 3;        }    }#else    rate <<= 3;#endif    sv = (u_short) ((NutGetCpuClock() / rate + 1UL) / 2UL) - 1;    outb(UBRRnL, (u_char) sv);#ifdef __AVR_ENHANCED__    outb(UBRRnH, (u_char) (sv >> 8));#endif    AvrUsartEnable();    return 0;}/*! * \brief Query the USART hardware for the number of data bits. * * This function is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \return The number of data bits set. */static u_char AvrUsartGetDataBits(void){    if (bit_is_set(UCSRnB, UCSZ2)) {        return 9;    }#ifdef __AVR_ENHANCED__    if (bit_is_set(UCSRnC, UCSZ1)) {        if (bit_is_set(UCSRnC, UCSZ0)) {            return 8;        } else {            return 7;        }    } else if (bit_is_set(UCSRnC, UCSZ0)) {        return 6;    }    return 5;#else    return 8;#endif}/*! * \brief Set the USART hardware to the number of data bits. * * This function is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \return 0 on success, -1 otherwise. */static int AvrUsartSetDataBits(u_char bits){    AvrUsartDisable();    cbi(UCSRnB, UCSZ2);#ifdef __AVR_ENHANCED__    cbi(UCSRnC, UCSZ0);    cbi(UCSRnC, UCSZ1);    switch (bits) {    case 6:        sbi(UCSRnC, UCSZ0);        break;    case 9:        sbi(UCSRnB, UCSZ2);    case 8:        sbi(UCSRnC, UCSZ0);    case 7:        sbi(UCSRnC, UCSZ1);        break;    }#else    if(bits == 9) {        sbi(UCSRnB, UCSZ2);    }#endif    AvrUsartEnable();    /*     * Verify the result.     */    if (AvrUsartGetDataBits() != bits) {        return -1;    }    return 0;}/*! * \brief Query the USART hardware for the parity mode. * * This routine is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \return Parity mode, either 0 (disabled), 1 (odd) or 2 (even). */static u_char AvrUsartGetParity(void){#ifdef __AVR_ENHANCED__    if (bit_is_set(UCSRnC, UPM1)) {        if (bit_is_set(UCSRnC, UPM0)) {            return 1;        } else {            return 2;        }    }#endif    return 0;}/*! * \brief Set the USART hardware to the specified parity mode. * * This routine is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \param mode 0 (disabled), 1 (odd) or 2 (even) * * \return 0 on success, -1 otherwise. */static int AvrUsartSetParity(u_char mode){#ifdef __AVR_ENHANCED__    AvrUsartDisable();    switch (mode) {    case 0:        cbi(UCSRnC, UPM0);        cbi(UCSRnC, UPM1);        break;    case 1:        sbi(UCSRnC, UPM0);        sbi(UCSRnC, UPM1);        break;    case 2:        cbi(UCSRnC, UPM0);        sbi(UCSRnC, UPM1);        break;    }    AvrUsartEnable();#endif    /*     * Verify the result.     */    if (AvrUsartGetParity() != 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 or 2. */static u_char AvrUsartGetStopBits(void){#ifdef __AVR_ENHANCED__    if (bit_is_set(UCSRnC, USBS)) {        return 2;    }#endif    return 1;}/*! * \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 AvrUsartSetStopBits(u_char bits){#ifdef __AVR_ENHANCED__    AvrUsartDisable();    if (bits == 1) {        cbi(UCSRnC, USBS);    } else if (bits == 2) {        sbi(UCSRnC, USBS);    }    AvrUsartEnable();#endif    /*     * Verify the result.     */    if (AvrUsartGetStopBits() != bits) {        return -1;    }    return 0;}/*! * \brief Query the USART hardware status. * * \return Status flags. */static u_long AvrUsartGetStatus(void){    u_long rc = 0;    /*     * Set receiver error flags.     */    if ((rx_errors & _BV(FE)) != 0) {        rc |= UART_FRAMINGERROR;    }    if ((rx_errors & _BV(DOR)) != 0) {        rc |= UART_OVERRUNERROR;    }#ifdef __AVR_ENHANCED__    if ((rx_errors & _BV(UPE)) != 0) {        rc |= UART_PARITYERROR;    }#endif    /*     * 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;    }#ifdef __AVR_ENHANCED__    if (bit_is_set(UCSRnA, MPCM)) {        rc |= UART_RXADDRFRAME;    } else {        rc |= UART_RXNORMFRAME;    }#else    rc |= UART_RXNORMFRAME;#endif    return rc;}/*! * \brief Set the USART hardware status. * * \param flags Status flags. * * \return 0 on success, -1 otherwise. */static int AvrUsartSetStatus(u_long flags){    /*     * Process software handshake control.     */    if (flow_control) {        /* Access to the flow control status must be atomic. */        NutEnterCritical();        /*

⌨️ 快捷键说明

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