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

📄 uart_drv.c

📁 某个ARM9板子的实际bootloader 对裁剪
💻 C
字号:
/***************************************************************************** Copyright  Storlink Corp 2005.  All rights reserved.                *--------------------------------------------------------------------------* Name			: uart_drv.c* Description	: *		Handle UART functions** History**	Date		Writer		Description*	-----------	-----------	-------------------------------------------------*	04/19/2005	Gary Chen	Create and implement from Jason's Redboot code*****************************************************************************/#include <stdarg.h>#include <define.h>#include <board_config.h>#include <sl2312.h>#include "uart.h"#include "lpc.h"typedef struct {	UINT32	overrun_err_cnt;	// Overrun Error Counter	UINT32	break_condet_cnt;	// Break Condition Detect Counter	UINT32	parity_err_cnt;		// Parity Error Counter	UINT32	frame_err_cnt;		// Frame Error Counter	UINT32	no_rxbuf_cnt;		// No free rx buffer} UART_STATISTICS_T;#define UART_RXBUF_SIZE			256typedef struct {	UINT32	total;		UINT32	in_idx;			UINT32	out_idx;		UINT8	buf[UART_RXBUF_SIZE];} UART_BUF_T;typedef struct {	int					IT8712_existed;	UINT32				base;	int					baud_rate;	UINT32				baud_clk;	int					isr_vector;	UART_BUF_T			rxbuf;	UART_STATISTICS_T	stat;} UART_INFO_T;UART_INFO_T uart_info;static void uart_init_channel(UART_INFO_T *uart);void uart_enable_interrupt(void);void uart_disable_interrupt(void);void uart_puts(unsigned char *datap);#define UART_ENABLE_INTERRUPT()#define UART_DISABLE_INTERRUPT()/*------------------------------------------------------------------------------* 	uart_init-----------------------------------------------------------------------------+*/void uart_init(int baud_rate){	UART_INFO_T *uart;	UINT32		base;	UINT8		lcr;		uart = (UART_INFO_T *)&uart_info;	memset((char *)uart, 0, sizeof(UART_INFO_T));	uart->baud_rate = baud_rate;	// change baud rate to clock	switch (baud_rate)	{		case 9600:		uart->baud_clk = SL2312_BAUD_9600; break;		case 14400:		uart->baud_clk = SL2312_BAUD_14400; break;		case 19200:		uart->baud_clk = SL2312_BAUD_19200; break;		case 38400:		uart->baud_clk = SL2312_BAUD_38400; break;		case 57600: 	uart->baud_clk = SL2312_BAUD_57600; break;		case 115200: 	uart->baud_clk = SL2312_BAUD_115200; break;		default:		uart->baud_clk = SL2312_BAUD_19200; break;	}	#ifdef LPC_IT8712    // init channel 1    uart->base = (UINT32)(LPC_BASE);    if (SearchIT8712() == 0)     {    	uart->IT8712_existed = 1;    	LPCSetConfig(0, 0x02, 0x01);    	LPCSetConfig(LDN_SERIAL1, 0x30, 1);    	LPCSetConfig(LDN_SERIAL1, 0x23, 0x00);    	uart->isr_vector = (unsigned int) LPCGetConfig(LDN_SERIAL1, 0x70) + LPC_IRQ_BASE;    	base = (UINT32) LPCGetConfig(LDN_SERIAL1, 0x60);    	base = (base << 8) | ((UINT32) LPCGetConfig(LDN_SERIAL1, 0x61));    	base = uart->base = (UINT32)(LPC_BASE + base);    	//uart->baud_rate = 0x38400 ;    	    	// Disable interrupts.    	// UART_DISABLE_INTERRUPT();    	    	HAL_READ_UINT8(base + UART_LCR, lcr);    	lcr &= ~UART_LCR_DLAB;    	HAL_WRITE_UINT8(base + UART_LCR, UART_LCR_DLAB);    	HAL_WRITE_UINT8(base + UART_DLM, 6 >> 8);    	HAL_WRITE_UINT8(base + UART_DLL, 6);    	lcr &= 0xc0;    	lcr |= UART_LCR_STOP;    	lcr |= UART_LCR_WLEN8;    	HAL_WRITE_UINT8(base + UART_LCR, lcr);    	HAL_WRITE_UINT8(base + UART_MCR, 0x08);    	HAL_WRITE_UINT8(base + UART_FCR, 0x01);    	HAL_WRITE_UINT8(base + UART_IER, 0x05);    }    else#endif    {		uart->base = SL2312_UART_BASE;	    	// Disable interrupts.		// UART_DISABLE_INTERRUPT();    		uart_init_channel(uart);	}		uart_puts("\x1B[0m\n\n");}/*------------------------------------------------------------------------------* 	uart_init_channel-----------------------------------------------------------------------------+*/static void uart_init_channel(UART_INFO_T *uart){    UINT32 base = uart->base;#ifdef GEMINI_ASIC	REG32(SL2312_GPIO_BASE + 0x08) |= SL2312_UART_DIR;	REG32(SL2312_GPIO_BASE + 0x0C) |= SL2312_UART_PIN;#else	REG32(SL2312_GPIO_BASE + 0x0C) |= SL2312_UART_PIN;#endif	//  set uart mode    HAL_WRITE_UINT32(base+SERIAL_MDR,SERIAL_MDR_UART);    // 8-1-no parity.    HAL_WRITE_UINT32(base+SERIAL_LCR, SERIAL_LCR_DLAB);    HAL_WRITE_UINT32(base+SERIAL_DLM, (uart->baud_clk >> 8) & 0xff);    HAL_WRITE_UINT32(base+SERIAL_DLL, uart->baud_clk & 0xff);    HAL_WRITE_UINT32(base+SERIAL_LCR, SERIAL_LCR_LEN8);    // enable FIFO mode    HAL_WRITE_UINT32(base+SERIAL_FCR, SERIAL_FCR_FIFO_ENABLE);    // enable RX interrupts - otherwise ISR cannot be polled. Actual    // interrupt control of serial happens via INT_MASK    // HAL_WRITE_UINT32(base+SERIAL_IER,(SERIAL_IER_DR|SERIAL_IER_RLS));}/*------------------------------------------------------------------------------* 	uart_putc-----------------------------------------------------------------------------+*/void uart_putc(unsigned char c){	UINT32		cnt=0;	UART_INFO_T	*uart;		uart = (UART_INFO_T *)&uart_info;	#ifdef LPC_IT8712	if (uart->IT8712_existed)	{    	UINT8 tsr;    	do {        	HAL_READ_UINT8(uart->base + UART_LSR, tsr);    	} while(!((tsr & UART_LSR_THRE)==UART_LSR_THRE)    			&& (cnt++<0x8000000));        	HAL_WRITE_UINT8(uart->base + UART_TX, (UINT8)(unsigned char)c);    }    else#endif        {    	UINT32 tsr;    	do {        	HAL_READ_UINT32(uart->base + SERIAL_LSR, tsr);        	// Wait for TXI flag to be set - or for the register to be        	// zero (works around a HW bug it seems).    	} while (!((tsr & SERIAL_LSR_THRE)==SERIAL_LSR_THRE)    			&& (cnt++<0x8000000));    	HAL_WRITE_UINT32(uart->base + SERIAL_THR, (UINT32)(unsigned char)c);    }    }/*------------------------------------------------------------------------------* 	uart_puts-----------------------------------------------------------------------------+*/void uart_puts(unsigned char *datap){	// watchdog_disable();	while (*datap)	{		if (*datap==0x0a)			uart_putc(0x0d);		uart_putc(*datap++);	}	// watchdog_enable();}/*--------------------------------------------------------------* 	uart_polling*---------------------------------------------------------------* DESCRIPTION: To poll and get a character from UART* INPUT      : None* OUTPUT     : None---------------------------------------------------------------*/void uart_polling (void){	UINT8 				ch;	UART_STATISTICS_T 	*stat;	UART_BUF_T 			*rxbuf;	UINT32				base;	UART_INFO_T			*uart;		uart = (UART_INFO_T *)&uart_info;		base = uart->base;	stat = (UART_STATISTICS_T *)&uart->stat;	rxbuf = (UART_BUF_T *)&uart->rxbuf;#ifdef LPC_IT8712	if (uart->IT8712_existed)	{    	UINT8 lsr, data;    	HAL_READ_UINT8(base + UART_LSR, lsr);    	if ((lsr & UART_LSR_DR) == UART_LSR_DR)     	{	  		HAL_READ_UINT8(base + UART_RX, data);			if (rxbuf->total < UART_RXBUF_SIZE)			{				rxbuf->buf[rxbuf->in_idx++] = data;				if (rxbuf->in_idx >= UART_RXBUF_SIZE)					rxbuf->in_idx = 0;				rxbuf->total++;			}			else			{				stat->no_rxbuf_cnt ++;			}		}   	}	else#endif		{    	UINT32 lsr, data;    	HAL_READ_UINT32(base+SERIAL_LSR, lsr);    	if ((lsr & SERIAL_LSR_DR)==SERIAL_LSR_DR)     	{	  		HAL_READ_UINT32(base+SERIAL_RBR, data);			if (rxbuf->total < UART_RXBUF_SIZE)			{				rxbuf->buf[rxbuf->in_idx++] = data & 0xff;				if (rxbuf->in_idx >= UART_RXBUF_SIZE)					rxbuf->in_idx = 0;				rxbuf->total++;			}			else			{				stat->no_rxbuf_cnt ++;			}		}	}}/*--------------------------------------------------------------* 	uart_scanc---------------------------------------------------------------*/int uart_scanc(unsigned char *c){	UART_BUF_T *rxbuf;	unsigned char data;    	rxbuf = (UART_BUF_T *)&uart_info.rxbuf;		uart_polling();		if (rxbuf->total)	{		UART_DISABLE_INTERRUPT();		data =rxbuf->buf[rxbuf->out_idx++];		if (rxbuf->out_idx >= UART_RXBUF_SIZE)			rxbuf->out_idx = 0;		rxbuf->total--;		*c = data;		UART_ENABLE_INTERRUPT();		return  1;	}	else	{		return  0;	}}/*--------------------------------------------------------------* 	uart_getc---------------------------------------------------------------*/UINT8 uart_getc(void){	UINT8 key;		while (!uart_scanc(&key));        return key;}

⌨️ 快捷键说明

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