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

📄 uart.c

📁 AVR单片机模拟USB实现CDC类串行口
💻 C
字号:
/* Name: uart.c
 * Project: AVR USB driver for CDC interface on Low-Speed USB
 * Author: Osamu Tamura
 * Creation Date: 2006-06-18
 * Tabsize: 4
 * Copyright: (c) 2006 by Recursion Co., Ltd.
 * License: Proprietary, free under certain conditions. See Documentation.
 *
 * 2006-07-08   adapted to higher baud rate by T.Kitazawa
 */
/*
General Description:
    This module implements the UART rx/tx system of the USB-CDC driver.

Note: This module violates the rule that interrupts must not be disabled for
longer than a couple of instructions (see usbdrv.h). Running UART interrupt
handlers with sei as the first instruction is not possible because it would
recurse immediately (the cause of the interrupt has not been removed). If
we collect the data and then call sei(), we win little. We therefore decide
to violate the rule. The effect on USB operation is, that packages may be
lost. This is equivalent to a package being dropped due to a CRC error. The
host will therefore retry the transfer after a timeout. It is therefore very
likely that no effect is seen at the application layer.
*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>   /* needed by usbdrv.h */
#include "oddebug.h"
#include "uart.h"
#include "usbdrv.h"

#if UART_CFG_HAVE_USART

/* UART buffer */
uchar    rx_buf[RX_SIZE], tx_buf[TX_SIZE];
uchar    urptr, uwptr, irptr, iwptr;


#ifndef URSEL
#   define URSEL_MASK   0
#else
#   define URSEL_MASK   (1 << URSEL)
#endif

void uartInit(ulong baudrate, uchar parity, uchar stopbits, uchar databits)
{
usbDWord_t   br;

    br.dword = F_CPU / (8L * baudrate) - 1;
	UCSR0A  |= (1<<U2X0);

#if DEBUG_LEVEL < 1
    /*    USART configuration    */
    UCSR0B  = 0;
    UCSR0C  = URSEL_MASK | ((parity==1? 3:parity)<<UPM00) | ((stopbits>>1)<<USBS0) | ((databits-5)<<UCSZ00);
    UBRR0L  = br.bytes[0];
    UBRR0H  = br.bytes[1];
#else
    DBG1(0xf0, br.bytes, 2);
#endif /* DEBUG_LEVEL */

#ifdef USE_UART_RXD_INTERRUPT
    UCSR0B  = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0);
#else
    UCSR0B  = (1<<RXEN0) | (1<<TXEN0);
#endif
}

void uartPoll(void)
{

	/* transmit */
	if( (UCSR0A&(1<<UDRE0)) && uwptr!=irptr ) {
        UDR0    = tx_buf[irptr];
        irptr   = (irptr + 1) & TX_MASK;

        /*    usb -> rs232c:  ready to receive?    */
        if( usbAllRequestsAreDisabled() && uartTxBytesFree()>8 ) {
            usbEnableAllRequests();
        }
    }

#ifndef USE_UART_RXD_INTERRUPT
	/* recieve */
	if( UCSR0A&(1<<RXC0) ) {
        uchar   status, data;

        status  = UCSR0A;
        data    = UDR0;
        status  &= (1<<FE0) | (1<<DOR0) | (1<<UPE0);
        if(status == 0) /* no receiver error occurred */
            uartRxBufAppend( data );
    }
#endif
}

uchar uartRxIsBusy(void)
{
    return UCSR0A & (1<<RXC0);
}

#endif     /* UART_CFG_HAVE_USART */

⌨️ 快捷键说明

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