📄 serial.c
字号:
/*
********************************************************************************
* Wiznet.
* 5F Simmtech Bldg., 228-3, Nonhyun-dong, Kangnam-gu,
* Seoul, Korea
*
* (c) Copyright 2002, Wiznet, Seoul, Korea
*
* Filename : serial.c
* Version : 1.0
* Programmer(s) :
* Created : 2003/01/28
* Modified :
*
* Description : UART functions for EVBAVR VER 1.0 (AVR-GCC Compiler)
********************************************************************************
*/
/*
*******************************************************************************
Include Part
*******************************************************************************
*/
#include <avr/io.h>
#include <stdio.h>
#include <avr/signal.h>
#include "serial.h"
/*
*******************************************************************************
Define Part
*******************************************************************************
*/
/*
*******************************************************************************
Global Variable Definition Part
*******************************************************************************
*/
/*
*******************************************************************************
Local Variable Definition Part
*******************************************************************************
*/
uint8 sio_rxd[UART_DEVICE_CNT][MAX_SIO_COUNT];
int sio_head[UART_DEVICE_CNT]; /* a pointer to serial Rx buffer */
int sio_tail[UART_DEVICE_CNT]; /* a pointer to serial Rx buffer */
uint8 SIO_FLOW[UART_DEVICE_CNT];
uint8 bXONOFF[UART_DEVICE_CNT]; /* XON/XOFF flag bit : 0 bit(1-MY XOFF State, 0-MY XON State), 1 bit(1 - Peer XOFF, 0-Peer XON) */
#define SET_MY_XOFF_STATE(X) (bXONOFF[X] |= 0x01)
#define SET_MY_XON_STATE(X) (bXONOFF[X] &= ~(0x01))
#define SET_PEER_XOFF_STATE(X) (bXONOFF[X] |= 0x02)
#define SET_PEER_XON_STATE(X) (bXONOFF[X] &= ~(0x02))
UARTHANDLER uart_handler[2];
/*
*******************************************************************************
Function Prototype Declaration Part
*******************************************************************************
*/
/*
*******************************************************************************
Function Implementation Part
*******************************************************************************
*/
/*
********************************************************************************
* ATmega64 UART Rx ISR
*
* Description : This function is the signal handler for receive complete interrupt
* Arguments : None
* Returns : None
* Note : Internal Function
********************************************************************************
*/
SIGNAL(SIG_UART0_RECV)
{
sio_rxd[0][sio_head[0]] = UDR0; /* read RX data from UART0 */
if(SIO_FLOW[0])
{
if(sio_rxd[0][sio_head[0]] == XOFF_CHAR)
SET_PEER_XOFF_STATE(0);
else if(sio_rxd[0][sio_head[0]] == XON_CHAR)
SET_PEER_XON_STATE(0);
else sio_head[0]++;
}
else sio_head[0]++;
if (sio_head[0] == sio_tail[0])
{
if(SIO_FLOW[0])
{
while (!(UCSR0A & 0x20)) ;
UDR0 = XOFF_CHAR;
SET_MY_XOFF_STATE(0);
}
sio_head[0]--; /* buffer full. */
}
if (sio_head[0] >= MAX_SIO_COUNT) /* for ring buffer */
{
sio_head[0] = 0;
if (sio_head[0] == sio_tail[0]) sio_head[0] = MAX_SIO_COUNT;
}
}
void uart1_irq(void)
{
sio_rxd[1][sio_head[1]] = UDR1; /* read RX data from UART0 */
if(SIO_FLOW[1])
{
if(sio_rxd[1][sio_head[1]] == XOFF_CHAR)
SET_PEER_XOFF_STATE(1);
else if(sio_rxd[1][sio_head[1]] == XON_CHAR)
SET_PEER_XON_STATE(1);
else sio_head[1]++;
}
else sio_head[1]++;
if (sio_head[1] == sio_tail[1])
{
if(SIO_FLOW[1])
{
while (!(UCSR1A & 0x20)) ;
UDR1 = XOFF_CHAR;
SET_MY_XOFF_STATE(1);
}
sio_head[1]--; /* buffer full. */
}
if (sio_head[1] >= MAX_SIO_COUNT) /* for ring buffer */
{
sio_head[1] = 0;
if (sio_head[1] == sio_tail[1]) sio_head[1] = MAX_SIO_COUNT;
}
}
/*
********************************************************************************
* INIT. UART
*
* Description : This function initializes the UART of ATmega64
* Arguments : None
* Returns : None
* Note :
********************************************************************************
*/
void uart_init(uint8 uart, uint8 baud_index)
{
// DDRG = 0xff; /* DED5(4), DED6(3), ALE(2), /RD(1), /WR(0) : all out */
// PORTG = 0xff; /* All 1(High) output */
/* enable RxD/TxD and RX INT */
if(!uart)
{
UCSR0B = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
/* set baud rate */
/*
/* for 16MHz
UBRR0H = (uint8) ((UART_BAUD_SELECT(baud_index) >> 8) & 0xFF);
UBRR0L = (uint8) (UART_BAUD_SELECT(baud_index)& 0xFF);
*/
// for 16MHz
UBRR0L = 16; // 57600 @ 8Mhz
// for 8MHz
//UBRR0L = 8; // 57600 @ 8Mhz
uart_handler[0].uart_get_handler = uart0_getchar;
uart_handler[0].uart_put_handler = uart0_putchar;
if(!uart)fdevopen(uart0_putchar, uart0_getchar, 0);
}
else
{
UCSR1B = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
/* set baud rate */
UBRR1H = (uint8) ((UART_BAUD_SELECT(baud_index) >> 8) & 0xFF);
UBRR1L = (uint8) (UART_BAUD_SELECT(baud_index)& 0xFF);
uart_handler[1].uart_get_handler = uart1_getchar;
uart_handler[1].uart_put_handler = uart1_putchar;
}
sio_head[uart] = 0;
sio_tail[uart] = 0;
SIO_FLOW[uart] = 0;
bXONOFF[uart] = 0;
}
void uart_databit(uint8 uart, uint8 dbit)
{
if(!uart)
{
UCSR0C |= 1 << 3;
if(!dbit) UCSR0C &= ~(1<<1); // 7bit
else UCSR0C |= (1<<1); // 8bit;
}
else
{
UCSR1C |= 1 << 3;
if(!dbit) UCSR1C &= ~(1<<1); // 7bit
else UCSR1C |= (1<<1); // 8bit;
}
}
void uart_stopbit(uint8 uart,uint8 sbit)
{
if(!uart)
{
if(!sbit) UCSR0C &= ~(1 << 3); // 1 BIT
else UCSR0C |= (1 << 3); // 2 BIT
}
else
{
if(!sbit) UCSR1C &= ~(1 << 3); // 1 BIT
else UCSR1C |= (1 << 3); // 2 BIT}
}
}
void uart_paritybit(uint8 uart,uint8 pbit)
{
if(!uart)
{
if(!pbit) UCSR0C &= ~(3 << 4); // none
else if (pbit ==1) UCSR0C &= ~(1 << 4); // even
else UCSR0C |= (3 << 4); // odd
}
else
{
if(!pbit) UCSR1C &= ~(3 << 4); // none
else if (pbit ==1) UCSR1C &= ~(1 << 4); // even
else UCSR1C |= (3 << 4); // odd
}
}
void uart_flowctrl(uint8 uart,uint8 flow)
{
SIO_FLOW[uart] = flow;
}
/*
********************************************************************************
* CHECK RX
*
* Description : This function checks if there is Rx.
* Arguments : None
* Returns : retunr RX size, if there is Rx.
* if not, return 0
* Note :
********************************************************************************
*/
uint16 uart_keyhit(uint8 uart)
{
if(sio_head[uart] >= sio_tail[uart] ) return (sio_head[uart]-sio_tail[uart]);
else return (MAX_SIO_COUNT-(sio_tail[uart]-sio_head[uart]));
}
/*
********************************************************************************
* WRITE A CHARACTER
*
* Description : This function sends a character through UART.
* Arguments : c - is a character to write
* Returns : None.
* Note :
********************************************************************************
*/
void uart0_putchar(char c)
{
while(SIO_FLOW[0] && (bXONOFF[0] & 0x02)); // If Peer XOFF STATE
while (!(UCSR0A & 0x20)) ;
UDR0 = c;
}
/*
********************************************************************************
* READ A CHARACTER
*
* Description : This function gets a character from UART.
* Arguments : None
* Returns : c - is a character to read
* Note :
********************************************************************************
*/
char uart0_getchar(void)
{
char c;
while (sio_head[0] == sio_tail[0]);
c = sio_rxd[0][sio_tail[0]++];
if(SIO_FLOW[0] && (bXONOFF[0] & 0x01)) // IF MY XOFF STATE
{
while (!(UCSR0A & 0x20)) ;
UDR0 = XON_CHAR;
SET_MY_XON_STATE(0);
}
if (sio_tail[0] >= MAX_SIO_COUNT) sio_tail[0] = 0;
return c;
}
/*
********************************************************************************
* WRITE A CHARACTER
*
* Description : This function sends a character through UART.
* Arguments : c - is a character to write
* Returns : None.
* Note :
********************************************************************************
*/
void uart1_putchar(char c)
{
while(SIO_FLOW[1] && (bXONOFF[1] & 0x02)); // If Peer XOFF STATE
while (!(UCSR1A & 0x20)) ;
UDR1 = c;
}
/*
********************************************************************************
* READ A CHARACTER
*
* Description : This function gets a character from UART.
* Arguments : None
* Returns : c - is a character to read
* Note :
********************************************************************************
*/
char uart1_getchar(void)
{
char c;
while (sio_head[1] == sio_tail[1]);
c = sio_rxd[1][sio_tail[1]++];
if(SIO_FLOW[1] && (bXONOFF[1] & 0x01)) // IF MY XOFF STATE
{
while (!(UCSR1A & 0x20)) ;
UDR1 = XON_CHAR;
SET_MY_XON_STATE(1);
}
if (sio_tail[1] >= MAX_SIO_COUNT) sio_tail[1] = 0;
return c;
}
/*
********************************************************************************
* WRITE A STRING
*
* Description : This function sends a string to UART.
* Arguments : str - is a pointer to the string to write
* Returns : None
* Note :
********************************************************************************
*/
void uart_puts(uint8 uart, char * str)
{
int i;
i = 0;
while (str[i]) (*uart_handler[uart].uart_put_handler)(str[i++]);
}
/*
********************************************************************************
* READ A CHARACTER
*
* Description : This function gets a string from UART.
* Arguments : None
* Returns : str - is a pointer to the string to read
* Note :
********************************************************************************
*/
int uart_gets(uint8 uart, char * str, char bpasswordtype, int max_len)
{
char c;
char * tsrc = str;
char IsFirst = 1;
int len = 0;
while ((c = (*uart_handler[uart].uart_get_handler)()) != 0x0D)
{
if (IsFirst && c=='!')
{
while(*str != '\0') (*uart_handler[uart].uart_put_handler)(*str++);
IsFirst = 0;
len++;
continue;
}
if (c == 0x08 && tsrc != str)
{
(*uart_handler[uart].uart_put_handler)(0x08);
(*uart_handler[uart].uart_put_handler)(' ');
(*uart_handler[uart].uart_put_handler)(0x08);
str--;
len--;
continue;
}
else if (c == 0x1B)
{
while (tsrc != str)
{
(*uart_handler[uart].uart_put_handler)(0x08);
(*uart_handler[uart].uart_put_handler)(' ');
(*uart_handler[uart].uart_put_handler)(0x08);
str--;
len--;
}
IsFirst = 1;
continue;
}
else if ((c < 32 || c > 126) && c != '\t') continue;
if(len < max_len)
{
if(bpasswordtype) (*uart_handler[uart].uart_put_handler)('*');
else (*uart_handler[uart].uart_put_handler)(c);
*str++ = c;
len++;
IsFirst = 0;
}
}
*str = '\0';
uart_puts(uart,"\r\n");
return len;
}
/*
********************************************************************************
* GET A BYTE
*
* Description : This function flush rx buffer of serial
* Arguments : None
* Returns :
* Note :
********************************************************************************
*/
void uart_flush_rx(uint8 uart)
{
sio_head[uart] = sio_tail[uart];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -