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

📄 uart.c

📁 嵌入式系统启动代码
💻 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 + -