📄 uart.c
字号:
/*************************************************************************/
/* */
/* FILE NAME VERSION */
/* */
/* source\uart.c 1.0 */
/* */
/* DESCRIPTION */
/* */
/* UART LIB CODE for S3C4510B0 */
/* */
/* */
/* DATA STRUCTURES */
/* */
/* FUNCTIONS : UART initialization and library */
/* */
/* DEPENDENCIES */
/* */
/* */
/* NAME: Nicolas Park */
/* The last Modification date: 18-April-2002 */
/* REMARKS: Created initial version 1.0 */
/* */
/* Copyright (C) 2002 AIJISYSTEM CO.,LTD */
/*************************************************************************/
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "apdialog.h"
#include "s3c4510b0.h"
#include "uart.h"
#include "isr.h"
#include "pollio.h"
#include "sysconf.h"
/* Define references to external structures */
SERIAL_DEV uart_dev_init;
UART_BUFFER RxQ[NUM_OF_SERIAL_DEV],TxQ[NUM_OF_SERIAL_DEV];
BaudTable U_BaudRate[BAUD_TABLE] = {
/* for 50MHz/2 UART clock */
9600, 0x00a20,
19200, 0x00500,
38400, 0x00280,
57600, 0x001a0,
115200, 0x000d0,
230400, 0x00060,
460800, 0x00020 // not available
};
uint32 UART_Initialize()
{
Disable_Int(nGLOBAL_INT); /* Global interrupt disabled */
/*****************************/
/* Initialize UART channel 0 */
/*****************************/
uart_dev_init.com_port = SERIAL_DEV0; /* com 0 */
uart_dev_init.baud_rate = baudrate;
uart_dev_init.data_mode = (UCON_RXM_INTREQ|UCON_TXM_INTREQ|UCON_RXSTAT_INT);
uart_dev_init.parity = ULCON_PMD_NO; /* No parity */
uart_dev_init.stop_bits = 0; /* one bit */
uart_dev_init.data_bits = ULCON_WL8; /* 8bits */
uart_dev_init.clk_sel = 0; /* internal clock */
UART_Init(&uart_dev_init);
/*****************************/
/* Initialize UART channel 1 */
/*****************************/
uart_dev_init.com_port = SERIAL_DEV1; /* com 0 */
UART_Init(&uart_dev_init);
Enable_Int(nGLOBAL_INT); /* Global interrupt disabled */
return(SUCCESS);
}
/***************************/
/* Uart main Init function */
/***************************/
uint32 UART_Init(SERIAL_DEV *s)
{
uint32 rUARTBRD;
/* UART interrupt off */
UARTRxIntOff(s->com_port);
UARTTxIntOff(s->com_port);
/* Initialize UART transmit & receive Queue */
TxQInit(s->com_port);
RxQInit(s->com_port);
/* default baud rate will be set. sysconf.h */
rUARTBRD = 0x1a0; //57600bps or 0x280-38400bps
if(s->com_port)
{
/* Interrupt service routine setup */
SysSetInterrupt(nUART1_TX_INT, Uart1TxLisr);
SysSetInterrupt(nUART1_RX_ERR_INT, Uart1RxErrLisr);
UARTLCON1 = s->data_bits|s->stop_bits|s->parity|s->clk_sel;
UARTCONT1 = s->data_mode;
UARTBRD1 = rUARTBRD;
}
else
{
/* Interrupt service routine setup */
SysSetInterrupt(nUART0_TX_INT, Uart0TxLisr);
SysSetInterrupt(nUART0_RX_ERR_INT, Uart0RxErrLisr);
/* UART mode, default baud rate setup */
UARTLCON0 = s->data_bits|s->stop_bits|s->parity|s->clk_sel;
UARTCONT0 = s->data_mode;
UARTBRD0 = rUARTBRD;
}
return(SUCCESS);
}
/* Transmit Que initialize */
void TxQInit(uint32 channel)
{
int i;
for(i=0; i < MAXEVENT; i++)
{
TxQ[channel].buff[i] = '\0';
}
TxQ[channel].wptr = 0;
TxQ[channel].rptr = 0;
}
/* Receive Que initialize */
void RxQInit(uint32 channel)
{
int i;
for(i=0; i < MAXEVENT; i++)
{
RxQ[channel].buff[i] = '\0';
}
RxQ[channel].wptr = 0;
RxQ[channel].rptr = 0;
}
void Uart0TxLisr(void)
{
if(UARTSTAT0 & USTAT_TXB_EMPTY)
{
if(TxQ[0].rptr == MAXEVENT)
TxQ[0].rptr=0; /*loop back*/
if(TxQ[0].rptr != TxQ[0].wptr)
{
UARTTXH0 = TxQ[0].buff[TxQ[0].rptr++];
}
}
UARTTxIntOff(0);
}
/* Rcv, Error Interrupt Service Routine */
void Uart0RxErrLisr(void)
{
if(!(UARTSTAT0 & USTAT_ERROR))
{
if(RxQ[0].wptr+1 != RxQ[0].rptr)
{
RxQ[0].buff[RxQ[0].wptr++] = UARTRXB0;
if(RxQ[0].wptr == MAXEVENT)
RxQ[0].wptr = 0; /*loop back*/
}
}
UARTRxIntOff(0);
}
void Uart1TxLisr(void)
{
if(UARTSTAT1 & USTAT_TXB_EMPTY)
{
if(++TxQ[1].rptr == MAXEVENT)
TxQ[1].rptr=0; /*loop back*/
if(TxQ[1].rptr != TxQ[1].wptr)
{
UARTTXH0 = TxQ[1].buff[TxQ[1].rptr];
}
}
UARTTxIntOff(1);
}
void Uart1RxErrLisr(void)
{
if(!(UARTSTAT1 & USTAT_ERROR))
{
if(RxQ[1].wptr+1 != RxQ[1].rptr)
{
RxQ[1].buff[RxQ[1].wptr++] = UARTRXB1;
if(RxQ[1].wptr == MAXEVENT)
RxQ[1].wptr = 0; /*loop back*/
}
}
UARTRxIntOff(1);
}
void UARTTxIntOn(uint32 channel)
{
if(channel) {
/* Enable Interrupt */
Enable_Int(nUART1_TX_INT);
SetPendingBit(nUART1_TX_INT);
}
else {
/* Enable Interrupt */
Enable_Int(nUART0_TX_INT);
SetPendingBit(nUART0_TX_INT);
}
}
void UARTRxIntOn(uint32 channel)
{
if(channel) {
/* Enable Interrupt */
Enable_Int(nUART1_RX_ERR_INT);
}
else {
/* Enable Interrupt */
Enable_Int(nUART0_RX_ERR_INT);
}
}
void UARTTxIntOff(uint32 channel)
{
if(channel) {
/* Enable Interrupt */
Disable_Int(nUART1_TX_INT);
Clear_PendingBit(nUART1_TX_INT) ;
}
else {
/* Disable Interrupt */
Disable_Int(nUART0_TX_INT);
Clear_PendingBit(nUART0_TX_INT) ;
}
}
void UARTRxIntOff(uint32 channel)
{
if(channel) {
/* Disable Interrupt */
Disable_Int(nUART1_RX_ERR_INT);
}
else {
/* Disable Interrupt */
Disable_Int(nUART0_RX_ERR_INT);
}
}
/* Transmit Que write function */
uint32 TxQWr(uint32 channel,uint8 data)
{
if(TxQ[channel].wptr+1 == TxQ[channel].rptr)
{
return(ERROR); /* ring buffer full state */
}
TxQ[channel].buff[TxQ[channel].wptr++] = data;
if(TxQ[channel].wptr == MAXEVENT)
{
TxQ[channel].wptr=0;
}
return(SUCCESS);
}
/* Receive Que read function */
uint8 RxQRd(uint32 channel)
{
if(RxQ[channel].rptr == MAXEVENT)
RxQ[channel].rptr=0; /*loop back*/
if(RxQ[channel].rptr == RxQ[channel].wptr)
return('\0');
return(RxQ[channel].buff[RxQ[channel].rptr++]);
}
uint8 i_getc(uint32 channel)
{
UARTRxIntOn(channel);
return(RxQRd(channel));
}
/* Interrupt get string */
uint32 i_gets(uint32 channel, uint8 *s)
{
uint32 count;
uint8 c;
count = 0;
while((c = (uint8)i_getc(channel)) != CR)
{
count++;
*s++ = c;
}
*s = (uint8)NULL;
return(count);
}
uint32 i_putc(uint32 channel, uint8 ch)
{
if(U_TX_COMPLETE(channel)) /* check transmit complet */
{
if(TxQWr(channel, ch)) /* write data to tx que */
{
UARTTxIntOn(channel); /* Transmit interrupt on */
while(!U_BUFF_EMPTY(channel)); /* wait for tx buffer empty */
return(SUCCESS);
}
}
return(ERROR);
}
/* UART Interrupt put string */
uint32 i_puts(uint32 channel, uint8 *str)
{
uint32 i; /* Working variable */
uint32 sz;
sz = strlen((const char *)str);
/* Loop to print out all characters. */
for(i=0; i < sz ; i++)
{
/* Call i_putc to print each character. */
while(!i_putc(channel, *(str + i)));
}
return(SUCCESS);
}
/* formatted output string */
void i_printf(char *fmt, ...)
{
va_list argptr;
char temp_buf[256];
va_start(argptr, fmt);
vsprintf(temp_buf, fmt, argptr);
sputs((uint8 *)temp_buf);
va_end(argptr);
}
void put_char(uint32 channel,char ch)
{
if(channel) {
WaitXmitter(UARTSTAT1);
UARTTXH1 = ch;
}
else {
WaitXmitter(UARTSTAT0);
UARTTXH0 = ch;
}
}
char get_char(uint32 channel)
{
char ch;
if(channel) { WaitRcver(UARTSTAT1);
ch = UARTRXB1;
}
else { WaitRcver(UARTSTAT0);
ch = UARTRXB0;
}
return ch;
}
void put_string(char *ptr )
{
while(*ptr )
{
put_byte(*ptr++ );
}
}
void dbg_out(char *fmt, ...)
{
va_list argptr;
char temp_buf[256];
va_start(argptr, fmt);
vsprintf(temp_buf, fmt, argptr);
put_string(temp_buf);
va_end(argptr);
}
uint32 gethex2dec(uint32 digitcnt)
{
uint32 decimal = 0;
uint8 hex;
uint32 i;
put_string("0x");
hex = get_byte();
for(i=0;(i<digitcnt)&&(!is_control(hex));i++) {
hex = to_upper(hex);
if(is_xdigit(hex)) {
if(is_digit(hex)) /* '0' - '9' */
decimal = decimal * 16 + hex - '0';
else /* 'A' - 'F' */
decimal = decimal * 16 + 10 + hex - 'A';
}
else {
Print("\r[ERROR] Re-enter %d hexdigit\r",digitcnt);
i = 0; // clear character counter
decimal = 0;
put_string("0x");
}
hex = get_byte(); //get next character
}
put_byte('\r');
return(decimal);
}
uint32 get_num(void)
{
char RcvData[10] ;
unsigned RcvNum=0 ;
int i = 0 ;
while ( (RcvData[i] = get_byte() ) != CR )
{
if ( (RcvData[i] >= '0') && (RcvData[i] <= '9') )
RcvNum=(RcvNum<<4) + (RcvData[i]-'0') ;
else if ( (RcvData[i] >= 'A') && (RcvData[i] <= 'F') )
RcvNum=(RcvNum<<4) + (RcvData[i]-'A'+ 10) ;
else if ( (RcvData[i] >= 'a') && (RcvData[i] <= 'f') )
RcvNum=(RcvNum<<4) + (RcvData[i]-'a'+ 10) ;
i++ ;
}
return RcvNum ;
}
uint32 get_digit(void)
{
uint8 RcvData[10] ;
int RcvNum=0 ;
int RcvDataSize=0 ;
int i ;
while ((RcvData[RcvDataSize] = get_byte()) != CR) RcvDataSize++ ;
for (i=0;i < RcvDataSize ; i++)
RcvNum = RcvNum*10 + (RcvData[i]-'0') ;
return RcvNum ;
}
uint32 kbd_hit(void)
{
uint32 KbdHit ;
int8 ch ;
#ifdef PORT1
if (UARTSTAT1 & USTAT_RCV_READY)
{
KbdHit = 1 ;
ch = UARTRXB1;
}
else KbdHit = 0 ;
#else
if (UARTSTAT0 & USTAT_RCV_READY)
{
KbdHit = 1 ;
ch = UARTRXB0;
}
else KbdHit = 0 ;
#endif
return KbdHit ;
}
uint32 BaudRateVal(uint32 baud)
{
uint32 index;
for(index = 0; index < BAUD_TABLE; index++)
{
if(U_BaudRate[index].baud == baud) return(index);
}
return(0); /* baudrate data doesn't in table */
}
uint32 BaudRate(uint32 div)
{
uint32 index;
for(index = 0; index < BAUD_TABLE; index++)
{
if(U_BaudRate[index].div == div) return(index);
}
return(0); /* baudrate data doesn't in table */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -