📄 uart.c
字号:
#include "function.h"
#include "xsuart.h"
#include "util.h"
#define UART_BASE_PHYSICAL 0x40100000
#define CKEN_PHYSICAL 0x41300004
#define CK_FFUART 0x1<<6
//used by zeromem
#define wsize sizeof(unsigned int)
#define wmask (wsize - 1)
#define VAL c0
#define WIDEVAL c
#define VAL0 0
#define WIDEVAL0 0
#define FFRBR 0
#define FFTHR 0
#define FFIER 1
#define FFIIR 2
#define FFFCR 2
#define FFLCR 3
#define FFMCR 4
#define FFLSR 5
#define FFMSR 6
#define FFSPR 7
#define FFISR 8
#define FFDLL 0
#define FFDLH 1
#define BAUD_38400 38400 /* baud rate */
#define BAUD_19200 19200 /* baud rate */
/**
* Initialize the UART3 for working on polling mode
**/
/**
* Initialize the UART for working on polling mode
**/
void UartInitialize()
{
unsigned int divisor;
volatile unsigned int * addr;
unsigned int value;
unsigned int volatile *pUartCntrlBase=(unsigned int volatile*)UART_BASE_PHYSICAL;
addr = (unsigned *)GPDR1_ADDR;
value = *addr;
value |= 1<<7 | 1<<8 | 1<<9; //GP39,GP40,GP41 as out
value &= ~(1<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6); // GP34-38 as in
*addr = value;
addr = (unsigned *)GAFR1_L_ADDR;
value = *addr;
value &= ~(0x000ffff0);
value |= 0x000a9550;
*addr = value;
//enable clock
addr=(unsigned int*)CKEN_PHYSICAL;
value=*addr;
value|=CK_FFUART;
*addr=value;
/* clear sticky status first */
pUartCntrlBase[FFLCR] = 0x0;
pUartCntrlBase[FFFCR] = 0x0;
pUartCntrlBase[FFMCR] = 0x0;
pUartCntrlBase[FFISR] = 0x0;
pUartCntrlBase[FFIER] = 0x0;
// Clear the Rx FIFO
pUartCntrlBase[FFFCR] = FCR_TRFIFOE | FCR_RESETRF;
// Clear the Tx FIFO
pUartCntrlBase[FFFCR] = FCR_TRFIFOE | FCR_RESETTF;
// Set Serial Line Control Register (LCR)
// DLAB = 1
pUartCntrlBase[FFLCR] = LCR_DLAB1 | LCR_WLS8;
// To Configure the baud rate generators for UART:
// DLAB = 1 to access DLL and DLH
// Load DLL and DLH with divisor (divisor = 8 for 115200)
// DLAB = 0
divisor = 14745600 / (16 * BAUD_38400);
if (divisor < FFDIVISOR_MIN )
divisor = FFDIVISOR_MIN;
pUartCntrlBase[FFDLL] = divisor & 0xff;
pUartCntrlBase[FFDLH] = (divisor & 0xff00) >> 8;
//pUartCntrlBase[FFDLL] = 24;
//pUartCntrlBase[FFDLH] = 0;
pUartCntrlBase[FFLCR]&= ~LCR_DLAB1;
// Close loop back mode
pUartCntrlBase[FFMCR] &= ~MCR_LOOP;
// Read MSR once to clear delta bits (bits 3:0)
value = pUartCntrlBase[FFMSR];
// Enable FIFOs and reset FIFOs and set interrupt trigger level
pUartCntrlBase[FFFCR] = FCR_TRFIFOE| FCR_RESETRF| FCR_RESETTF;
// Disable DMA, configure NRZ, IRQ, and enable UART unit
// Just make sure that DMA is disabled and UART is enabled
pUartCntrlBase[FFIER] = IER_UUE;
addr = UTIL_PCR_ADDR; // PCR
value = *addr;
value |= 1<<2 | 1<<14; // RS232_On
*addr = value;
} //UartInitialize
// Init the UART1 port ex
void UartInitializeEx(unsigned int Baudrate, UART_Bits Bits, UART_Parity Parity, UART_StopBit Stop, int FlowControl)
{
volatile unsigned int *addr;
unsigned int buffer;
unsigned int divisor;
unsigned int value;
unsigned int volatile *pUartCntrlBase=(unsigned int volatile*)UART_BASE_PHYSICAL; /* Current UART */
addr = (unsigned *)GPDR1_ADDR;
value = *addr;
value |= 1<<7 | 1<<8 | 1<<9; //GP39,GP40,GP41 as out
value &= ~(1<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6); // GP34-38 as in
*addr = value;
addr = (unsigned *)GAFR1_L_ADDR;
value = *addr;
value &= ~(0x000ffff0);
value |= 0x000a9550;
*addr = value;
//enable clock
addr=(unsigned int*)CKEN_PHYSICAL;
value=*addr;
value|=CK_FFUART;
*addr=value;
/* clear sticky status first */
pUartCntrlBase[FFFCR] = 0x0;
pUartCntrlBase[FFLCR] = 0x0;
pUartCntrlBase[FFMCR] = 0x0;
pUartCntrlBase[FFISR] = 0x0;
pUartCntrlBase[FFIER] = 0x0;
// Clear the Rx FIFO
pUartCntrlBase[FFFCR] = FCR_TRFIFOE | FCR_RESETRF;
// Clear the Tx FIFO
pUartCntrlBase[FFFCR] = FCR_TRFIFOE | FCR_RESETTF;
/* Assume on-chip baud rate generator, tx and rx clock rising edge latches data */
buffer = 0;
switch(Parity)
{
case UART_NOPARITY:
buffer |= 0<<3;
break;
case UART_PARITY:
buffer |= 1<<3;
break;
default:
break;
}
switch(Stop)
{
case UART_ONESTOPBIT:
buffer |= 0<<2;
break;
case UART_TWOSTOPBITS:
buffer |= 1<<2;
break;
}
switch(Bits)
{
case UART_5BITS:
buffer |= 0;
break;
case UART_6BITS:
buffer |= 1;
break;
case UART_7BITS:
buffer |= 2;
break;
case UART_8BITS:
buffer |= 3;
break;
}
// Set Serial Line Control Register (LCR)
// DLAB = 1
pUartCntrlBase[FFLCR] = LCR_DLAB1 | buffer;
// To Configure the baud rate generators for UART:
// DLAB = 1 to access DLL and DLH
// Load DLL and DLH with divisor (divisor = 8 for 115200)
// DLAB = 0
divisor = 14745600 / (16 * Baudrate);
if (divisor < FFDIVISOR_MIN )
divisor = FFDIVISOR_MIN;
pUartCntrlBase[FFDLL] = divisor & 0xff;
pUartCntrlBase[FFDLH] = (divisor & 0xff00) >> 8;
pUartCntrlBase[FFLCR]&= ~LCR_DLAB1;
pUartCntrlBase[FFMCR] &= ~MCR_LOOP;
// Read MSR once to clear delta bits (bits 3:0)
value = pUartCntrlBase[FFMSR];
// Enable FIFOs and reset FIFOs and set interrupt trigger level
pUartCntrlBase[FFFCR] = FCR_TRFIFOE| FCR_RESETRF| FCR_RESETTF;
addr = UTIL_PCR_ADDR; // PCR
value = *addr;
value |= 1<<2 | 1<<14; // RS232_On
*addr = value;
}//UartInitializeEx
/**
* send data with length identified
**/
void UartXmitData (unsigned int volatile *pUart, char *buf, int len)
{
int i;
unsigned int volatile *pUartCntrlBase=(unsigned int volatile*)UART_BASE_PHYSICAL; /* Current UART */
for (i=0; i < len; i++)
{
// Write data
pUartCntrlBase[FFTHR] = *buf++;
// Wait for UART to complete transmition
while((pUartCntrlBase[FFLSR] & LSR_TEMT) == 0)
{;}
}
}
void print_string(char * buf)
{
unsigned int volatile *pUartCntrlBase=(unsigned int volatile*)UART_BASE_PHYSICAL; /* Current UART */
int i;
for (i=0; buf[i]; i++ ) {
UartXmitData ( pUartCntrlBase,(char*)buf+i, 1);}
}
void print_string_uart(char * buf)
{
unsigned int volatile *pUartCntrlBase=(unsigned int volatile*)UART_BASE_PHYSICAL; /* Current UART */
int i;
for (i=0; buf[i]; i++ ) {
UartXmitData ( pUartCntrlBase,(char*)buf+i, 1);}
}
void Byte2String (char *buf, unsigned char hex)
{
unsigned char digH,digL;
digH = (unsigned char)(hex >>4);
digL = (unsigned char)(hex & 0xf);
if ( digH < 0xa ) {
buf[0] = (char)(digH + '0');
}
else {
buf[0] = (char)(digH - 0xa + 'A');
}
if ( digL < 0xa ) {
buf[1] = (char)(digL + '0');
}
else {
buf[1] = (char)(digL - 0xa + 'A');
}
buf[2] = '\0';
}
void HalfWord2String (char *buf, unsigned short int hex)
{
Byte2String (buf, (unsigned char)(hex>>8));
Byte2String (buf+2, (unsigned char)(hex&0xff));
}
/***** buf at least has more than 9bytes size **/
void HexWord2String (char *buf, int hex)
{
HalfWord2String ( buf, (unsigned short int)(hex>>16) );
HalfWord2String ( buf+4, (unsigned short int)(hex&0xffff) );
}
void print_mesg_hex(char *msg, unsigned int hex)
{
char buf[9];
print_string (msg);
HexWord2String (buf,hex);
print_string(buf);
print_string("\r\n");
}
void print_mesg_hex_uart(char *msg, unsigned int hex)
{
char buf[9];
print_string_uart (msg);
HexWord2String (buf,hex);
print_string_uart(buf);
print_string_uart("\r\n");
}
void Dump_Bin(unsigned int base_address,int size)
{
char buf[9];
unsigned int* hex;
int i;
int true=1;
i=0;
hex=(unsigned int*)base_address;
while(true)
{
HexWord2String (buf,*hex);
print_string(buf);
print_string(" ");
hex++;
i++;
if(i>size) break;
HexWord2String (buf,*hex);
print_string(buf);
print_string(" ");
hex++;
i++;
if(i>size) break;
HexWord2String (buf,*hex);
print_string(buf);
print_string(" ");
hex++;
i++;
if(i>size) break;
HexWord2String (buf,*hex);
print_string(buf);
print_string(" ");
hex++;
i++;
if(i>size) break;
print_string("\r\n");
// uart_getch();
}
print_string("\r\n");
}
void
zeromem(void *dst0,register unsigned int length)
{
register unsigned int t;
register unsigned char *dst;
dst = dst0;
if (length < 3 * wsize) {
while (length != 0) {
*dst++ = (unsigned char)VAL0;
--length;
}
return;
}
//* Align destination by filling in bytes. /
if ((t = (unsigned int)dst & wmask) != 0) {
t = wsize - t;
length -= t;
do {
*dst++ = (unsigned char)VAL0;
} while (--t != 0);
}
//* Fill words. Length was >= 2*words so we know t >= 1 here.
t = length / wsize;
do {
*(unsigned int *)dst = WIDEVAL0;
dst += wsize;
} while (--t != 0);
//* Mop up trailing bytes, if any. /
t = length & wmask;
if (t != 0)
do {
*dst++ =(unsigned char) VAL0;
} while (--t != 0);
return;
}
void *
memset(void *dst0,register int c0,register int length)
{
register unsigned int t;
register unsigned char *dst;
register unsigned int c;
dst = dst0;
if (length < 3 * wsize) {
while (length != 0) {
*dst++ =(unsigned char) VAL;
--length;
}
return dst0;
}
if ((c = (unsigned char)c0) != 0) { //* Fill the word.
c = (c << 8) | c; //* u_int is 16 bits. *
c = (c << 16) | c; //* u_int is 32 bits. *
}
//* Align destination by filling in bytes.
if ((t = (unsigned int)dst & wmask) != 0) {
t = wsize - t;
length -= t;
do {
*dst++ = (unsigned char)VAL;
} while (--t != 0);
}
//* Fill words. Length was >= 2*words so we know t >= 1 here.
t = length / wsize;
do {
*(unsigned int *)dst = WIDEVAL;
dst += wsize;
} while (--t != 0);
//* Mop up trailing bytes, if any.
t = length & wmask;
if (t != 0)
do {
*dst++ =(unsigned char) VAL;
} while (--t != 0);
return dst0;
}
void DelayUs(unsigned int count)
{
volatile int* oscr;
int start;
int ticks;
oscr=(int*)0x40a00010;
ticks = 3 * count + (6 * count) / 10 + (8 *count) /100;
start=*oscr;
while(*oscr-start<ticks);
}
void DelayMs(unsigned int count)
{
DelayUs(count*1000);
}
void DelayS(unsigned int count)
{
while(count-->0)
DelayUs(1000000);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -